comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: Renaming tags in an array of structures
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: Renaming tags in an array of structures [message #72522] Fri, 17 September 2010 07:50
wlandsman is currently offline  wlandsman
Messages: 743
Registered: June 2000
Senior Member
Check out the ALIAS keyword in mrdfits.pro

; ALIAS The keyword allows the user to specify the column
names
; to be created when reading FITS data. The value of
; this keyword should be a 2xn string array. The first
; value of each pair of strings should be the desired
; tag name for the IDL column. The second should be
; the FITS TTYPE value.

This is probably more efficient than changing the tag names after the
structure has been read, though I realize that you might not know the
names you need until after the file is read. (And I haven't used
the ALIAS keyword much so I can't vouch for it.) --Wayne

On Sep 17, 10:16 am, Michael Williams <mjwilli...@gmail.com> wrote:
>
> I'm reading in a FITS file (data format used in astronomy) that I did
> not create. The library function I'm using to do this (mrdfits from
> astroidl) returns an array of structures. The names of the tags are
> specified in the fits file itself.
>
> It so happens that in this new file I'm working with, these names do
> not match the choices used for the same data in all my other files.
> For example, let's say I want to plot old_data.speed against
> new_data.speed. But new_data doesn't have a .speed tag. It calls
> it .velocity. If it's just one tag and just one case, then hard coding
> something would work, but as the number of tags grows this becomes
> ugly and error prone. It would be much easier and more general to just
> rename tags. Unfortunately that seems to be non-trivial in IDL.
>
> In my case, the best thing to do is probably to edit the FITS file at
> source and change the header so that the tag names match. That may not
> be possible (or desirable from a data purity point of view) in all
> circumstances, and renaming data structures or changing the metadata
> associated with a strucure should of course be possible in a modern
> language! Hence this question :-)
>
> -- Mike
Re: Renaming tags in an array of structures [message #72525 is a reply to message #72522] Fri, 17 September 2010 07:16 Go to previous message
Michael Williams is currently offline  Michael Williams
Messages: 17
Registered: December 2008
Junior Member
On Sep 17, 3:30 pm, Paul van Delst <paul.vande...@noaa.gov> wrote:
> Michael Williams wrote:
>> I have an array of structures:
>
>> IDL> x = {a: 1, b:2, c: indgen(5)}
>> IDL> xx = replicate(x, 10)
>
>> In this case, I want to rename the 'b' tag to 'foo' and the 'c' tag to
>> bar.
>
> Can one inquire why you would like/need to do this?

I'm reading in a FITS file (data format used in astronomy) that I did
not create. The library function I'm using to do this (mrdfits from
astroidl) returns an array of structures. The names of the tags are
specified in the fits file itself.

It so happens that in this new file I'm working with, these names do
not match the choices used for the same data in all my other files.
For example, let's say I want to plot old_data.speed against
new_data.speed. But new_data doesn't have a .speed tag. It calls
it .velocity. If it's just one tag and just one case, then hard coding
something would work, but as the number of tags grows this becomes
ugly and error prone. It would be much easier and more general to just
rename tags. Unfortunately that seems to be non-trivial in IDL.

In my case, the best thing to do is probably to edit the FITS file at
source and change the header so that the tag names match. That may not
be possible (or desirable from a data purity point of view) in all
circumstances, and renaming data structures or changing the metadata
associated with a strucure should of course be possible in a modern
language! Hence this question :-)

