;+ ; ; The GRIB_Parse_Info extracts the metadata contents from records of a ; Gridded Binary (GRIB) file and returns the metadata in an IDL structure variable. ; ; @Param ; Info {in} {required} {type=string array} {default=none} ; A string array containing the raw, unparsed metadata for eaach record ; ; @Author ; JimP ; ITT Visual Information Solutions ; ; @Copyright ; ITT-VIS 2006 ; ; @Categories ; comma separated list ; ; @History ; Original 1998 ; ; @Returns ; An IDL structure that contains the metadata information for each record. ; ; @Requires ; idl_grib.dll, idl_grib.dlm ; ; @Restrictions ; This version currently only works up to version 6.2 of IDL ; ; @Version ; 1.0 ;- Function GRIB_Parse_Info, Info ; Provide some error handling Catch, ErrorNumber If (ErrorNumber ne 0) then Begin Catch, /Cancel Message, !error_state.msg, /Continue Return, -1 EndIf ; ; Define the IDL structure that will hold the header information Header = { $ DataFlag : 0L, $ Flag : { $ NXNY : [0L, 0L], $ LEN : 0L, $ DataStart : 0L, $ UnusedBits : 0L, $ NumBits : 0L, $ NX : 0L, $ NY : 0L $ }, $ Record : 0L, $ Byte : 0L, $ Date : '', $ Quantity : '', $ Description : '', $ Units : '', $ KDPS5 : 0L, $ KDPS6 : 0L, $ KDPS7 : 0L, $ Levels : LonArr(2), $ GridID : '', $ ANL : '', $ TimeRange : 0L, $ P1 : 0L, $ P2 : 0L, $ TimeU : 0L, $ NX : 0L, $ NY : 0L, $ Type : '', $ Grid : 0L, $ Num_in_AVE : 0L, $ Missing : 0L, $ Center : 0L, $ Subcenter : 0L, $ Process : 0L, $ Table : 0L, $ ProjectionType : '', $ MinMaxData : [0., 0.], $ NumBits : 0L, $ BDS_Ref : 0., $ DecScale : 0L, $ BinScale : 0L $ } ; Define a structure for the Projection information ProjectionInfo = {Empty : 0B} ; A valid header record should have 'rec' as first 3 characters ThisLine = (Where(StrPos(StrTrim(Info, 2), 'rec') eq 0, NRecLine))[0] If (NRecLine eq 0) then Begin Return, -1 EndIf If (ThisLine ne 0) then Begin ; This section defines the FLAG structure that is part of the header structure If (StrPos(Info[0], 'grib header') ne -1) then Begin Line = StrCompress(StrTrim(Info[0], 2)) Header.DataFlag = 1 Components = StrTok(Line, ' ', /Extract) Header.Flag.NXNY = Long(Components[9:10]) Line = StrCompress(StrTrim(Info[1], 2)) Components = StrTok(Line, ' ', /Extract) Header.Flag.LEN = Long(Components[1]) Header.Flag.DataStart = Long(Components[3]) Header.Flag.UnusedBits = Long(Components[5]) Header.Flag.NumBits = Long(Components[7]) Header.Flag.NX = Long(Components[9]) Header.Flag.NY = Long(Components[11]) EndIf EndIf ; Assign all values to the header structure fields RecLine = Info[ThisLine] Components = StrTok(StrMid(RecLine, 4), ':', /Extract) Header.Record = Long(Components[0]) Header.Byte = Long(Components[1]) SpaceComponents = StrTok(Components[2], ' ', /Extract) Header.Date = SpaceComponents[1] Header.Quantity = SpaceComponents[2] KDPS5Components = StrTok(SpaceComponents[3], '=', /Extract) Header.KDPS5 = KDPS5Components[1] KDPS6Components = StrTok(SpaceComponents[4], '=', /Extract) Header.KDPS6 = KDPS6Components[1] KDPS7Components = StrTok(SpaceComponents[5], '=', /Extract) Header.KDPS7 = KDPS7Components[1] LevelsComponents = StrTok(SpaceComponents[6], '=', /Extract) Levels = Byte(LevelsComponents[1]) Levels[0] = 32B Levels[N_elements(Levels) - 1] = 32B Levels = StrTok(StrTrim(Levels, 2), ',', /Extract) Header.Levels = Long(Levels) GridComponents = StrTok(RecLine, 'grid', /Extract, /REGEX) GridInfo = StrTok(GridComponents[1], '=', /Extract) GridInfo = StrTok(GridInfo[0], 'anl', /Extract, /REGEX) Header.GridID = StrTrim(GridInfo[0], 2) ANLComponents = StrTok(StrTrim(RecLine, 2), ' anl:', /Extract, /REGEX) If (N_elements(ANLComponents) gt 1) then Begin BitmapSep = StrTok(ANLComponents[1], 'bitmap', /Extract, /REGEX) Header.ANL = StrTrim(BitmapSep[0], 2) EndIf MissingComponents = StrTok(StrTrim(RecLine, 2), 'bitmap', /Extract, /REGEX) If (N_elements(MissingComponents) eq 2) then Begin Missing = StrTok(StrCompress(MissingComponents[1]), ' ', /Extract) Header.Missing = Long(Missing[1]) EndIf ThisLine = ThisLine + 1 Equals = StrPos(Info[ThisLine], '=') DescriptionComponents = StrMid(Info[ThisLine], Equals + 1) Description = StrTok(DescriptionComponents, '[', /Extract) Header.Description = StrTrim(Description[0], 2) ; Added this check since I found files where the description variable ; is only 1 element and its value is "undefined" IF N_ELEMENTS(description) EQ 2 THEN Units = Byte(StrTrim(Description[1], 2)) ELSE Units = '' Units[N_elements(Units) - 1] = 32B Header.Units = StrTrim(Units, 2) ThisLine = ThisLine + 1 ThirdLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(ThirdLine, ' ', /Extract) Header.TimeRange = Long(Components[1]) Header.P1 = Long(Components[3]) Header.P2 = Long(Components[5]) Header.TimeU = Long(Components[7]) Header.NX = Long(Components[9]) Header.NY = Long(Components[11]) Header.Type = Components[12] Header.Grid = Long(Components[14]) Header.Num_in_Ave = Long(Components[16]) Header.Missing = Long(Components[18]) ThisLine = ThisLine + 1 FourthLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(FourthLine, ' ', /Extract) Header.Center = Long(Components[1]) Header.Subcenter = Long(Components[3]) Header.Process = Long(Components[5]) Header.Table = Long(Components[7]) ThisLine = ThisLine + 1 FifthLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(FifthLine, ':', /Extract) Header.ProjectionType = StrUpCase(StrTrim(Components[0], 2)) ; Depending on the projection type we define different project structures Case Header.ProjectionType of 'LATLON' : Begin ProjectionInfo = { $ Lat1 : 0., $ Lat2 : 0., $ DLat : 0., $ NXNY : 0L, $ Lon1 : 0., $ Lon2 : 0., $ DLon : 0., $ Dimensions : [0L, 0L], $ Scan : 0L, $ Mode : 0L, $ BDSGrid : 0L $ } Components = StrTok(StrTrim(Components[1], 2), ' ', /Extract) ProjectionInfo.Lat1 = Float(Components[1]) ProjectionInfo.Lat2 = Float(Components[3]) ProjectionInfo.DLat = Float(Components[5]) ProjectionInfo.NXNY = Long(Components[7]) ThisLine = ThisLine + 1 SixthLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(SixthLine, ' ', /Extract) ProjectionInfo.Lon1 = Float(Components[1]) ProjectionInfo.Lon2 = Float(Components[3]) ProjectionInfo.DLon = Float(Components[5]) ProjectionInfo.Dimensions = Long([StrMid(Components[6], 1), $ StrMid(Components[8], 0, StrLen(Components[8]) - 1)]) ProjectionInfo.Scan = Long(Components[10]) ProjectionInfo.Mode = Long(Components[12]) ProjectionInfo.BDSGrid = Long(Components[14]) End 'THINNED LATLON' : Begin ProjectionInfo = { $ Lat1 : 0., $ Lat2 : 0., $ DLat : 0., $ NXNY : 0L, $ Lon1 : 0., $ Lon2 : 0., $ GridPoints : 0L, $ Dimensions : [0L, 0L], $ Scan : 0L, $ Mode : 0L, $ BDSGrid : 0L, $ ThinLon : 0. $ } Components = StrTok(StrTrim(Components[1], 2), ' ', /Extract) ProjectionInfo.Lat1 = Float(Components[1]) ProjectionInfo.Lat2 = Float(Components[3]) ProjectionInfo.DLat = Float(Components[5]) ProjectionInfo.NXNY = Long(Components[7]) ThisLine = ThisLine + 1 SixthLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(SixthLine, ' ', /Extract) ProjectionInfo.Lon1 = Float(Components[1]) ProjectionInfo.Lon2 = Float(Components[3]) ProjectionInfo.GridPoints = Long(Components[4]) ProjectionInfo.Dimensions = Long([StrMid(Components[7], 1), $ StrMid(Components[9], 0, StrLen(Components[9]) - 1)]) ProjectionInfo.Scan = Long(Components[11]) ProjectionInfo.Mode = Long(Components[13]) ProjectionInfo.BDSGrid = Long(Components[15]) ThisLine = ThisLine + 1 SeventhLine = StrCompress(StrTrim(Info[ThisLine], 2)) Projection.ThinLon = Float(SeventhLine) End 'GAUSSIAN' : Begin ProjectionInfo = { $ Lat1 : 0., $ Lat2 : 0., $ Lon1 : 0., $ Lon2 : 0., $ DLon : 0., $ Dimensions : [0L, 0L], $ Scan : 0L, $ Mode : 0L, $ BDSGrid : 0L $ } Components = StrTok(StrTrim(Components[1], 2), ' ', /Extract) ProjectionInfo.Lat1 = Float(Components[1]) ProjectionInfo.Lat2 = Float(Components[3]) ThisLine = ThisLine + 1 SixthLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(SixthLine, ' ', /Extract) ProjectionInfo.Lon1 = Float(Components[1]) ProjectionInfo.Lon2 = Float(Components[3]) ProjectionInfo.DLon = Long(Components[5]) ProjectionInfo.Dimensions = Long([StrMid(Components[6], 1), $ StrMid(Components[8], 0, StrLen(Components[8]) - 1)]) ProjectionInfo.Scan = Long(Components[10]) ProjectionInfo.Mode = Long(Components[12]) ProjectionInfo.BDSGrid = Long(Components[14]) End 'THINNED GAUSSIAN' : Begin ProjectionInfo = { $ Lat1 : 0., $ Lat2 : 0., $ Lon1 : 0., $ GridPoints : 0L, $ Dimensions : [0L, 0L], $ Scan : 0L, $ Mode : 0L, $ BDSGrid : 0L, $ NLat : 0L, $ ThinLon : 0. $ } Components = StrTok(StrTrim(Components[1], 2), ' ', /Extract) ProjectionInfo.Lat1 = Float(Components[1]) ProjectionInfo.Lat2 = Float(Components[3]) ThisLine = ThisLine + 1 SixthLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(SixthLine, ' ', /Extract) ProjectionInfo.Lon1 = Float(Components[1]) ProjectionInfo.GridPoints = Long(Components[2]) ProjectionInfo.Dimensions = Long([StrMid(Components[5], 1), $ StrMid(Components[7], 0, StrLen(Components[7]) - 1)]) ProjectionInfo.Scan = Long(Components[9]) ProjectionInfo.Mode = Long(Components[11]) ProjectionInfo.BDSGrid = Long(Components[13]) ThisLine = ThisLine + 1 SeventhLine = StrCompress(StrTrim(Info[ThisLine], 2)) Projection.ThinLon = Float(SeventhLine) End 'POLAR STEREO' : Begin ProjectionInfo = { $ Lat1 : 0., $ Lon1 : 0., $ Orient : 0., $ Pole : '', $ Dimensions : [0L, 0L], $ DX : 0., $ DY : 0., $ Scan : 0L $ } Components = StrTok(StrTrim(Components[1], 2), ' ', /Extract) ProjectionInfo.Lat1 = Float(Components[1]) ProjectionInfo.Lon1 = Float(Components[3]) ProjectionInfo.Orient = Float(Components[5]) ThisLine = ThisLine + 1 SixthLine = StrCompress(StrTrim(Info[ThisLine], 2)) PoleComponents = StrTok(SixthLine, 'pole', /Extract, /REGEX) ProjectionInfo.Pole = StrUpCase(StrTrim(PoleComponents[0], 2)) DimensionsComponents = StrTrim(StrTok(StrTrim(PoleComponents[1], 2), ')', /Extract), 2) DimensionsComponents2 = StrTrim(StrTok(DimensionsComponents[0], 'x', /Extract), 2) ProjectionInfo.Dimensions[0] = Long(StrMid(DimensionsComponents2[0], 1)) ProjectionInfo.Dimensions[1] = Long(DimensionsComponents2[1]) Components = StrTok(StrTrim(DimensionsComponents[1], 2), ' ', /Extract) ProjectionInfo.DX = Float(Components[1]) ProjectionInfo.DY = Float(Components[3]) ProjectionInfo.Scan = Long(Components[5]) End 'LAMBERT CONF' : Begin ProjectionInfo = { $ Lat1 : 0., $ Lon1 : 0., $ Lov : 0., $ Latin1 : 0., $ Latin2 : 0., $ LatSP : 0., $ LonSP : 0., $ Pole : '', $ Dimensions : [0L, 0L], $ DX : 0., $ DY : 0., $ Scan : 0L, $ Mode : 0L $ } Components = StrTok(StrTrim(Components[1], 2), ' ', /Extract) ProjectionInfo.Lat1 = Float(Components[1]) ProjectionInfo.Lon1 = Float(Components[3]) ProjectionInfo.Lov = Float(Components[5]) ThisLine = ThisLine + 1 SixthLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(SixthLine, ' ', /Extract) ProjectionInfo.Latin1 = Float(Components[1]) ProjectionInfo.Latin2 = Float(Components[3]) ProjectionInfo.LatSP = Float(Components[5]) ProjectionInfo.LonSP = Float(Components[7]) ThisLine = ThisLine + 1 SeventhLine = StrCompress(StrTrim(Info[ThisLine], 2)) PoleComponents = StrTok(SeventhLine, 'Pole', /Extract, /REGEX) ProjectionInfo.Pole = StrUpCase(StrTrim(PoleComponents[0], 2)) DimensionsComponents = StrTrim(StrTok(StrTrim(PoleComponents[1], 2), ')', /Extract), 2) DimensionsComponents2 = StrTrim(StrTok(DimensionsComponents[0], 'x', /Extract), 2) ProjectionInfo.Dimensions[0] = Long(StrMid(DimensionsComponents2[0], 1)) ProjectionInfo.Dimensions[1] = Long(DimensionsComponents2[1]) Components = StrTok(StrTrim(DimensionsComponents[1], 2), ' ', /Extract) ProjectionInfo.DX = Float(Components[1]) ProjectionInfo.DY = Float(Components[3]) ProjectionInfo.Scan = Long(Components[5]) ProjectionInfo.Mode = Long(Components[7]) End 'MERCATOR' : Begin ProjectionInfo = { $ Lat1 : 0., $ Lat2 : 0., $ DLat : 0., $ NXNY : 0L, $ Lon1 : 0., $ Lon2 : 0., $ DLon : 0., $ Dimensions : [0L, 0L], $ Scan : 0L, $ Mode : 0L, $ Latin : 0., $ BDSGrid : 0L $ } Components = StrTok(StrTrim(Components[1], 2), ' ', /Extract) ProjectionInfo.Lat1 = Float(Components[1]) ProjectionInfo.Lat2 = Float(Components[3]) ProjectionInfo.DLat = Float(Components[5]) ProjectionInfo.NXNY = Long(Components[7]) ThisLine = ThisLine + 1 SixthLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(SixthLine, ' ', /Extract) ProjectionInfo.Lon1 = Float(Components[1]) ProjectionInfo.Lon2 = Float(Components[3]) ProjectionInfo.DLon = Float(Components[5]) ProjectionInfo.Dimensions = Long([StrMid(Components[6], 1), $ StrMid(Components[8], 0, StrLen(Components[8]) - 1)]) ProjectionInfo.Scan = Long(Components[10]) ProjectionInfo.Mode = Long(Components[12]) ProjectionInfo.Latin = Float(Components[14]) ProjectionInfo.BDSGrid = Long(Components[16]) End 'SEMI-STAGGERED ARAKAWA E-GRID' : Begin ProjectionInfo = { $ Lat1 : 0., $ Lon1 : 0., $ NXNY : 0L, $ DLat : 0., $ DLon : 0., $ GridPoints : 0L, $ Dimensions : [0L, 0L], $ Scan : 0L, $ Mode : 0L $ } Components = StrTok(StrTrim(Components[1], 2), ' ', /Extract) ProjectionInfo.Lat1 = Float(Components[1]) ProjectionInfo.Lon1 = Float(Components[3]) ProjectionInfo.NXNY = Long(Components[5]) ThisLine = ThisLine + 1 SixthLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(SixthLine, ' ', /Extract) ProjectionInfo.DLat = Float(Components[1]) ProjectionInfo.DLon = Float(Components[3]) ProjectionInfo.Dimensions = Long([StrMid(Components[4], 1), $ StrMid(Components[6], 0, StrLen(Components[6]) - 1)]) ProjectionInfo.Scan = Long(Components[8]) ProjectionInfo.Mode = Long(Components[10]) End 'FILLED ARAKAWA E-GRID' : Begin ProjectionInfo = { $ Lat1 : 0., $ Lon1 : 0., $ NXNY : 0L, $ DLat : 0., $ DLon : 0., $ GridPoints : 0L, $ Dimensions : [0L, 0L], $ Scan : 0L, $ Mode : 0L $ } Components = StrTok(StrTrim(Components[1], 2), ' ', /Extract) ProjectionInfo.Lat1 = Float(Components[1]) ProjectionInfo.Lon1 = Float(Components[3]) ProjectionInfo.NXNY = Long(Components[5]) ThisLine = ThisLine + 1 SixthLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(SixthLine, ' ', /Extract) ProjectionInfo.DLat = Float(Components[1]) ProjectionInfo.DLon = Float(Components[3]) ProjectionInfo.Dimensions = Long([StrMid(Components[4], 1), $ StrMid(Components[6], 0, StrLen(Components[6]) - 1)]) ProjectionInfo.Scan = Long(Components[8]) ProjectionInfo.Mode = Long(Components[10]) End 'ROTATED LATLON GRID' : Begin ProjectionInfo = { $ Lat1 : 0., $ Lat2 : 0., $ Lon1 : 0., $ Lon2 : 0., $ NXNY : 0L, $ Dimensions : [0L, 0L], $ DX : 0L, $ DY : 0L, $ Scan : 0L, $ Mode : 0L, $ SPoleLat : 0., $ SPoleLon : 0., $ Angle : 0. $ } Components = StrTok(StrTrim(Components[1], 2), ' ', /Extract) ProjectionInfo.Lat1 = Float(Components[1]) ProjectionInfo.Lat2 = Float(Components[3]) ProjectionInfo.Lon1 = Float(Components[5]) ProjectionInfo.Lon1 = Float(Components[7]) ThisLine = ThisLine + 1 SixthLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(SixthLine, ' ', /Extract) ProjectionInfo.NXNY = Long(Components[1]) ProjectionInfo.Dimensions = Long([StrMid(Components[2], 1), $ StrMid(Components[4], 0, StrLen(Components[4]) - 1)]) ProjectionInfo.DX = Float(Components[6]) ProjectionInfo.DY = Float(Components[8]) ProjectionInfo.Scan = Long(Components[10]) ProjectionInfo.Mode = Long(Components[12]) ThisLine = ThisLine + 1 SeventhLine = StrCompress(StrTrim(Info[ThisLine], 2)) Components = StrTok(SeventhLine, ' ', /Extract) ProjectionInfo.SPoleLat = Float(Components[4]) ProjectionInfo.SPoleLon = Float(Components[6]) ProjectionInfo.Angle = Long(Components[9]) End 'GNOMIC GRID' : Begin End 'HARMONIC (SPECTRAL)' : Begin End Else : EndCase ThisLine = ThisLine + 1 LastLine = StrCompress(StrTrim(Info[ThisLine], 2)) If (StrPos(LastLine, 'min/max data') ne -1) then Begin Components = StrTok(LastLine, ' ', /Extract) Header.MinMaxData[0] = Float(Components[2]) Header.MinMaxData[1] = Float(Components[3]) Header.NumBits = Long(Components[6]) Header.BDS_Ref = Float(Components[8]) Header.DecScale = Float(Components[10]) Header.BinScale = Float(Components[12]) EndIf Return, {Info : Header, Projection : ProjectionInfo} End ;======================================================== ;+ ; ; The READ_GRIB function is the IDL program that calls the IDL_GRIB dll. IDL_GRIB does the actual ; reading of the data and metadata contained in a Gridded Binary (GRIB) file. The data records are then ; processed by READ_GRIB and then returned to the calling programs. ; ; @Param ; file {in} {required} {type=string} {default=none} ; A scalar string specifying the full pathname of the GRIB file to read ; ; @Keyword ; records {in} {optional} {type=integer array} {default=none} ; An integer array used to specify the record numbers to be read. ; ; @Keyword ; Header_Only {in} {optional} {type=integer} {default=0} ; Set this keyword to indicate that the routine should return only metadata for each record ; ; @Keyword ; Data_Only {in} {optional} {type=integer} {default=0} ; Set this keyword to indicate that the routine should return only the data records. ; ; @Keyword ; Missing {in} {optional} {type=float} {default=none} ; Set this keyword to specify the value to use for missing data. ; ; @Author ; JimP ; ITT Visual Information Solutions ; ; @Copyright ; ITT-VIS 2006 ; ; @Categories ; File I/O ; ; @History ; Original 1998 ; ; @Returns ; Pointer array for the IDL data structure that contains the data and metadata ; ; @Requires ; IDL 6.2 ; ; @Restrictions ; Requires idl_grib.dll, idl_grib.dlm ; ; @Version ; 1.0 ;- Function Read_GRIB, File, $ Records = Records, $ Header_Only = Header_Only, $ Data_Only = Data_Only, $ Missing = Missing ; Provide some error handling Catch, ErrorNumber If (ErrorNumber ne 0) then Begin Catch, /Cancel Message, !error_state.msg, /Continue If (N_elements(pGribRecords) ne 0) then Begin For I = 0L, N_elements(pGribRecords) - 1 Do Begin Ptr_Free, pGribRecords[I] EndFor EndIf Return, -1 EndIf ; Only use these keywords if you want one or the other. To read both don't use the keywords If (Keyword_Set(Data_Only) and Keyword_Set(Header_Only)) then Begin Message, 'DATA_ONLY and HEADER_ONLY are mutually exclusive keywords.', /Continue Return, -1 EndIf ; this needs to be fixed up but it works for now dflag=0 if Keyword_Set(Data_Only) then dflag = 1 ; Pick the file if no file was specified If (N_elements(File) eq 0) then Begin File = Dialog_Pickfile(Filter=['*.grib','*.grb']) If (File eq '') then Begin Return, -1 EndIf EndIf ; Are there GRIB records in this file and how many? ; The IDL_Grib dll is used for reading the actual file. Stat = IDL_GRIB(file, Count = LCount) If (Stat ne 1) then Begin Message, 'No GRIB records found.', /Continue Return, -1 EndIf ; Create an array to hold pointers for all the records read pGribRecords = PtrArr(LCount) ; This will be for reading all the records in the file If (N_elements(Records) eq 0) then Begin GetRecords = StrTrim(LIndgen(LCount) + 1, 2) EndIf Else Begin ; specific records were requested GetRecords = StrTrim(Long(Records), 2) LCount = N_elements(GetRecords) EndElse ; Read each of the GRIB records For I = 0L, LCount - 1 Do Begin Stat = IDL_GRIB(File, Image, Dump = GetRecords[I], $ Diagnostic = Keyword_Set(Data_Only) eq dflag, $ Info = Info) If (Stat eq -1) then Begin For J = 0L, I - 1 Do Begin Ptr_Free, pGribRecords[J] EndFor Message, 'Error reading GRIB record ' + GetRecords[I] + '.', /Continue Return, -1 EndIf ; Extract the header information from the record Header = GRIB_Parse_Info(Info) ; If header is not of type 'Struct' then there was an error If (Size(Header[0], /TName) ne 'STRUCT') then Begin Return, -1 EndIf ; If a value was specified for MISSING data, assign it here If (N_elements(Missing) eq 1) then Begin ThisMissingLow = Where(Image lt Header.Info.MinMaxData[0], NThisMissing) If (NThisMissing ne 0) then Begin Image[ThisMissingLow] = Missing EndIf ThisMissingHigh = Where(Image gt Header.Info.MinMaxData[1], NThisMissing) If (NThisMissing ne 0) then Begin Image[ThisMissingHigh] = Missing EndIf EndIf ; Depending on what the user specifies for the data to be returned, ; pointers to the different choices are created and stored If (Keyword_Set(Data_Only)) then Begin pGribRecords[I] = Ptr_New(Image, /No_Copy) EndIf Else Begin If (Keyword_Set(Header_Only)) then Begin Image = 0B pGribRecords[I] = Ptr_New(Temporary(Header)) EndIf Else Begin ; read both data and header pGribRecords[I] = Ptr_New({Image : Temporary(Image), $ Header : Temporary(Header)}) EndElse EndElse EndFor ; Return the pointer array to the data Return, pGribRecords End