#ifdef _SOLARIS
#include <ieeefp.h>
#endif
#include "TFFitsIO.h"
#include "TFError.h"
#include "TFIOElement.h"
#include "TFGroup.h"
#include "TFImage.h"
#include "fitsio.h"
#ifndef TF_CLASS_IMP
#define TF_CLASS_IMP
ClassImp(TFFitsIO)
ClassImp(TFFitsFileIter)
#endif
static const char * errMsg[] = {
"Cannot open the file %s. FITS error: %d",
"Cannot write/update keyword %s of %s in file %s. FITS error: %d",
"HDU %s does not exist in file %s",
"HDU number %d does not exist in file %s",
"HDU number %d in file %s has name %s, but expecting name %s",
"Found %s in file %s, but expected a %s",
"Can neither create nor open the file %s",
"Neither name nor HDU number is defined. Cannot open an element in file %s"
};
static void HeaderFits2Root(fitsfile * fptr, TFIOElement * element, int * status);
static void HeaderRoot2Fits(TFIOElement * element, fitsfile * fptr, int * status);
TFIOElement * MakeTable(fitsfile * fptr, int * status);
int CreateFitsTable(fitsfile* fptr, TFTable * table);
int SaveTable(fitsfile* fptr, TFTable* table);
TFIOElement * MakeImage(fitsfile * fptr, int * status);
int CreateFitsImage(fitsfile* fptr, TFBaseImage* image);
int SaveImage(fitsfile* fptr, TFBaseImage* image);
TFFitsIO::TFFitsIO( TFIOElement * element, const char * fileName)
: TFVirtualIO(element)
{
int status = 0;
fits_create_file((fitsfile**)&fFptr, fileName, &status);
if (status != 0)
{
status = 0;
fits_open_file((fitsfile**)&fFptr, fileName, READWRITE, &status);
if (status != 0)
{
TFError::SetError("TFFitsIO::TFFitsIO", errMsg[6], fileName);
fFptr = NULL;
}
}
else
{
long axis[1] = {0};
fits_create_img((fitsfile*)fFptr, SHORT_IMG, 0, axis, &status);
}
}
TFFitsIO::TFFitsIO( TFIOElement * element, void * fptr, int cycle)
: TFVirtualIO(element)
{
fFptr = fptr;
fCycle = cycle;
}
TFFitsIO::~TFFitsIO()
{
int status = 0;
if (fFptr)
fits_close_file((fitsfile*)fFptr, &status);
}
TFIOElement * TFFitsIO::TFRead(const char * fileName, const char * name,
Int_t cycle, FMode mode, TClass * classType)
{
int status = 0;
fitsfile * fptr;
fits_open_file(&fptr, fileName, mode == kFRead ? READONLY : READWRITE,
&status);
if (status != 0)
{
TFError::SetError("TFFitsIO::TFRead", errMsg[0], fileName, status);
return NULL;
}
if (cycle <= 0)
{
if (name == NULL || name[0] == 0)
{
TFError::SetError("TFFitsIO::TFRead", errMsg[7], fileName);
return NULL;
}
char * tmpName = new char[strlen(name) + 1];
strcpy(tmpName, name);
fits_movnam_hdu(fptr, ANY_HDU, tmpName, -cycle, &status);
delete [] tmpName;
if (status != 0)
{
status = 0;
char gr[10];
strcpy(gr, "GROUPING");
fits_movnam_hdu(fptr, ANY_HDU, gr, 0, &status);
if ( status != 0 )
{
TFError::SetError("TFFitsIO::TFRead", errMsg[2], name, fileName);
fits_close_file(fptr, &status);
return NULL;
}
}
int hduNum;
fits_get_hdu_num(fptr, &hduNum);
cycle = hduNum;
}
else
{
fits_movabs_hdu(fptr, cycle, NULL, &status);
if (status != 0)
{
TFError::SetError("TFFitsIO::TFRead", errMsg[3], cycle, fileName);
status = 0;
fits_close_file(fptr, &status);
return NULL;
}
}
TFIOElement * element;
char elementType[20];
char keyname[20];
strcpy(keyname, "XTENSION");
fits_read_keyword(fptr, keyname, elementType, NULL, &status);
if (status == 0 && strcmp(elementType , "'BINTABLE'") == 0)
{
element = MakeTable(fptr, &status);
}
else if ( (status == 0 && strstr(elementType , "IMAGE") != NULL ) ||
status == 202 )
{
status = 0;
element = MakeImage(fptr, &status);
}
else
{
element = new TFIOElement("no name");
status = 0;
}
if (element && status == 0 && classType)
{
if (element->IsA() != classType)
if (classType != TFBaseImage::Class() ||
!element->IsA()->InheritsFrom(classType))
{
TFError::SetError("TFFitsIO::TFRead", errMsg[5],
element->ClassName(), fileName,
classType->GetName());
delete element;
fits_close_file(fptr, &status);
return NULL;
}
}
HeaderFits2Root(fptr, element, &status);
if (element && status == 0 && name && name[0] != 0 )
{
char elementName[110];
strcpy(elementName, element->GetName());
char * pos = strrchr(elementName, '_');
if (pos) *pos = 0;
if (strcmp(elementName, name) != 0)
{
if (!(strcmp(name, "GROUPING") == 0 &&
element->IsA()->InheritsFrom(TFGroup::Class()) ) )
{
TFError::SetError("TFFitsIO::TFRead", errMsg[4], cycle, fileName,
element->GetName(), name);
delete element;
fits_close_file(fptr, &status);
return NULL;
}
}
}
if (element)
{
element->SetIO(new TFFitsIO(element, fptr, cycle));
element->SetFileAccess(mode);
}
return element;
}
Bool_t TFFitsIO::IsOpen()
{
return fFptr != NULL;
}
const char * TFFitsIO::GetFileName()
{
if (fFptr == NULL)
return NULL;
int status = 0;
static char fileName[512];
fits_file_name((fitsfile*)fFptr, fileName, &status);
return status == 0 ? fileName : NULL;
}
Int_t TFFitsIO::GetCycle()
{
return fCycle;
}
void TFFitsIO::CreateElement()
{
if (fFptr == NULL)
return;
fitsfile * fptr = (fitsfile*)fFptr;
int status = 0;
if (fElement->IsA()->InheritsFrom(TFBaseImage::Class()))
status = CreateFitsImage(fptr, (TFBaseImage*)fElement);
if (fElement->IsA()->InheritsFrom(TFTable::Class()))
status = CreateFitsTable(fptr, (TFTable*)fElement);
if (status == 0)
{
int hduNum;
fits_get_hdu_num(fptr, &hduNum);
fCycle = (UInt_t)hduNum;
}
else
{
status = 0;
fits_close_file(fptr, &status);
fFptr = NULL;
}
}
Int_t TFFitsIO::DeleteElement()
{
if (fFptr == NULL)
return 0;
fitsfile * fptr = (fitsfile*)fFptr;
int status = 0;
int numHdus;
fits_get_num_hdus(fptr, &numHdus, &status);
if (status != 0) return -1;
if (numHdus == 1)
{
fits_delete_file(fptr, &status);
}
else
{
fits_delete_hdu(fptr, NULL, &status);
fits_close_file(fptr, &status);
}
fFptr == NULL;
return 0;
}
Int_t TFFitsIO::SaveElement(Int_t compLevel)
{
if (fFptr == NULL)
return 0;
fitsfile * fptr = (fitsfile*)fFptr;
int status = 0;
if (fElement->IsA()->InheritsFrom(TFBaseImage::Class()))
status = SaveImage(fptr, (TFBaseImage*)fElement);
else if (fElement->IsA()->InheritsFrom(TFTable::Class()))
status = SaveTable(fptr, (TFTable*)fElement);
HeaderRoot2Fits(fElement, fptr, &status);
fits_write_chksum(fptr, &status);
return status == 0 ? 0 : -1;
}
TFFitsFileIter::TFFitsFileIter(const char * fileName, FMode mode)
: TFVirtualFileIter(fileName)
{
int status = 0;
fStatus = 0;
fCycle = 0;
fMode = mode;
fitsfile * fptr;
fits_open_file(&fptr, fileName, mode == kFRead ? READONLY : READWRITE,
&status);
if (status == 0)
fFptr = fptr;
else
{
fFptr = NULL;
TFError::SetError("TFFitsFileIter::TFFitsFileIter", errMsg[0],
fileName, status);
}
}
TFFitsFileIter::~TFFitsFileIter()
{
int status = 0;
if (fFptr)
fits_close_file((fitsfile*)fFptr, &status);
}
Bool_t TFFitsFileIter::Next()
{
delete fElement;
fElement = NULL;
if (fFptr == NULL || fStatus != 0)
return kFALSE;
fitsfile * fptr = (fitsfile*)fFptr;
int status = 0;
char elementType[20];
char keyname[40];
strcpy(keyname, "XTENSION");
fits_read_keyword(fptr, keyname, elementType, NULL, &status);
if (status == 0 && strcmp(elementType , "'BINTABLE'") == 0)
{
fElement = MakeTable(fptr, &status);
}
else if ( (status == 0 && strstr(elementType , "IMAGE") != NULL ) ||
status == 202 )
{
status = 0;
fElement = MakeImage(fptr, &status);
}
else
{
fElement = new TFIOElement("no name");
status = 0;
}
if (fElement == NULL)
return kFALSE;
fitsfile * fptr2;
char filename[512];
sprintf(filename, "%s[%d]", fFileName.Data(), fCycle);
fits_open_file(&fptr2, filename, fMode == kFRead ? READONLY : READWRITE,
&status);
fCycle++;
fElement->SetIO(new TFFitsIO(fElement, fptr2, fCycle));
HeaderFits2Root(fptr, fElement, &status);
fits_movrel_hdu(fptr, 1, NULL, &fStatus);
return kTRUE;
}
void TFFitsFileIter::Reset()
{
if (fFptr == NULL)
return;
fCycle = 0;
fStatus = 0;
fits_movabs_hdu((fitsfile*)fFptr, 1, NULL, &fStatus);
}
static void HeaderFits2Root(fitsfile * fptr, TFIOElement * element, int * status)
{
if (*status != 0) return;
char name[30], value[100], comment[100], unit[40];
int nkeys;
fits_get_hdrspace(fptr, &nkeys, NULL, status);
for (int num = 0; num < nkeys && *status == 0; num++)
{
fits_read_keyn(fptr, num + 1, name, value, comment, status);
if (strncmp(name, "TTYPE", 5) == 0 ||
strncmp(name, "TFORM", 5) == 0 ||
strncmp(name, "TNULL", 5) == 0 ||
strncmp(name, "TZERO", 5) == 0 ||
strncmp(name, "TSCAL", 5) == 0 ||
strncmp(name, "NAXIS", 5) == 0 ||
strcmp (name, "XTENSION") == 0 ||
strcmp (name, "TFIELDS") == 0 ||
strcmp (name, "BITPIX") == 0 ||
strcmp (name, "PCOUNT") == 0 ||
strcmp (name, "GCOUNT") == 0 ||
strcmp (name, "BLANK") == 0 ||
strcmp (name, "BSCALE") == 0 ||
strcmp (name, "BZERO") == 0 ||
strcmp (name, "CHECKSUM") == 0 ||
strcmp (name, "DATASUM") == 0 )
continue;
fits_read_key_unit(fptr, name, unit, status);
if (value[0] == '\'' && value[strlen(value) - 1] == '\'')
{
int len = strlen(value) - 2;
while (value[len] == ' ') len--;
value[len+1] = 0;
if (strcmp("EXTNAME", name) != 0 && strcmp("GRPNAME", name) != 0)
element->AddAttribute(TFStringAttr(name, TString(value+1), unit, comment), kFALSE);
if ( (strcmp("EXTNAME", name) == 0 && strcmp("GROUPING", value+1) != 0) ||
(strcmp("GRPNAME", name) == 0) )
{
int hduNum = 0;
fits_get_hdu_num(fptr, &hduNum);
char elementName[110];
sprintf(elementName, "%s_%d", value+1, hduNum);
element->SetName(elementName);
}
}
else if (strcmp(value, "T") == 0)
element->AddAttribute(TFBoolAttr(name, kTRUE, unit, comment), kFALSE);
else if (strcmp(value, "F") == 0)
element->AddAttribute(TFBoolAttr(name, kFALSE, unit, comment), kFALSE);
else if (strlen(value) < 9 && value[0] != 0 && strchr(value, '.') == NULL)
element->AddAttribute(TFIntAttr(name, atoi(value), unit, comment), kFALSE);
else if (value[0] != 0)
{
Double_t val;
sscanf(value, "%lg", &val);
element->AddAttribute(TFDoubleAttr(name, val, unit, comment), kFALSE);
}
else
element->AddAttribute(TFStringAttr(name, TString(value), unit, comment), kFALSE);
}
}
static void HeaderRoot2Fits(TFIOElement * element, fitsfile * fptr, int * status)
{
if (*status != 0)
return;
TFAttrIter i_attr = element->MakeAttrIterator();
while (i_attr.Next())
{
char * comment = (char*)i_attr->GetComment();
if (comment[0] == 0) comment = NULL;
if (i_attr->IsA() == TFBoolAttr::Class())
{
int val = (int)((TFBoolAttr&)(*i_attr)).GetValue();
fits_update_key(fptr, TLOGICAL, (char*)i_attr->GetName(), &val,
comment, status);
}
else if (i_attr->IsA() == TFIntAttr::Class())
{
int val = ((TFIntAttr&)(*i_attr)).GetValue();
fits_update_key(fptr, TINT, (char*)i_attr->GetName(), &val,
comment, status);
}
else if (i_attr->IsA() == TFUIntAttr::Class())
{
unsigned int val = ((TFUIntAttr&)(*i_attr)).GetValue();
fits_update_key(fptr, TUINT, (char*)i_attr->GetName(), &val,
comment, status);
}
else if (i_attr->IsA() == TFDoubleAttr::Class())
{
double val = ((TFDoubleAttr&)(*i_attr)).GetValue();
fits_update_key(fptr, TDOUBLE, (char*)i_attr->GetName(), &val,
comment, status);
}
else if (i_attr->IsA() == TFStringAttr::Class())
{
const char * val = ((TFStringAttr&)(*i_attr)).GetValue().Data();
fits_update_key(fptr, TSTRING, (char*)i_attr->GetName(), (void*)val,
comment, status);
}
if (i_attr->GetUnit()[0] != 0)
fits_write_key_unit(fptr, (char*)i_attr->GetName(),
(char*)i_attr->GetUnit(), status);
if (*status != 0)
{
TFError::SetError("HeaderRoot2Fits", errMsg[1], i_attr->GetName(),
element->GetName(), fptr->Fptr->filename, *status);
*status = 0;
}
}
}
static void never_used()
{
int status;
fitsfile * fptr = NULL;
char * header;
ffgiwcs(fptr, &header, &status);
ffgtwcs(fptr, 1, 2, &header, &status);
}
Last update: Fri Mar 14 13:55:15 2008
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.