#ifndef MARS_MWreitFitsFile #define MARS_MWreitFitsFile #include #include #include #ifndef ROOT_TClass #include #endif #ifndef MARS_MLogManip #include "MLogManip.h" #endif #ifndef MARS_MWriteFile #include "MWriteFile.h" #endif #ifndef MARS_MTopFitsGroup #include "MTopFitsGroup.h" #endif #ifndef MARS_MFitsArray #include "MFitsArray.h" #endif #ifndef MARS_MRawRunHeader #include "MRawRunHeader.h" #endif class MRawRunHeader; /////////////////////////////////////////////////////////////////////////////// // Information of one MParContainer, which data should be written into all or // just a few columns of one FITS table class MFitsSubTable { // the container, which data should be written to the FITS sub-table. MParContainer *fContainer; // used only if the Container is defined by its name. // if kTRUE must exist in the MParList of the program // if kFALSE the container is ignored. if it is not in the // MParList of the program Bool_t fMust; public: MFitsSubTable( Bool_t must) : fContainer(NULL), fMust(must) {} MFitsSubTable(MParContainer * container, Bool_t must) : fContainer(container), fMust(must) {} MFitsSubTable(const MFitsSubTable & subTable) : fContainer(subTable.fContainer), fMust(subTable.fMust) {} Bool_t MustHave() {return fMust;} MParContainer * GetContainer() {return fContainer;} void SetContainer(MParContainer * cont) {fContainer = cont;} }; /////////////////////////////////////////////////////////////////////////////// // A class to write data of MParContainer into FITS files. class MWriteFitsFile : public MWriteFile { private: // all (global) currently open top FITS groups. // Note: several instances of MWriteFitsFile can write to the same // top level FITS group (a top level FITS group corresponds to // one ROOT file) static std::map fTopFitsGroups; // pointer to the top level FITS group of this instance std::map::iterator iTopFitsGroup; // the key (TString) of following maps is the FITS table name, which // corresponds to one TTree // all main FITS table. Children tables to store data of // TClonesArray are not in this map. //ETIENNE ofits objects cannot be copied. So store pointers instead std::map fFitsTables; // all information needed to write data of TClonesArray to their // own FITS table. Note: one parent FTIS table may have several // children tables, each for one TClonesArray. std::map > fClHelper; // all information about the MParContainer, which data are stored // in the same FITS table. The key of map // is the class name of the MParContainer std::map > fSubTables; std::map > fDataPointers; std::map > fTypeChars; std::map > fColSizes; std::map > fColWidth; std::map fTableObjectCreated; std::map fTableHeaderWritten; void DeleteArrayHelper(); // rule to construct an output file-name from the input-filename TString fRule; TString fOpenOption; // RECREATE or NEW TString fGroupName; // name of top level group TString fTitle; // title of top level group void OpenTopLevelGroup(const char * fname); void CloseTopLevelGroup(); Bool_t InitColumns(const TString & tableName, const TString & parentVarName, ofits* fitsTable, void * baseAdr, TClass * classDef); void InitSingleColumn(const TString& tableName, uint32_t count, const std::string& typeName, void* dataPointer, const std::string& columnName, const std::string& unit, const std::string& comment); void writeOneRow(const TString& tableName); void InitAttr(const char* attrName, const char* dataType, void* var, const char* unit=NULL, const char* comment=NULL, ofits* outFile=NULL); // MWrite Bool_t IsFileOpen() const {return iTopFitsGroup != fTopFitsGroups.end();} Bool_t CheckAndWrite(); Bool_t GetContainer(MParList *pList); const char *GetFileName() const; Int_t PreProcess(MParList *pList); Int_t PostProcess(); void SetupHeaderKeys(MRawRunHeader &header); public: //Header keys related stuff template std::string GetFitsString(const _T& value) { std::ostringstream returnVal; std::string typeName = typeid(_T).name(); if (typeName == "i" || typeName == "j" || //int typeName == "s" || typeName == "t" || //short typeName == "l" || typeName == "m" || //long typeName == "x" || typeName == "y") //long long returnVal << value; if (typeName == "b") { if (value) returnVal << "T"; else returnVal << "F"; } if (typeName == "Ss" || typeName == "PKc" || (typeName.size() >= 4 && typeName[0] == 'A' && typeName[typeName.size()-1] == 'c' && typeName[typeName.size()-2] == '_')) { returnVal << value; std::string temp = returnVal.str(); returnVal.str(""); for (std::string::iterator c=temp.begin(); c bool SetHeaderKey(const std::string& key, const _T& value, const std::string& comment="") { //check if header was already written for (std::map::iterator it=fTableHeaderWritten.begin(); it!= fTableHeaderWritten.end(); it++) if (it->second == true) return false; //headers were not written yet. Add one key std::vector::iterator it = fHeaderKeys.begin(); //check if the value had been set beforel for (;it!=fHeaderKeys.end();it++) { if (it->key == key) { it->value = GetFitsString(value); it->comment = comment; break; } } //did we find the key ? if (it == fHeaderKeys.end()) {//no ? add it ! ofits::Key temp; temp.key = key; temp.value = GetFitsString(value); temp.comment = comment; fHeaderKeys.push_back(temp); } return true; } private: std::vector fHeaderKeys; std::string Trim(const std::string &str); // MTask Bool_t ReInit(MParList *pList); std::vector fVetoedColumns; std::map fBytesPerSamples; public: //Veto a type-mapping functions and variables Bool_t VetoColumn(const std::string& colName); Bool_t SetBytesPerSample(const std::string& colName, uint32_t numBytes); enum FILE_MODE { kMultiFiles, kSingleFile } ; MWriteFitsFile(const char *fname, FILE_MODE fileMode = kMultiFiles, const Option_t *opt="RECREATE", const char *name=NULL, const char *title=NULL); //Similar contructor to what MWriteRootFiles takes. //Some of the args are not used: comp as they does not make sense in FITS MWriteFitsFile(const Int_t comp, const char* rule, const Option_t* option="RECREATE", const char* fTitle="Untitled", const char* name=NULL, const char* title=NULL); ~MWriteFitsFile(); void AddContainer(const char *cName, const char *tName=NULL, Bool_t must=kTRUE, UInt_t max=0); void AddContainer(MParContainer *cont, const char *tName=NULL, Bool_t must=kTRUE, UInt_t max=0); void AddTree(const char *name, Bool_t force=kTRUE) { AddContainer(Form("MReport%s", name), name, force); AddContainer(Form("MTime%s", name), name, force); } ClassDef(MWriteFitsFile, 0) }; //Specializations for float and doubles (because of the precision handling, I could not deal with it in the main function template<> std::string MWriteFitsFile::GetFitsString(const double& value); template<> std::string MWriteFitsFile::GetFitsString(const float& value); #endif