-- Mike
Re: Renaming tags in an array of structures [message #72528 is a reply to message #72525] Fri, 17 September 2010 06:30 Go to previous message
Paul Van Delst[1] is currently offline  Paul Van Delst[1]
Messages: 1157
Registered: April 2002
Senior Member
Michael Williams wrote:
> I have an array of structures:
>
> IDL> x = {a: 1, b:2, c: indgen(5)}
> IDL> xx = replicate(x, 10)
>
> In this case, I want to rename the 'b' tag to 'foo' and the 'c' tag to
> bar.

Can one inquire why you would like/need to do this?
Re: Renaming tags in an array of structures [message #72538 is a reply to message #72528] Thu, 16 September 2010 14:18 Go to previous message
Michael Williams is currently offline  Michael Williams
Messages: 17
Registered: December 2008
Junior Member
On Sep 16, 11:13 pm, Michael Williams <mjwilli...@gmail.com> wrote:
[...]
>     ; (iii) setup template structure
>     empties = '0d'
>     for i = 1, n_elements(tags) - 1 do empties += ',0d'
>     void = execute('template = create_struct(tags, ' + empties + ')')
>     stop
>     newstr2 =  replicate(template, n_elements(str))
>     ; (iv) Throw out old old_tags
>     struct_assign, newstr, newstr2
>
>     return, newstr2
> end

pro-tip for those trying to run this code: you're going to want to
delete that "stop" ;-)
Re: Renaming tags in an array of structures [message #72539 is a reply to message #72538] Thu, 16 September 2010 14:13 Go to previous message
Michael Williams is currently offline  Michael Williams
Messages: 17
Registered: December 2008
Junior Member
On Sep 16, 10:40 pm, Michael Williams <mjwilli...@gmail.com> wrote:
> On Sep 16, 8:50 pm, David Fanning <n...@dfanning.com> wrote:
>
>>> Can anyone see how to fix these problems so that the function works
>>> for arbitrarily many tag names, copies the data (ideally without using
>>> execute statements, which is the only way I can think of doing it),
>>> and the old fields are deleted? Or is there another solution
>>> altogether?
>
>> Yes, I think I can see how to do it. I can't see how to
>> do it in a couple of lines of code. And I can't see how
>> to do it without either using EXECUTE or FOR loops. But
>> I think it can be done.
>
> Thanks. If there isn't a more elegant way (short of migrating to
> hashes or a post-Cold War language ;-) then I think I can see a way of
> doing it too. Luckily, I don't need to worry about nested structures.
> I'm just dealing with what is essentially a 2-D matrix where the
> columns have names and each element is a float, so I can afford to be
> fairly braindead about this.

And here is my implementation. I am obviously in a state of sin with
all these for loops and execute statements, but it works for my
purposes. Comments welcome.

The one practical limitation that may cause me some problems in the
future is that fact that every element of the new array of structures
is forced to be a double because of the way I'm deleting the old_tags.
I can see a rather tedious and ugly way around this (essentially
constructing a lookup table which says what string to add to the
empties variable based on the type of the each tag you keep). That
solution seems ugly even for IDL so I would be particularly interested
in any ideas there.

function rename_tags_array, str, old_tags, new_tags
nchange = n_elements(old_tags)

; Set up new template with tags in str + new_tags
empties = '0d'
for i = 1, nchange - 1 do empties += ',0d'
void = execute('template = create_struct(new_tags, ' + empties +
', str[0])')
newstr = replicate(template, n_elements(str))
struct_assign, str, newstr

; Copy str.old_tags to newstr.new_tags
for i = 0, nchange - 1 do begin
void = execute('newstr.' + new_tags[i] + ' = str.' +
old_tags[i])
endfor

; Delete newstr.old_tags
;
; (i) generate list of all tags in newstr
tags = tag_names(newstr)
; (ii) remove old_tags from this list
for i = 0, nchange - 1 do begin
j = where(strupcase(tags) eq strupcase(old_tags[i]),
complement = keep)
tags = tags[keep]
endfor
; (iii) setup template structure
empties = '0d'
for i = 1, n_elements(tags) - 1 do empties += ',0d'
void = execute('template = create_struct(tags, ' + empties + ')')
stop
newstr2 = replicate(template, n_elements(str))
; (iv) Throw out old old_tags
struct_assign, newstr, newstr2

return, newstr2
end
Re: Renaming tags in an array of structures [message #72540 is a reply to message #72539] Thu, 16 September 2010 13:40 Go to previous message
Michael Williams is currently offline  Michael Williams
Messages: 17
Registered: December 2008
Junior Member
On Sep 16, 8:50 pm, David Fanning <n...@dfanning.com> wrote:
>> Can anyone see how to fix these problems so that the function works
>> for arbitrarily many tag names, copies the data (ideally without using
>> execute statements, which is the only way I can think of doing it),
>> and the old fields are deleted? Or is there another solution
>> altogether?
>
> Yes, I think I can see how to do it. I can't see how to
> do it in a couple of lines of code. And I can't see how
> to do it without either using EXECUTE or FOR loops. But
> I think it can be done.

Thanks. If there isn't a more elegant way (short of migrating to
hashes or a post-Cold War language ;-) then I think I can see a way of
doing it too. Luckily, I don't need to worry about nested structures.
I'm just dealing with what is essentially a 2-D matrix where the
columns have names and each element is a float, so I can afford to be
fairly braindead about this.

> Is this worth something to you? :-)

