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

Home » Public Forums » archive » How to traverse/inquire a class object structure in IDL?
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
How to traverse/inquire a class object structure in IDL? [message #17394] Wed, 13 October 1999 00:00 Go to next message
Paul van Delst is currently offline  Paul van Delst
Messages: 364
Registered: March 1997
Senior Member
Hello,

Last night I entered into the world of IDL objects. I was amazed at how much
easier it is to keep control of a data object rather than using a regular
structure.

Anyway, since I have been programming IDL in an Object Oriented mode for about 8
hours, I have some questions that I hope someone out there can help me with. The
documentation (on-line and printed) was not useful.

I have a class structure definition in nasti__define.pro:

PRO nasti__define, nasti_structure

; -- Define the data structure
nasti_structure = { NASTI, $
wavenumber : PTR_NEW(), $
radiance : PTR_NEW(), $
altitude : PTR_NEW(), $
fov_angle : PTR_NEW(), $
fov_index : PTR_NEW(), $
latitude : PTR_NEW(), $
longitude : PTR_NEW(), $
aircraft_roll : PTR_NEW(), $
aircraft_pitch : PTR_NEW(), $
scan_line_index : PTR_NEW(), $
date : PTR_NEW(), $
time : PTR_NEW(), $
decimal_time : PTR_NEW() }

END

which will eventually contain an aircraft instrument data time series of unknown
length - hence the pointers.

I create the object:

IDL> n=OBJ_NEW( 'nasti' )

and read in some data from a netCDF file (only the first data structure field,
wavenumber, is filled for now):

IDL> print, n->read_nasti( ncdf_filename )

This all works fine. I have an simple inquire method:

PRO nasti::inquire_nasti

PRINT, FORMAT = '( /5x, "Inquiring..." )'
PRINT, PTR_VALID(), OBJ_VALID()

END

which when I run it, gives:

IDL> n->inquire_nasti
Inquiring...
<PtrHeapVar2>
<ObjHeapVar1(NASTI)>

where the PtrHeapVar2 is the pointer to "self.wavenumber" and the object
reference is for the object. Cool.

I assumed that if I destroyed the object, the pointer references would still be
there, dangling away, which turns out to be true:

IDL> obj_destroy, n
IDL> print, ptr_valid(), obj_valid()
<PtrHeapVar2>
<NullObject>

Not good. As more objects are created and destroyed, the valid pointer list
grows. I would like to do the following in a CLEANUP method:

FOR i = 0, n_object_structure_elements - 1 DO $
IF ( PTR_VALID( self.(i) ) ) THEN $
PTR_FREE, self.(i)

that is, *explicitly* free up the pointers. This works great if I have a value
for n_object_structure_elements.

QUESTIONS:

1) Is my technique valid? That is, I want to do the following:
- create a data object
- read some amount of data into that object
- do stuff with the data object
- delete the data object INCLUDING any pointers in the object.
I don't know how much data I have ahead of time so I used pointers. Can I create
data objects on the fly, based on how much data is in a datafile or requested
from a datafile?

2a) If my technique is o.k., how do I free up the pointers in my object before I
destroy it?

..OR..

2b) Is the above code stub a valid/smart way to free up the pointers in a data
object and, if so, how do I determine the value of n_object_structure_elements?
(You can't use N_TAGS() on an object but you can use the self.(i) type of
structure reference so I'm confused.)


If you know how to solve my problem, please let me know. And, given my neophyte
object programming status, be kind.

:o)

paulv

--
Paul van Delst
Space Science and Engineering Center | Ph/Fax: (608) 265-5357, 262-5974
University of Wisconsin-Madison | Email: paul.vandelst@ssec.wisc.edu
1225 W. Dayton St., Madison WI 53706 | Web: http://airs2.ssec.wisc.edu/~paulv
Re: How to traverse/inquire a class object structure in IDL? [message #17520 is a reply to message #17394] Fri, 15 October 1999 00:00 Go to previous message
J.D. Smith is currently offline  J.D. Smith
Messages: 214
Registered: August 1996
Senior Member
Paul van Delst wrote:
>
> First off, thanks to David and Pavel for their insights. Before I could check the
> newsgroup for replies, one of our younger go-getter science types came and told me
> something about object oriented programming that made good sense:
>
> The data should be an attribute of the object, not the object itself.
>
> Hmm. Anyway, he and I sat down for about 15 minutes and came up with the following
> class structure definition and cleanup method:
>
> PRO nasti__define
>
> ; -- Define the NAMED data structure attribute
> data = { data, $
> wavenumber : PTR_NEW(), $
> radiance : PTR_NEW(), $
> altitude : PTR_NEW(), $
> fov_angle : PTR_NEW(), $
> fov_index : PTR_NEW(), $
> latitude : PTR_NEW(), $
> longitude : PTR_NEW(), $
> aircraft_roll : PTR_NEW(), $
> aircraft_pitch : PTR_NEW(), $
> scan_line_index : PTR_NEW(), $
> date : PTR_NEW(), $
> time : PTR_NEW(), $
> decimal_time : PTR_NEW() }
>
> ; -- Create object CLASS structure
> nasti = { nasti, $
> data : data }
>
> END
>
> I like this becuase now I can add additional attributes whenever I want, e.g.
> global attribute data read from the netCDF data file containing instrument
> calibration information and/or processing software CVS/RCS info etc.
>
> The cleanup method is now:
>
> PRO nasti::cleanup
>
> PRINT, FORMAT = '( /5x, "Clean up..." )'
>
> ; -- Free up pointers
> n_data_fields = N_TAGS( self.data )
> FOR i = 0, n_data_fields - 1 DO $
> IF ( PTR_VALID( self.data.(i) ) ) THEN $
> PTR_FREE, self.data.(i)
>
> END
>
> I just couldn't bring myself to typing PTR_FREE, self.whatever a bunch of times
> because if I ever change the data structure definition, I would have to change the
> cleanup as well. I like changes in my code to have as small a footprint as
> possible, i.e. change is required in as few places as possible. Dunno if that's a
> great idea but for my simple little example but it's a start. Right?
>
> I wish I'd "discovered" objects earlier......all that code I wrote that *needs* the
> data to be encapsulated. Crikey.

I hate to add yet another level of dereferencing, which can get pretty
ugly in code, but I have had some instances where an array of structure
"data records" (or "attribute records" just as well) can be employed for
just this purpose. If your attributes are really changing that much,
then they shouldn't be "hard-coded" into any structure itself,
class-defining or otherwise. An advantage of the method below is that if
the data pointer field is the same in all records, then cleanup is
trivial.

This is best illustrated with an example:

;; The class definition procedure...
pro MyClassDef__define
struct={MyClassDef,
Recs:ptr_new()} ; a pointer to a list of structs of type
MyClassData_Rec

; Define an auxilliary structure for new Data Records
struct={MyClassData_Rec,
Name:'',
Data:ptr_new()}
end

Then for each new type of data record to include, simply use something
like:

pro MyClassDef::AddRec, name, data
rec={MyClassData_Rec,Name:name,Data:ptr_new(data)}
if ptr_valid(self.Recs) then $
*self.Recs=[*self.Recs,rec] else self.Recs=ptr_new([rec])
end

You can easily also put in code to remove data records during run-time
or do any other attribute manipulation, based on the Name field (or
other relevant fields), etc. Obviously this can grow quite powerful,
but be forewarned that such power is easily misused.

When it's time to cleanup, we have simply:

pro MyClassDef::Cleanup
if ptr_valid(self.Recs) then ptr_free,(*self.Recs).Data, self.Recs
end

Note that ptr_free doesn't care if the pointer is a null pointer (in
fact it's faster just to free it without testing for this), but
dereferencing does -- hence the first ptr_valid() test is the only one
necessary.

Good Luck,

JD

P.S. The proper way to reference things is then:

; A pointer to a single attribute's data
thedataptr=(*self.Recs)[element].Data

; all pointers to all attributes' data
alldataptrs=(*self.Recs).Data

; a single attribute's data vector (or array, or ....)
thedata=*(*self.Recs)[element].Data

;an vector of names of all the attributes
attrs=(*self.Recs).Name

etc.

--
J.D. Smith |*| WORK: (607) 255-5842
Cornell University Dept. of Astronomy |*| (607) 255-6263
304 Space Sciences Bldg. |*| FAX: (607) 255-5875
Ithaca, NY 14853 |*|
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Re: Y axis where Z axis is by default w/ surface
Next Topic: Re: simple string manipulation problem

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

Current Time: Fri Oct 10 09:58:43 PDT 2025

Total time taken to generate the page: 0.64049 seconds