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

Last change on this file since 19255 was 19255, checked in by tbretz, 6 months ago
Some precompiler macros turned into enums in root 6.
File size: 7.6 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 ROOT_VERSION_CODE < ROOT_VERSION(6,00,00)
95      if (dataMember->Property() & ( G__BIT_ISENUM | G__BIT_ISSTATIC))
96         continue;
97#else
98      if (dataMember->Property() & ( EProperty::kIsEnum | EProperty::kIsStatic))
99         continue;
100#endif
101      if (strcmp(dataMember->GetTrueTypeName(), "TClass*") == 0)
102         continue;
103
104      // is it an array of more than 1 dimension?
105      if (dataMember->GetArrayDim() > 1)
106         {
107         *log << err << "Two and more dimensional arrays of member variables"
108                         " are not supported." << endl;
109         *log <<        "See variable " << dataMember->GetName() << 
110                         " in container " << fClonesArray->GetClass()->GetName() <<  endl;
111         status = kFALSE;
112         return;
113         }
114
115
116      // get the position, where the current variable ends.
117      Int_t endPos;
118      if (dataMember->GetArrayDim() == 1)
119         endPos = dataMember->GetOffset() + (dataMember->GetUnitSize() * 
120                                             dataMember->GetMaxIndex(0)  );
121      else
122         endPos = dataMember->GetOffset() + dataMember->GetUnitSize();
123
124      if (endPos > fDataBufferSize)
125         fDataBufferSize = endPos;
126
127      if (dataMember->GetOffset() < fStartOfData)
128         fStartOfData = dataMember->GetOffset();
129      }     
130
131   fDataBuffer = new Byte_t[fDataBufferSize];
132
133}
134
135// ----------------------------------------------------------------------------
136//                                                                             
137// the fClonesArray, the size of the data buffer and the fits Table are       
138// copied. A new buffer is allocated. Note: the fArraySize is not copied.     
139// Anyhow only its pointer is needed, which will change during this copy       
140//                                                                             
141MClonesArrayHelper::MClonesArrayHelper(const MClonesArrayHelper & clHelper)
142   : fClonesArray(clHelper.fClonesArray)
143{
144   fFitsTable       = clHelper.fFitsTable;
145   fDataBufferSize  = clHelper.fDataBufferSize;
146   fStartOfData     = clHelper.fStartOfData;
147   fDataBuffer      = new Byte_t[fDataBufferSize];
148}
149
150
151
152// ----------------------------------------------------------------------------
153//                                                                             
154// Writes all currently stored classes in the fClonesArray, i. e. writes 0 to 
155// may rows to the FITS table.                                                 
156// fArraySize is updated with the number of new row, written to the FITS       
157// table. Therefore the parent FITS table must be updated after calling this   
158// method.                                                                     
159//                                                                             
160void MClonesArrayHelper::Write()
161{
162   // get number of classes in fClonesArray.                                 
163   fArraySize = fClonesArray->GetLast() + 1;
164
165   for (UInt_t idx = 0; idx < fArraySize; idx++)
166      {
167      // copy the data of one class to fDataBuffer                           
168      memcpy(fDataBuffer, (*fClonesArray)[idx], fDataBufferSize);
169
170      // now the data can be written from the fDataBuffer to the FITS table 
171      fFitsTable->WriteRow(fDataBuffer, fDataBufferSize);
172      }
173}
174
175// ----------------------------------------------------------------------------
176//                                                                             
177// resize the clone array (fClonesArray) and reads fArraySize data sets from   
178// the FITS file into the fClonesArray.                                       
179// The number of data sets must be determined before calling this function,   
180// i.e. the parent FITS table must be read before calling this method.         
181Int_t MClonesArrayHelper::Read()
182{
183 /*  fClonesArray->ExpandCreate(fArraySize);
184
185   for (int idx = 0; idx < fArraySize; idx++)
186      {
187      // read the data in the buffer
188      if (!fFitsTable.Read())
189         {
190         gLog << "Expecting more entries in " << fFitsTable.GetFileName() << endl;
191         return kERROR;
192         }
193      // copy the data of one class from fDataBuffer into the class
194      memcpy( (Byte_t*)((*fClonesArray)[idx]) + fStartOfData,
195              fDataBuffer + fStartOfData, fDataBufferSize - fStartOfData);
196      }
197*/
198   return kTRUE;
199}
Note: See TracBrowser for help on using the repository browser.