source: branches/Mars_MC/mfileio/MWriteFitsFile.h@ 17086

Last change on this file since 17086 was 17045, checked in by ftemme, 11 years ago
Moved the setting of the header keys for the fitsoutput of ceres files from MJSimulation.cc to MWriteFitsFile::ReInit, cause several used header keys are only then known and can't be set in MJSimulation::Process()
File size: 9.2 KB
Line 
1#ifndef MARS_MWreitFitsFile
2#define MARS_MWreitFitsFile
3
4#include <list>
5#include <vector>
6#include <map>
7
8#include <TClass.h>
9
10#ifndef MARS_MWriteFile
11#include "MWriteFile.h"
12#endif
13
14#ifndef MARS_MTopFitsGroup
15#include "MTopFitsGroup.h"
16#endif
17
18#ifndef MARS_MFitsArray
19#include "MFitsArray.h"
20#endif
21
22#ifndef MARS_MRawRunHeader
23#include "MRawRunHeader.h"
24#endif
25
26class MRawRunHeader;
27
28///////////////////////////////////////////////////////////////////////////////
29// Information of one MParContainer, which data should be written into all or
30// just a few columns of one FITS table
31class MFitsSubTable
32{
33 // the container, which data should be written to the FITS sub-table.
34 MParContainer *fContainer;
35
36 // used only if the Container is defined by its name.
37 // if kTRUE must exist in the MParList of the program
38 // if kFALSE the container is ignored. if it is not in the
39 // MParList of the program
40 Bool_t fMust;
41
42public:
43 MFitsSubTable( Bool_t must)
44 : fContainer(NULL), fMust(must)
45 {}
46
47 MFitsSubTable(MParContainer * container, Bool_t must)
48 : fContainer(container), fMust(must)
49 {}
50
51
52 MFitsSubTable(const MFitsSubTable & subTable)
53 : fContainer(subTable.fContainer), fMust(subTable.fMust)
54 {}
55
56 Bool_t MustHave() {return fMust;}
57 MParContainer * GetContainer() {return fContainer;}
58 void SetContainer(MParContainer * cont)
59 {fContainer = cont;}
60
61};
62
63
64
65///////////////////////////////////////////////////////////////////////////////
66// A class to write data of MParContainer into FITS files.
67class MWriteFitsFile : public MWriteFile
68{
69private:
70 // all (global) currently open top FITS groups.
71 // Note: several instances of MWriteFitsFile can write to the same
72 // top level FITS group (a top level FITS group corresponds to
73 // one ROOT file)
74 static std::map<MUniqueFileId, MTopFitsGroup> fTopFitsGroups;
75
76 // pointer to the top level FITS group of this instance
77 std::map<MUniqueFileId, MTopFitsGroup>::iterator iTopFitsGroup;
78
79 // the key (TString) of following maps is the FITS table name, which
80 // corresponds to one TTree
81
82 // all main FITS table. Children tables to store data of
83 // TClonesArray are not in this map.
84 //ETIENNE ofits objects cannot be copied. So store pointers instead
85 std::map<TString, ofits*> fFitsTables;
86
87 // all information needed to write data of TClonesArray to their
88 // own FITS table. Note: one parent FTIS table may have several
89 // children tables, each for one TClonesArray.
90 std::map<TString, std::list<MArrayHelperBase *> > fClHelper;
91
92 // all information about the MParContainer, which data are stored
93 // in the same FITS table. The key of map<TString, MFitsSubTable>
94 // is the class name of the MParContainer
95 std::map<TString, std::map<TString, MFitsSubTable> > fSubTables;
96
97 std::map<TString, std::vector<void*> > fDataPointers;
98 std::map<TString, std::vector<char> > fTypeChars;
99 std::map<TString, std::vector<uint32_t> > fColSizes;
100 std::map<TString, std::vector<uint32_t> > fColWidth;
101 std::map<TString, bool> fTableObjectCreated;
102 std::map<TString, bool> fTableHeaderWritten;
103
104 void DeleteArrayHelper();
105
106 // rule to construct an output file-name from the input-filename
107 TString fRule;
108
109 TString fOpenOption; // RECREATE or NEW
110 TString fGroupName; // name of top level group
111 TString fTitle; // title of top level group
112
113 void OpenTopLevelGroup(const char * fname);
114 void CloseTopLevelGroup();
115
116 Bool_t InitColumns(const TString & tableName,
117 const TString & parentVarName,
118 ofits* fitsTable,
119 void * baseAdr,
120 TClass * classDef);
121 void InitSingleColumn(const TString& tableName,
122 uint32_t count,
123 const std::string& typeName,
124 void* dataPointer,
125 const std::string& columnName,
126 const std::string& unit,
127 const std::string& comment);
128 void writeOneRow(const TString& tableName);
129 void InitAttr(const char* attrName,
130 const char* dataType,
131 void* var,
132 const char* unit=NULL,
133 const char* comment=NULL,
134 ofits* outFile=NULL);
135
136 // MWrite
137 Bool_t IsFileOpen() const
138 {return iTopFitsGroup != fTopFitsGroups.end();}
139 Bool_t CheckAndWrite();
140 Bool_t GetContainer(MParList *pList);
141 const char *GetFileName() const;
142
143 Int_t PreProcess(MParList *pList);
144 Int_t PostProcess();
145
146 void SetupHeaderKeys(MRawRunHeader &header);
147
148 //Header keys related stuff
149 template<typename _T>
150 std::string GetFitsString(const _T& value)
151 {
152 std::ostringstream returnVal;
153 std::string typeName = typeid(_T).name();
154 if (typeName == "i" || typeName == "j" || //int
155 typeName == "s" || typeName == "t" || //short
156 typeName == "l" || typeName == "m" || //long
157 typeName == "x" || typeName == "y") //long long
158 returnVal << value;
159
160 if (typeName == "b")
161 {
162 if (value) returnVal << "T"; else returnVal << "F";
163 }
164 if (typeName == "Ss" || typeName == "PKc" ||
165 (typeName.size() >= 4 && typeName[0] == 'A' && typeName[typeName.size()-1] == 'c' && typeName[typeName.size()-2] == '_'))
166 {
167 returnVal << value;
168 std::string temp = returnVal.str();
169 returnVal.str("");
170 for (std::string::iterator c=temp.begin(); c<temp.end(); c++)
171 if (*c=='\'')
172 temp.insert(c++, '\'');
173 returnVal << "'" << temp << "'";
174 }
175 if (returnVal.str() == "")
176 *fLog << warn << "WARNING: could not construct fits string from \"" << value << "\" typename: " << typeName << endl;
177 return returnVal.str();
178 }
179
180public:
181 template<typename _T>
182 bool SetHeaderKey(const std::string& key,
183 const _T& value,
184 const std::string& comment="")
185 {
186 //check if header was already written
187 for (std::map<TString, bool>::iterator it=fTableHeaderWritten.begin(); it!= fTableHeaderWritten.end(); it++)
188 if (it->second == true)
189 return false;
190 //headers were not written yet. Add one key
191 std::vector<ofits::Key>::iterator it = fHeaderKeys.begin();
192 //check if the value had been set beforel
193 for (;it!=fHeaderKeys.end();it++)
194 {
195 if (it->key == key)
196 {
197 it->value = GetFitsString(value);
198 it->comment = comment;
199 break;
200 }
201 }
202 //did we find the key ?
203 if (it == fHeaderKeys.end())
204 {//no ? add it !
205 ofits::Key temp;
206 temp.key = key;
207 temp.value = GetFitsString(value);
208 temp.comment = comment;
209 fHeaderKeys.push_back(temp);
210 }
211 return true;
212 }
213private:
214 std::vector<ofits::Key> fHeaderKeys;
215
216 std::string Trim(const std::string &str);
217
218 // MTask
219 Bool_t ReInit(MParList *pList);
220
221 std::vector<std::string> fVetoedColumns;
222 std::map<std::string, uint32_t> fBytesPerSamples;
223
224
225public:
226
227 //Veto a type-mapping functions and variables
228 Bool_t VetoColumn(const std::string& colName);
229 Bool_t SetBytesPerSample(const std::string& colName, uint32_t numBytes);
230
231 enum FILE_MODE {
232 kMultiFiles,
233 kSingleFile
234 } ;
235
236 MWriteFitsFile(const char *fname,
237 FILE_MODE fileMode = kMultiFiles,
238 const Option_t *opt="RECREATE",
239 const char *name=NULL,
240 const char *title=NULL);
241 //Similar contructor to what MWriteRootFiles takes.
242 //Some of the args are not used: comp as they does not make sense in FITS
243 MWriteFitsFile(const Int_t comp,
244 const char* rule,
245 const Option_t* option="RECREATE",
246 const char* fTitle="Untitled",
247 const char* name=NULL,
248 const char* title=NULL);
249
250 ~MWriteFitsFile();
251
252
253 void AddContainer(const char *cName, const char *tName=NULL, Bool_t must=kTRUE);
254 void AddContainer(MParContainer *cont, const char *tName=NULL, Bool_t must=kTRUE);
255
256
257 void AddTree(const char *name, Bool_t force=kTRUE)
258 {
259 AddContainer(Form("MReport%s", name), name, force);
260 AddContainer(Form("MTime%s", name), name, force);
261 }
262
263 ClassDef(MWriteFitsFile, 0)
264};
265//Specializations for float and doubles (because of the precision handling, I could not deal with it in the main function
266template<>
267std::string MWriteFitsFile::GetFitsString(const double& value);
268template<>
269std::string MWriteFitsFile::GetFitsString(const float& value);
270#endif
Note: See TracBrowser for help on using the repository browser.