Find the place(s) in the code where a FITS file is opened and closed. For a Pegasus handler based on libff, the old call to open the file would look something like this:
ff_init(filename);
Replace it with:
HeaderUnit hu; hu = fh_file(filename, FH_FILE_RDWR); /* Or use FH_FILE_RDONLY if not updating */ if (!hu) /* ERROR ... */
If fh_file() was used instead of open(), fh_destroy() will close() the file, but for the same reasons, check the return of fh_destroy() if you opened a file for reading.
Calls to the libff routine to set a string:
ff_chng_value(FF_CARDNAME, FITS_STRING, string);
are changed to:
fh_set_str(hu, "CARDNAME", string, comment);
The actual "CARDNAME" and `comment' field can be found by looking inside the ``handler.def'' template file. After a handler is converted, and if DetCom is generating the FITS file (i.e., leaving room with fh_reserve) then the .def template is no longer needed.
ff_chng_value() calls with FITS_REAL, FITS_INTEGER, and FITS_LOGICAL are easiest to convert to directly to calls to fh_set_value(), which allows the calling program to do the sprintf'ing and precisely control the formatting of the value:
sprintf(String, "%15.6f", juliandate); ff_chng_value(FF_MJDOBS, FITS_REAL, String);
becomes:
sprintf(String, "%15.6f", juliandate); fh_set_value(hu, "MJD-OBS", String, comment);
(Note how the actual name of the FITS keyword is not always the name of the defined symbol less the FF_. You must check the template and ff/ff.h for the real name.)
See sections on fh_set_int(), fh_set_flt(), and fh_set_bool() for a way to set integer, float, and T/F values using the library's internal formatting. This is recommended over fh_set_value().
After all calls to fh_set_*() have been done, make one call to write the changes back to the file. Check for errors here!
if (fh_rewrite(hu) != FH_SUCCESS) rtn = FAIL; /* ... */ if (fh_destroy(hu) != FH_SUCCESS) rtn = FAIL; return rtn;
WARNING: Do not combine the two statements above with '||' (short-circuit logic), or simply ``return FAIL'' on the first failure because the memory and file locks associated with ``hu'' may not be properly released.
In Pegasus handlers with libff, this replaces the call to ff_flush() (and ff_free()).
Whether you used fh_file() or fh_create(), when the HeaderUnit is no longer needed, make a call to:
if (fh_destroy(hu) != FH_SUCCESS) return FAIL;
In Pegasus handlers, this replaces the call to ff_free().