source: trunk/Mars/mfileio/MFitsArray.cc @ 14792

Last change on this file since 14792 was 14792, checked in by lyard, 7 years ago
Added fits output for MC data
File size: 7.5 KB
Line 
1#include "MAGIC.h"
2#include "MLogManip.h"
3
4#include "MFitsArray.h"
5
6#include <TDataMember.h>
7#include <TClonesArray.h>
8#include <TClass.h>
9#include <TList.h>
10
11using namespace std;
12
13// ----------------------------------------------------------------------------
14//                                                                             
15// Opens the FITS table of this TClonesArray. This should be done after all   
16// columns are initialized. baseFileName is the name of the group, this       
17// children table belongs to. dataName is the name of the TClonesArray         
18// variable in the MParContainer - class.                                     
19//                                                                             
20Bool_t MArrayHelperBase::OpenFitsTable(const char * baseFileName, 
21                                         const char * dataName, 
22                                         const char * option, MLog * log )
23{
24   // get the baseFileName without extension                     
25   char fileNameNoExt[strlen(baseFileName) + 1];
26   strcpy(fileNameNoExt, baseFileName);
27   // remove the extension                                       
28   char * pos = strrchr(fileNameNoExt, '.');
29   if (pos) *pos = 0;
30
31   // add the dataName to the file name define the table name:   
32   // result will be something like:                             
33   // baseFileName_dataName.fits[dataName]                       
34   TString dol = fileNameNoExt;
35   TString fileName;
36   dol += "_";
37   dol += dataName;
38   dol += ".fits";
39   fileName = dol;
40//   dol += "[";
41//   dol += dataName;
42//   dol += "]";
43
44//   try {
45
46      if (strcmp(option, "RECREATE") == 0)
47         // remove the file
48         unlink(fileName.Data());
49
50      // create the file with the FITS table and all its columns   
51      //FIXME I must implement a constructor and set fFitsTable to NULL
52      //Otherwise I cannot safely destroy the object (in the destructor, also to be implemented)
53      fFitsTable = new ofits();
54      fFitsTable->open(dol.Data());
55
56//      }
57//   catch (exception & e)
58//      {
59//      *log << err << e.what() << endl;
60//      return kFALSE;
61 //     }
62   return kTRUE;
63}
64
65///////////////////////////////////////////////////////////////////////////////
66///////////////////////////////////////////////////////////////////////////////
67
68// ----------------------------------------------------------------------------
69//                                                                             
70// Determines the size of the buffer to store all data of the clonesArray -   
71// Class, which should be written to a FITS table. The buffer is allocated.   
72//                                                                             
73// status is set to kFALSE if some data cannot be stored in a FITS table,     
74// for example more than 1 dimensional arrays.                                 
75MClonesArrayHelper::MClonesArrayHelper(TClonesArray * clonesArray, MLog * log, 
76                                       Bool_t & status)
77  :  fClonesArray(clonesArray) 
78{
79   status = kTRUE;
80
81   // get size of buffer
82   fDataBufferSize = 0;
83   fStartOfData    = 0x7fffffff;
84
85   TList * dataMembers = fClonesArray->GetClass()->GetListOfDataMembers();
86   TIter next(dataMembers);
87   TDataMember * dataMember;
88
89   while ((dataMember = (TDataMember*)next()) != NULL)
90      {
91      if (!dataMember->IsPersistent())
92         continue;
93
94      if (dataMember->Property() & ( G__BIT_ISENUM | G__BIT_ISSTATIC))
95         continue;
96
97      if (strcmp(dataMember->GetTrueTypeName(), "TClass*") == 0)
98         continue;
99
100      // is it an array of more than 1 dimension?
101      if (dataMember->GetArrayDim() > 1)
102         {
103         *log << err << "Two and more dimensional arrays of member variables"
104                         " are not supported." << endl;
105         *log <<        "See variable " << dataMember->GetName() << 
106                         " in container " << fClonesArray->GetClass()->GetName() <<  endl;
107         status = kFALSE;
108         return;
109         }
110
111
112      // get the position, where the current variable ends.
113      Int_t endPos;
114      if (dataMember->GetArrayDim() == 1)
115         endPos = dataMember->GetOffset() + (dataMember->GetUnitSize() * 
116                                             dataMember->GetMaxIndex(0)  );
117      else
118         endPos = dataMember->GetOffset() + dataMember->GetUnitSize();
119
120      if (endPos > fDataBufferSize)
121         fDataBufferSize = endPos;
122
123      if (dataMember->GetOffset() < fStartOfData)
124         fStartOfData = dataMember->GetOffset();
125      }     
126
127   fDataBuffer = new Byte_t[fDataBufferSize];
128
129}
130
131// ----------------------------------------------------------------------------
132//                                                                             
133// the fClonesArray, the size of the data buffer and the fits Table are       
134// copied. A new buffer is allocated. Note: the fArraySize is not copied.     
135// Anyhow only its pointer is needed, which will change during this copy       
136//                                                                             
137MClonesArrayHelper::MClonesArrayHelper(const MClonesArrayHelper & clHelper)
138   : fClonesArray(clHelper.fClonesArray)
139{
140   fFitsTable       = clHelper.fFitsTable;
141   fDataBufferSize  = clHelper.fDataBufferSize;
142   fStartOfData     = clHelper.fStartOfData;
143   fDataBuffer      = new Byte_t[fDataBufferSize];
144}
145
146
147
148// ----------------------------------------------------------------------------
149//                                                                             
150// Writes all currently stored classes in the fClonesArray, i. e. writes 0 to 
151// may rows to the FITS table.                                                 
152// fArraySize is updated with the number of new row, written to the FITS       
153// table. Therefore the parent FITS table must be updated after calling this   
154// method.                                                                     
155//                                                                             
156void MClonesArrayHelper::Write()
157{
158   // get number of classes in fClonesArray.                                 
159   fArraySize = fClonesArray->GetLast() + 1;
160
161   for (int idx = 0; idx < fArraySize; idx++)
162      {
163      // copy the data of one class to fDataBuffer                           
164      memcpy(fDataBuffer, (*fClonesArray)[idx], fDataBufferSize);
165
166      // now the data can be written from the fDataBuffer to the FITS table 
167      fFitsTable->WriteRow(fDataBuffer, fDataBufferSize);
168      }
169}
170
171// ----------------------------------------------------------------------------
172//                                                                             
173// resize the clone array (fClonesArray) and reads fArraySize data sets from   
174// the FITS file into the fClonesArray.                                       
175// The number of data sets must be determined before calling this function,   
176// i.e. the parent FITS table must be read before calling this method.         
177Int_t MClonesArrayHelper::Read()
178{
179 /*  fClonesArray->ExpandCreate(fArraySize);
180
181   for (int idx = 0; idx < fArraySize; idx++)
182      {
183      // read the data in the buffer
184      if (!fFitsTable.Read())
185         {
186         gLog << "Expecting more entries in " << fFitsTable.GetFileName() << endl;
187         return kERROR;
188         }
189      // copy the data of one class from fDataBuffer into the class
190      memcpy( (Byte_t*)((*fClonesArray)[idx]) + fStartOfData,
191              fDataBuffer + fStartOfData, fDataBufferSize - fStartOfData);
192      }
193*/
194   return kTRUE;
195}
Note: See TracBrowser for help on using the repository browser.