GAMAP tips and tricks

From Geos-chem
Revision as of 19:07, 3 April 2008 by Bmy (talk | contribs)
Jump to navigation Jump to search

Date and time

Hi Inna,

One thing....CALDAT converts an astronomical Julian Day back to month/day/year. Astronomical Julian Day starts on Jan 1, 4713BC. It's used to compute intervals between widely-separated dates.

I think you may be referring to Julian day as the "day since the 1st of the year", as Julian day can also refer to that.

A quick way to compute the day of the year is w/ IDL's JULDAY function:

   Day_of_Year = Julday( Month, Day, Year ) - Julday( 1, 0, Year )

For example:

   IDL> print, julday( 1, 10, 2008 ) - julday( 1, 0, 2008 )
   % Compiled module: JULDAY.
         10

Julday( 1, 0, 2008 ) is essentially 12/31/2008. You use this so that you don't have to add one to the above difference. (i.e. julday( m, d, y ) - julday( 1, 1, y ) + 1 would be equivalent).

This is essentially done for you in the GAMAP function ~/IDL/gamap2/day_of_year.pro. You could replace the above code with:

   IDL> print, day_of_year( 1, 10, 2008 )
         10

To do the reverse, you would have to use CALDAT but then add on the astronomical Julian day for the first of the year, for example:

   IDL> caldat, julday( 1, 0, 2008 )+10, y, m, d
   IDL> print, y, m, d
              1          10        2008

There is another GAMAP function called ADD_DATE that essentially does this. You can do the following:

   ; Convert month/day/year to day of year
   IDL> doy = day_of_year( 1, 10, 2008 )
   IDL> print, doy
         10
   ; convert day of year back to month/day/year
   IDL> print, add_date( 20080101, 10-1 )
       20080110

The only thing to remember is you have to subtract 1 from the day of year because the way ADD_DATE is written, it will add the # of days. This may be a better solution for you.

I used to be an astronomer so I am pretty familiar w/ all of these time definitions.  :-)

Hope this helps,

Bob Y.

Combining output from timeseries files

Ray Nassar (ray@io.as.harvard.edu) wrote:

I just have a quick question, is there any GAMAP routine that can average all hourly data blocks in a timeseries file to make a single daily average bpch file?
It appears like I could use the average option of ctm_sum.pro but I do not quite understand where the averaged data goes and afterwards would still have to write to bpch.

Philippe Le Sager (plesager@seas.harvard.edu) replied:

Check the
   /gamap2/timeseries/gc_combine_nd49.pro
   /gamap2/timeseries/gc_combine_nd48.pro 
routines, which combines daily bpch files (nd48 & nd49 output, but also met field input files) into 4D data blocks. It has many options. You can extract a subset of data according to time and/or location, or process the data (moving average, daily max, shift to local time). You can either save the data into a new bpch file or just get an array of data in output.
I wrote a tutorial that gives some pointers here.
-Philippe

--Bob Yantosca 09:43, 1 April 2008 (EDT)

Memory management and CTM_MAKE_DATAINFO

When using CTM_MAKE_DATAINFO, you create few pointers and allocate memory to pointed data. Three scenarios to free that memory are possible.

(1) By default, GAMAP keeps track of the pointers in a global structure, and you can clean up the memory by calling CTM_CLEANUP (with or without the keyword /NO_GC):

    ctm_make_datainfo(data, ...)
    CTM_WriteBpch, DataInfo, FileInfo, FileName=file
    ctm_cleanup

(2) If you use the keyword /NO_GLOBAL when calling CTM_MAKE_DATAINFO, the story is a little bit more subtle. Now, GAMAP has no idea of the created pointers. If you use CTM_CLEANUP without the keyword /NO_GC, everything is clean up because there is a call to heap_gc. But you are also loosing **all other** pointers and objects.

    ctm_make_datainfo(data, ..., /No_global)
    CTM_WriteBpch, DataInfo, FileInfo, FileName=file
    ctm_cleanup

Note if you do not call ctm_cleanup or call it with /No_GC, then the memory allocated by CTM_MAKE_DATAINFO is still allocated and the pointers that refers to it are alive... until you exit the routine (unless they are passed back). Once you are out of the routine, this memory remains allocated but is useless since unaccessible, in other words you have memory leak.

(3) So, if you want to keep some objects and/or pointers alive in your code (i.e., you do not want to call heap_gc or ctm_cleanup,/no_gc), you need to free only the created pointers as follows:

    ctm_make_datainfo(data, datainfo, fileinfo, ..., /No_global)
    CTM_WriteBpch, DataInfo, FileInfo, FileName=file
    ptr_free, DataInfo.data
    ptr_free, fileinfo.gridinfo

To free only the heap memory created by multiple calls to CTM_MAKE_DATAINFO, the procedure is:

  for D=0L, NTracers-1L do begin
     
     Success = CTM_Make_DataInfo( Data[*,*,D], DataInfo, FileInfo, ..., /No_Global )
     
     ArrDataInfo = D eq 0l ? [ DataInfo ] : [ ArrDataInfo, DataInfo ]
     
     if D ne Ntracers-1l then ptr_free, Fileinfo.gridinfo
     
  endfor
     
  CTM_WriteBpch, ArrDataInfo, FileInfo, FileName=OutFileName
     
  for d=0, n_elements(ArrDataInfo)-1l do ptr_free, ArrDataInfo[d].data
  ptr_free, fileinfo.gridinfo

--Philippe Le Sager 10:28, 13 February 2008