Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Smart way to extract the same attribute from a list of objects?
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  4 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Paul van Delst  
View profile  
 More options Oct 4 2012, 11:44 am
Newsgroups: comp.lang.idl-pvwave
From: Paul van Delst <paul.vande...@noaa.gov>
Date: Thu, 04 Oct 2012 11:44:07 -0400
Local: Thurs, Oct 4 2012 11:44 am
Subject: Smart way to extract the same attribute from a list of objects?
Hello,

I have a list,

IDL> help, r
R               LIST  <ID=2  NELEMENTS=616>

composed of only a single type of object,

IDL> help, r[0]
<Expression>    OBJREF    = <ObjHeapVar3(RTSOLUTION)>
IDL> help, r[200]
<Expression>    OBJREF    = <ObjHeapVar1803(RTSOLUTION)>
..etc..

What I want to do is extract the same attribute from every object in the
list.

The way I'm doing it now is:

   radiance = DBLARR(r.Count())
   FOR i=0,r.count()-1 DO BEGIN
     r[i].get_property, radiance=x
     radiance[i]=x
   ENDFOR

and then I can do stuff with "radiance", such as plot it.

I find the above a little bit clunky since I have to explicitly iterate
through the list to pull out what I want, creating the temporary
"holding" array beforehand. If I want to extract more than one thing I
end up with something like

   n = r.Count()
   channel  = LONARR(n)
   radiance = DBLARR(n)
   FOR i=0,n-1 DO BEGIN
     r[i].get_property, radiance=x, channel=j
     radiance[i]= x
     channel[i] = j
   ENDFOR

which just looks messy.

Does anyone have any better/faster/more-elegant solutions to this sort
of problem?

I've had a look at the _overloadBracketsRightSide function documentation
but, to be honest, the description seems rather impenetrable to me. I
guess I'm looking for something akin to the "ELEMENTAL" attribute in
Fortran where a procedure written for in/output scalars can also operate
on any rank arrays (as long as they are conformable.)

cheers,

paulv


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paul Mallas  
View profile  
 More options Oct 4 2012, 12:53 pm
Newsgroups: comp.lang.idl-pvwave
From: Paul Mallas <bloodysam.v...@gmail.com>
Date: Thu, 4 Oct 2012 09:53:54 -0700 (PDT)
Local: Thurs, Oct 4 2012 12:53 pm
Subject: Re: Smart way to extract the same attribute from a list of objects?
Well, I will share with you what I did.  Not sure about if it qualitfies as better/faster/more-elegant, but here you go.

I created a new object that is just a list:

pro newObj__define
  compile_opt idl2

  _ = {newObj, $
    inherits list $
    }

Then, in my init, I created a struct like

function newObj::init, nSamples = nSamples
  compile_opt idl2

  newObjStruct = {newObjStruct, $
    radiance:0, $
    channel:0}

  self->add, replicate(newObjStruct, nSamples), /extract

  return, 1
end  

Then I overloaded the setProperty and getProperty functions.  

pro newObj::setProperty, _extra=extra
  compile_opt idl2

  if self->isEmpty() then return

  if (~n_elements(extra)) then return

  num = n_elements((tags=tag_names(extra)))

  lArray = self->toArray()
  self->remove, /all

  for ii=0, num-1 do begin
    ok = execute("lArray."+tags[ii]+ " = extra.(ii)")
  endfor

  self.add, lArray, /extract
end

pro newObj::getProperty, _ref_extra=extra
  compile_opt idl2

  if self->isEmpty() then return

  if (~n_elements(extra)) then return

  lArray = self.toArray()

  for ii=0, n_elements(extra)-1 do begin
    ok = execute("(scope_varfetch(extra[ii], /ref_extra)) = lArray."+extra[ii])
  endfor

end


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paul Mallas  
View profile  
 More options Oct 4 2012, 12:56 pm
Newsgroups: comp.lang.idl-pvwave
From: Paul Mallas <bloodysam.v...@gmail.com>
Date: Thu, 4 Oct 2012 09:56:44 -0700 (PDT)
Local: Thurs, Oct 4 2012 12:56 pm
Subject: Re: Smart way to extract the same attribute from a list of objects?
Actually, I my setProperty and getProperty functions I stole from here:  

http://idldatapoint.com/2012/01/05/a-technique-for-flexible-getsetpro...

The author did something similar to me, but uses a hash object inside his object, whereas I just inherited the list object into my object.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paul van Delst  
View profile  
 More options Oct 4 2012, 2:11 pm
Newsgroups: comp.lang.idl-pvwave
From: Paul van Delst <paul.vande...@noaa.gov>
Date: Thu, 04 Oct 2012 14:11:08 -0400
Local: Thurs, Oct 4 2012 2:11 pm
Subject: Re: Smart way to extract the same attribute from a list of objects?
Hello,

Thanks. I will have a closer look at your (and Mark's) technique.

In the meantime, what I came up with for my particular object is down
below. I reopened the List class to do it; a faux pas I know but...

-----%<-----
FUNCTION List::Get_Channel_Data, $
   data_name    , $ ; Input
   Debug = debug    ; Input keyword

   ; Set up
   @rtsolution_func_err_handler
   @rtsolution_parameters
   ; ...Check that *all* list members are RTSolution objects
   FOREACH element, self DO BEGIN
     IF ( ~ ISA(element,'RTSolution') ) THEN $
       MESSAGE, 'Non-RTSolution object found in channel list.', $
                NONAME=MsgSwitch, NOPRINT=MsgSwitch
   ENDFOREACH

   ; Construct the data retrieval command
   cmd_string = "self[i]->RTSolution::Get_Property, "+data_name+"=x"

   ; Define the return array
   n_channels = self.Count()
   data = MAKE_ARRAY(n_channels, VALUE = ZERO)

   ; Loop over list elements
   FOR i = 0L, n_channels-1 DO BEGIN
     ; ...Execute the command
     result = EXECUTE(cmd_string)
     IF ( result NE TRUE ) THEN $
       MESSAGE, "Error retrieving " + data_name + $
                " data for channel index " + STRTRIM(i,2), $
                NONAME=MsgSwitch, NOPRINT=MsgSwitch
     ; ...Save the channel data
     data[i] = x
   ENDFOR

   ; Done
   RETURN, data

END
-----%<-----

So once I've read my list-of-lists in

IDL> rtsolution_readfile, 'iasi616_metop-a.RTSolution.bin'
% RTSOLUTION_READFILE: Reading RTSolution profile #1
% RTSOLUTION_READFILE: Reading RTSolution profile #2
% RTSOLUTION_READFILE: Number of profiles/channels read from
iasi616_metop-a.RTSolution.bin : 2/616

I have my list of atmospheric profile results (the "profile" list),

IDL> help, rts
RTS             LIST  <ID=1  NELEMENTS=2>

each of which contains sensor spectral results (a "channel" list for
each "profile" entry),

IDL> help, rts[0]
<Expression>    LIST  <ID=2  NELEMENTS=616>

each of which contains the main object

IDL> help, (rts[0])[0]
<Expression>    OBJREF    = <ObjHeapVar3(RTSOLUTION)>

And now I can extract the same data from each object in the "channel" list:

IDL> help, rts[0].get_channel_data('radiance')
% Compiled module: LIST::GET_CHANNEL_DATA.
<Expression>    DOUBLE    = Array[616]
IDL> help, rts[1].get_channel_data('surface_emissivity')
<Expression>    DOUBLE    = Array[616]

etc..

Uff da. I really need to do more IDL metaprogramming.... :o)

cheers,

paulv

On 10/04/12 12:53, Paul Mallas wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »