| 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 |
|
|---|
| 11 | using 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 | //
|
|---|
| 20 | Bool_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 zofits();
|
|---|
| 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.
|
|---|
| 75 | MClonesArrayHelper::MClonesArrayHelper(const 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 | //
|
|---|
| 141 | MClonesArrayHelper::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 | //
|
|---|
| 160 | void 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.
|
|---|
| 181 | Int_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 | }
|
|---|