I'm afraid I'm a PhD student with (i) no money (ii) no time! :-) I'll
post my solution, and comments (and improvements) are of course
appreciated!

-- Mike
Re: Renaming tags in an array of structures [message #72542 is a reply to message #72540] Thu, 16 September 2010 13:33 Go to previous message
Michael Williams is currently offline  Michael Williams
Messages: 17
Registered: December 2008
Junior Member
On Sep 16, 9:05 pm, Paulo Penteado <pp.pente...@gmail.com> wrote:
> Any reason not to do it with hashes and avoid all those troubles?

I didn't actually know those had arrived with 8.0. I'm still on 7.x. I
would probably migrate the code to Python rather than do upgrade and
rewrite. Thanks for the heads-up though.
Re: Renaming tags in an array of structures [message #72548 is a reply to message #72542] Thu, 16 September 2010 12:05 Go to previous message
penteado is currently offline  penteado
Messages: 866
Registered: February 2018
Senior Member
Administrator
On Sep 16, 3:28 pm, Michael Williams <mjwilli...@gmail.com> wrote:
> I have an array of structures:
>
> IDL> x = {a: 1, b:2, c: indgen(5)}
> IDL> xx = replicate(x, 10)
>
> In this case, I want to rename the 'b' tag to 'foo' and the 'c' tag to
> bar. But I want a function that works for arbitrary tag names. I have
> readhttp://www.dfanning.com/code_tips/addfield.html, which describes
> how to add a field to an array of structures using struct_assign. So
> far I have the following function, which seems like it's headed in the
> right direction: it will add the foo and bar tags. But (i) it only
> works if you're renaming exactly two tags because of the create_struct
> call (ii) it doesn't copy the data in the old tags to the new tags and
> (iii) it doesn't delete the old tags, which is necessary for true
> "replacement".
>
> Can anyone see how to fix these problems so that the function works
> for arbitrarily many tag names, copies the data (ideally without using
> execute statements, which is the only way I can think of doing it),
> and the old fields are deleted? Or is there another solution
> altogether?

Any reason not to do it with hashes and avoid all those troubles?
Re: Renaming tags in an array of structures [message #72549 is a reply to message #72548] Thu, 16 September 2010 11:50 Go to previous message
David Fanning is currently offline  David Fanning
Messages: 11724
Registered: August 2001
Senior Member
Michael Williams writes:

> Can anyone see how to fix these problems so that the function works
> for arbitrarily many tag names, copies the data (ideally without using
> execute statements, which is the only way I can think of doing it),
> and the old fields are deleted? Or is there another solution
> altogether?

Yes, I think I can see how to do it. I can't see how to
do it in a couple of lines of code. And I can't see how
to do it without either using EXECUTE or FOR loops. But
I think it can be done.

Is this worth something to you? :-)

This would be a couple of hours worth of effort to
write a completely general program. For example,
you will probably have to write some kind of
recursive function to copy tag values that are
pointers and/or structures, etc. Just that alone
will take a couple hours, probably, although I
used to have something like that laying around
here.

Cheers,

David

--
David Fanning, Ph.D.
Fanning Software Consulting, Inc.
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Sepore ma de ni thui. ("Perhaps thou speakest truth.")
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Re: color tiffs
Next Topic: Re: IDL 8.0; difficulties with "New Graphics"

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 15:39:48 PDT 2025

Total time taken to generate the page: 0.00679 seconds