;+ ; NAME: ; NCDF_ATTRIBUTE ; ; PURPOSE: ; ; The pupose of this NCDF_Attribute object is to store information about ; a netCDF global or variable attribute. The object is principally used ; as a utility routine for the NCDF_FILE object. Given the attribute name, ; the object will acquire additional information about the attribute from ; the netCDF file containing the attribute. ; ; AUTHOR: ; ; FANNING SOFTWARE CONSULTING ; David Fanning, Ph.D. ; 1645 Sheely Drive ; Fort Collins, CO 80526 USA ; Phone: 970-221-0438 ; E-mail: david@idlcoyote.com ; Coyote's Guide to IDL Programming: http://www.idlcoyote.com ; ; CATEGORY: ; File I/O ; ; CALLING SEQUENCE: ; ; IDL> attrObj = Obj_New('NCDF_ATTRIBUTE', attrName, parent, VARNAME=varName) ; ; ARGUMENTS: ; ; attrName: The case sensitive name of a netCDF attribute that is stored in the ; netCDF file. (Input and required.) ; ; parent: The object reference (NCDF_FILE object) of the netCDF file. In other words, the ; object reference of the file that contains this attribute. (Input and required.) ; ; KEYWORD PARAMETERS: ; ; varName: If this is a variable attribute, this is the case sensitive name of the ; variable that the attribute is attached to. (Input and required for variable ; attributes.) Note that a variable object reference may be used in place of the ; variable name. ; ; METHODS: ; ; The following methods are available. Each is documented in front of the method. ; ; attrName = attrObject -> GetName() ; propertyValue = attrObject -> GetProperty(attrProperty) ; attrValue = attrObject -> GetValue() ; attrObject -> ParseAttribute ; ; ; MODIFICATION HISTORY: ; Written by: David W. Fanning, 3 Feb 2010. ;- ;******************************************************************************************; ; Copyright (c)2010, by Fanning Software Consulting, Inc. ; ; All rights reserved. ; ; ; ; Redistribution and use in source and binary forms, with or without ; ; modification, are permitted provided that the following conditions are met: ; ; ; ; * Redistributions of source code must retain the above copyright ; ; notice, this list of conditions and the following disclaimer. ; ; * Redistributions in binary form must reproduce the above copyright ; ; notice, this list of conditions and the following disclaimer in the ; ; documentation and/or other materials provided with the distribution. ; ; * Neither the name of Fanning Software Consulting, Inc. nor the names of its ; ; contributors may be used to endorse or promote products derived from this ; ; software without specific prior written permission. ; ; ; ; THIS SOFTWARE IS PROVIDED BY FANNING SOFTWARE CONSULTING, INC. ''AS IS'' AND ANY ; ; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ; ; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT ; ; SHALL FANNING SOFTWARE CONSULTING, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, ; ; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ; ; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ; ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ; ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ; ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; ;******************************************************************************************; ;-----------------------------------------------------------------------------------------; ; ; NAME: ; NCDF_Attribute::GetName ; ; Purpose: ; ; Returns the name of the attribute. ; ; Method Syntax: ; ; attrName = obj -> GetName() ; ; Auguments: ; ; None. ; ; Keywords: ; ; None. ; ; Return Value: ; ; attrName: A string variable containing the attribute name. ; ;------------------------------------------------------------------------------------------; FUNCTION NCDF_Attribute::GetName RETURN, self.name END ;-----------------------------------------------------------------------------------------; ; ; NAME: ; NCDF_Attribute::GetProperty ; ; Purpose: ; ; Returns various properties of the object one at a time. This is a shorthand and ; ; generic way to get the value of an object's "properties", which are defined as ; ; the IDL variables in the object's class structure. ; ; Method Syntax: ; ; propertyValue = obj -> GetProperty(thisProperty) ; ; Auguments: ; ; thisProperty: A string variable that is equivalent to a field in the object's ; ; class structure. See the *__DEFINE procedure for which properties ; ; can be returned. The property is case insensitive. ; ; Keywords: ; ; None. ; ; Return Value: ; ; propertyValue: The value of a particular object property. Note that pointer ; ; properties will return the variable the pointer points to. ; ; ;------------------------------------------------------------------------------------------; FUNCTION NCDF_Attribute::GetProperty, thisProperty ; Compiler options. Compile_Opt DEFINT32 Compile_Opt STRICTARR Compile_Opt STRICTARRSUBS Compile_Opt LOGICAL_PREDICATE Catch, theError IF theError NE 0 THEN BEGIN Catch, /CANCEL ; Log the error. (self.parent -> GetProperty('ERRORLOGGER')) -> AddError ; No success finding the property requested. RETURN, 0 ENDIF ; Get the self structure as a structure, rather than as an object. Call_Procedure, StrLowCase(Obj_Class(self)) + '__define', classStruct ; Find the property in this class structure. index = Where(StrPos(Tag_Names(classStruct), StrUpCase(thisProperty)) EQ 0, count) index = index[0] ; What happened? CASE count OF 0: Message, 'Property ' + StrUpCase(thisProperty) + ' could not be found.' 1: propertyValue = self.(index) ELSE: Message, 'Ambiguous property. Use more characters to specify it.' ENDCASE ; If this is a pointer, you want the thing pointed to. IF Size(propertyValue, /TNAME) EQ 'POINTER' THEN propertyValue = *propertyValue ; Strings are stored as bytes in netCDF files, so convert these back to strings. IF (Size(propertyValue, /TNAME) EQ 'BYTE') && (self.datatype EQ 'CHAR') THEN BEGIN propertyValue = String(propertyValue) ENDIF ; Make sure you return scalars, if needed. IF N_Elements(propertyValue) EQ 1 THEN propertyValue = propertyValue[0] RETURN, propertyValue END ;-----------------------------------------------------------------------------------------; ; ; NAME: ; NCDF_Attribute::GetValue ; ; Purpose: ; ; Returns the value of the attribute. ; ; Method Syntax: ; ; attrValue = obj -> GetValue(DATATYPE=datatype) ; ; Auguments: ; ; None. ; ; Keywords: ; ; DATATYPE: An output keyword that contains the netCDF data type of the attribute. ; ; ; Return Value: ; ; attrValue: A variable containing the attribute's value. ; ;------------------------------------------------------------------------------------------; FUNCTION NCDF_Attribute::GetValue, DATATYPE=datatype ; Compiler options. Compile_Opt DEFINT32 Compile_Opt STRICTARR Compile_Opt STRICTARRSUBS Compile_Opt LOGICAL_PREDICATE On_Error, 2 ; Get the value. theValue = *self.value datatype = self.datatype ; Strings are stored as bytes in netCDF files, so convert these back to strings. IF (Size(theValue, /TNAME) EQ 'BYTE') && (self.datatype EQ 'CHAR') THEN BEGIN theValue = String(theValue) ENDIF ; Make sure you return scalars, if needed. IF N_Elements(theValue) EQ 1 THEN theValue = theValue[0] RETURN, theValue END ;-----------------------------------------------------------------------------------------; ; ; NAME: ; NCDF_Attribute::ParseAttribute ; ; Purpose: ; ; Gathers information about the attribute from the netCDF file. ; ; Method Syntax: ; ; attrObject -> ParseAttribute ; ; Auguments: ; ; None. ; ; Keywords: ; ; None. ; ;------------------------------------------------------------------------------------------; PRO NCDF_Attribute::ParseAttribute ; Compiler options. Compile_Opt DEFINT32 Compile_Opt STRICTARR Compile_Opt STRICTARRSUBS Compile_Opt LOGICAL_PREDICATE On_Error, 2 ; Gather information about the attribute. fileID = self.parent -> GetFileID() IF (self.varID GE 0) THEN BEGIN attrInfo = NCDF_AttInq(fileID, self.varID, self.name) NCDF_AttGet, fileID, self.varID, self.name, value ENDIF ELSE BEGIN attrInfo = NCDF_AttInq(fileID, GLOBAL=1, self.name) NCDF_AttGet, fileID, self.name, value, GLOBAL=1 ENDELSE self.datatype = StrUpCase(attrInfo.datatype) self.length = attrInfo.length self.value = Ptr_New(value, /NO_COPY) END PRO NCDF_Attribute::CLEANUP Ptr_Free, self.value END FUNCTION NCDF_Attribute::INIT, attrName, parent, VARNAME=varName ; Compiler options. Compile_Opt DEFINT32 Compile_Opt STRICTARR Compile_Opt STRICTARRSUBS Compile_Opt LOGICAL_PREDICATE ; Error handling. Return 0 if can't finish. CATCH, theError IF theError NE 0 THEN BEGIN CATCH, /CANCEL errorLogger = parent -> GetProperty('ERRORLOGGER') errorLogger -> AddError RETURN, 0 ENDIF ; Check parameters. IF N_Elements(attrName) EQ 0 THEN Message, 'An attribute name is required' IF Size(attrName, /TNAME) NE 'STRING' THEN $ Message, 'The attribute name must be a string.' self.name = attrName IF N_Elements(parent) EQ 0 THEN Message, 'A parent object is required.' IF Size(parent, /TNAME) NE 'OBJREF' THEN $ Message, 'The parent parameter must be an object reference.' self.parent = parent ; Check to see what you got as a variable reference. IF N_Elements(varName) NE 0 THEN BEGIN CASE Size(varName, /TNAME) OF 'STRING': BEGIN check = self.parent -> HasVar(varName, OBJECT=varObj) IF check THEN BEGIN varID = varObj -> GetID() ENDIF ELSE Message, 'Cannot find a variable named "' + $ varName + '" in the file.' END 'OBJREF': BEGIN varObj = varName varID = varObj -> GetID() END ELSE: BEGIN ; Treat as the variable ID. varID = varName END ENDCASE ENDIF ; Store the variable ID associated with this attribute, if there is one. IF N_Elements(varID) NE 0 THEN BEGIN self.varID = varID self.global = 0 ENDIF ELSE BEGIN self.varID = -1 self.global = 1 ENDELSE ; Obtain information about the attribute and fill out the attribute object. self -> ParseAttribute RETURN, 1 END PRO NCDF_Attribute__DEFINE, class class = { NCDF_ATTRIBUTE, $ name: "", $ ; The attribute name. parent: Obj_New(), $ ; The NCDF_FILE object where this attribute resides. global: 0B, $ ; A flag that indicates a global attribute. varID: 0L, $ ; If this is a variable attribute, the ID of the variable. length: 0L, $ ; The length of the attribute. value: Ptr_New(), $ ; The value of the attribute. datatype: "" $ ; The datatype of the attribute. } END