// ---------------------------------------------------------------------- // // HepNtuple-capture.cc - implementation of generic HepNtuple: routines // associated with capture of data and storage of rows. // // HepNtuple a generic Ntuple. // Its final implementation is defined by a manager class/ // histogram subclass. HepNtuple provides methods for filling an Ntuple // histogram and retreiving information from and about it. // // The following methods are in this file: // column 2 7/7 // newColumn 3 7/7 // setExistingColumn 4 7/7 // capture (name, value) 5 7/11 // capture () 6 7/16 // captureBlock (name) 7 7/16 // capture (name, value[]) - // capture (name,value[],indexval) - // captureColumn 8 7/16 // storeCapturedData // captureThenStore // clearData - // // And the following private supporting methods: // createColumn // captureCheck ( &c, type ); 105 7/14 // captureBlock (Block*) 106 7/16 // prepareBlockForStoring // ??? // // And the following holders for virtual methods // storeWholeRow // storeSingleBlock (bk); // ??? // // Related files implementing the HepNtuple class are : // HepTUple.cc // HepNtuple-define.cc, ??? // // // // // HepNtuple objects are not directly instantiated. Instead, the manager // creates the object using its own implementation of the histogram. // // Typical usage: // // HepFileManager* m = new [define the manager]; // : // : // HepNtuple& t(m->newNtuple("Title")); // float x, y, z, w; // columnAt ("X", &x); // columnAt ("Y", &y); // columnAt ("Z", &z); // : // [gather data] // : // t->capture(); // t->storeCapturedData(); // : // [gather data into x,y,z AND compute w] // : // t->column("W2", w*w); // A new column, supplying the value to be captured // t->captureThenStore(); // : // [when Ntuple filling is finished ...] // : // delete(t); // // Note that the constructor can take an ID number which is used by // some implementations of HepNtuple. If omitted, the ID number is // generated automatically (which is recommended). The ID number is // available through the id() method. // // Some of the methods in HepNtuple do nothing more than generate an // error when called. It is up to the manager-specific derived class to // implement the appropriate ones. // // // A note about ZMx exceptions: // Since we are in the HepNtuple class, when we instantiate something like // ZMxProblem in a call to ZMthow, we will get an object of type // HepNtuple::ZMxProblem. In this case, the name of the package is also // HepNtuple; but the class diagram for these exceptions is like: // // ZMexception // ZMxLinearAlgebra // ZMxPhysicVectors // ZMxHeptuple // HepNtuple::ZMxGeneral // HepNtuple::ZMxCapture // HepNtuple::ZMxColumn // HepNtuple::ZMxNewColumn // ... // HepHist1D::ZMxGeneral // HepHist1D::ZMxBadRange (or whatever) // // So there is no ambiguity even when a class name matches its package name. // // // History: // 02-Jul-1997 MF Initial draft of these methods // 18-Jul-1997 MF Modification to reflect correct ColumnT template // mechanism. Some methods like captureCheck go into // the ColumnT class. // 06-Jan-1997 PC Change the store algorithm instead of storing // only captured columns always store ALL columns. // For columns that have not been captured we store // the default value. // Add a clearData() at the end of the store // HepNtuple::capture do not bark when all columns // have already been individually captured. // ---------------------------------------------------------------------- // 1 // TODO: ALL THE BELOW OUGHT TO BE CODE-GUARDED HERE #include "ZMutility/iostream" #include USING( std::string ) #include "HepTuple/HepFileManager.h" #include "HepTuple/HepNtuple.h" #include "HepTuple/Block.h" #include "HepTuple/Column.h" #include "HepTuple/ColumnT.h" #include "HepTuple/TupleNameTag.h" #include "ZMtools/pretendToUse.h" ZM_BEGIN_NAMESPACE( zmht ) /* namespace zmht { */ // ---------------------------------------------------------------------- // Public Methods // TO DO: // capture // (value[]) // (value[], indexval) // storeCapturedData // captureThenStore // clearData // (blockname) // () // 2 /****************/ /* */ /* createColumn */ /* */ /****************/ // // Just create a column, in a known block with a known C type // // If the block name is not specified in the tagName, the unspecified() // block will used. If the block does not yet exist, it will be created. template ColumnT* addNewColumnF ( const string& ColumnTagName, T defaultValue, HepNtuple *hep ) { if (hep->isLockedNewColumns()) { ZMthrow ( ZMxHepLockedItem (string("Attempt to create a new column ") +ColumnTagName+ string("in a locked HepNtuple: ") +hep->title())); return NULL; } if ( ! hep->isNameAvailable(ColumnTagName) ) { ZMthrow ( ZMxHepCantMakeColumn (string("Duplicate column name for new column: ") +ColumnTagName) ); return NULL; } TupleNameTag tag; hep->parseNameTag(tag, ColumnTagName); if (! tag.isValid() ) { ZMthrow ( ZMxHepCantMakeColumn (string("Improper form for column name tag: ") +ColumnTagName )); return NULL; } // Determine (and create, if necessary) the block: Block* b; if ( tag.block().length() != 0 ) { b = hep->findBlock (tag.block()); if ( !b ) { b = new Block(hep, tag.block(), hep->isCaseSensitive()); hep->addBlock (b); if ( !b ) { return NULL; } } } else { b = hep->unspecifiedBlock(); if ( !b ) { return NULL; } } ColumnT * c = new ColumnT ( b, tag.column() ); if ( !c ) { return NULL; } c->setDefaultValue (defaultValue); c->setToDefault(); hep->addColumn (b,c); hep->setCurrentColumn(c); return c; } #ifdef NEVER // The following is necessary because of a what seems to be a bug in gcc // It was unable to know that it should instantiate a template function // used inside a template function (addNewColumnF in newColumnF). #define addNewColumnUser_MACRO(TYPE) \ static void addNewColumnFuser ( \ const string& lbl, \ TYPE defautValue, \ HepNtuple *hep ) { \ addNewColumnF(lbl,defautValue,hep); \ } addNewColumnUser_MACRO ( Int1 ) addNewColumnUser_MACRO ( Int2 ) addNewColumnUser_MACRO ( Int4 ) #ifdef Int8 addNewColumnUser_MACRO ( Int8 ) #endif addNewColumnUser_MACRO ( Float4 ) addNewColumnUser_MACRO ( Float8 ) #ifdef Float16 addNewColumnUser_MACRO ( Float16 ) #endif addNewColumnUser_MACRO ( bool) addNewColumnUser_MACRO ( void *) #endif // ******************************************************************* // // // // getOrCreateColumnT // // // // Static function that return a columnT corresponding to nametag and // // set it to be the current column in hep // // // // It will throw an exception if the nametag is wrong and return NULL // // if the column does not exist and/or is of the wrong type // // // // ******************************************************************* // template static ColumnT* getOrCreateColumnT(const string& nametag,T defVal,HepNtuple *tuple) { // Declare a nametag as specified. Check if the syntax is valid, // throw an exception and return false if it isn't. TupleNameTag tag; tuple->parseNameTag( tag, nametag); if ( !tag.isValid() ) { ZMthrow ( ZMxHepCantMakeColumn (string("Improper form for column name tag: ") +string(nametag ) ) ); return NULL; } // Declare a pointer to the column with the given nametag. Column * c = tuple->findColumn(nametag); // If findColumn returns false, there isn't one already and we try // to create one. If that fails, return false give up. if ( !c ) { c = addNewColumnF (nametag, defVal, tuple); if (!c) { return NULL; } } // Make sure we have a proper type match and bail out if not. if (!c->checkType(T())) { ZMthrow(ZMxHepTypeMismatch (string("wrong type for column:") +string(nametag))); return NULL; } ColumnT * ct = (ColumnT *) c; // Tell the manager that this is the "current column" ... tuple->setCurrentColumn(c); return ct; } #ifdef NEVER // The following is necessary because of a what seems to be a bug in gcc // It was unable to know that it should instantiate a template function // used inside a template function (addNewColumnF in newColumnF). #define getOrCreateColumnT_User_MACRO(TYPE) \ static void getOrCreateColumnT_User (TYPE f) { \ TYPE a = 0; \ getOrCreateColumnT("Dummy Name",a,(HepNtuple*)NULL); \ } getOrCreateColumnT_User_MACRO ( Int1 ) getOrCreateColumnT_User_MACRO ( Int2 ) getOrCreateColumnT_User_MACRO ( Int4 ) #ifdef Int8 getOrCreateColumnT_User_MACRO ( Int8 ) #endif getOrCreateColumnT_User_MACRO ( Float4 ) getOrCreateColumnT_User_MACRO ( Float8 ) #ifdef Float16 getOrCreateColumnT_User_MACRO ( Float16 ) #endif getOrCreateColumnT_User_MACRO ( bool) getOrCreateColumnT_User_MACRO ( void *) #endif // *************************** // // // // newColumn // // // // *************************** // // Create a column and directly provide its value for this row. // // To Do: What about a tag name like: BlockA::ColB(2,3) ? // Where/when is it rejected ? template static Column* newColumnF( const string& lbl, T value, T defval, HepNtuple* hep) { ColumnT *c = addNewColumnF(lbl,defval,hep); c->captureValue (value); hep->setCurrentColumn(c); return c; } /* newColumn */ #define newColumn_MACRO(TYPE) \ bool \ HepNtuple::newColumn( \ const string& lbl, \ const TYPE value, \ const TYPE defval ) \ { \ return ( newColumnF (lbl, value, defval,this) != NULL ); \ } bool HepNtuple::newColumn( const string& lbl, const void* value, const void* defval ) { return ( newColumnF (lbl, const_cast(value), const_cast(defval),this) != NULL ); } newColumn_MACRO ( Int1 ) newColumn_MACRO ( Int2 ) newColumn_MACRO ( Int4 ) #ifdef Int8 newColumn_MACRO ( Int8 ) #endif newColumn_MACRO ( Float4 ) newColumn_MACRO ( Float8 ) #ifdef Float16 newColumn_MACRO ( Float16 ) #endif newColumn_MACRO ( bool) // 3 // *************************** // // // // Column // // // // *************************** // // Directly provide a value for a column, or create the column // and directly provide its value for this row. template static bool columnF( const string& nametag, T value, T defval, HepNtuple* tuple) { // Get (eventually after creating it) the column corresponding to // nametag and also set this column to be the current column. ColumnT* ct = getOrCreateColumnT(nametag,defval,tuple); if (ct == NULL) { // something bad happened and the exception has been ignored. return false; } return ct->captureValue(value); } /* columnT */ #define column_MACRO(TYPE) \ bool \ HepNtuple::column( \ const string& nametag, \ TYPE value, \ TYPE defval ) \ { \ return columnF (nametag, value, defval, this); \ } column_MACRO ( Int1 ) column_MACRO ( Int2 ) column_MACRO ( Int4 ) #ifdef Int8 column_MACRO ( Int8 ) #endif column_MACRO ( Float4 ) column_MACRO ( Float8 ) #ifdef Float16 column_MACRO ( Float16 ) #endif column_MACRO ( bool ) column_MACRO ( void * ) // *************************** // // // // ColumnAt // // // // *************************** // // Provide a pointer to a value for a column, or create the column // and provide a pointer to its value for this row. template static bool columnAtF( const string& nametag, T* value, T defval, HepNtuple* tuple) { // Get (eventually a new one) the column corresponding to // nametag and also set this column to be the current column. ColumnT* ct = getOrCreateColumnT(nametag,defval,tuple); if (ct == NULL) { // something bad happened and the exception has been ignored. return false; } return ct->setDesignatedVariable(value); } /* columnT */ #define columnAt_MACRO(TYPE) \ HepNtuple& \ HepNtuple::columnAt( \ const string& nametag, \ TYPE* value, \ TYPE defval ) \ { \ if (isValid()) { \ isValid(columnAtF (nametag, value, defval, this) ); \ } \ return *this; \ } columnAt_MACRO ( Int1 ) columnAt_MACRO ( Int2 ) columnAt_MACRO ( Int4 ) #ifdef Int8 columnAt_MACRO ( Int8 ) #endif columnAt_MACRO ( Float4 ) columnAt_MACRO ( Float8 ) #ifdef Float16 columnAt_MACRO ( Float16 ) #endif columnAt_MACRO ( bool ) columnAt_MACRO ( void * ) // *************************** // // // // ColumnVia // // for member functions // // // // *************************** // // Given a (user specified) function that produces a value for the column // specified by nametag, create the column if necessary, and insert the // value for this row. // N. B. The user specified function must be a member function of some // class but may not take any arguments. template static bool columnViaM( const string& nametag, ZMuseMethod* function, T defval, HepNtuple* tuple) { // Get (eventually a new one) the column corresponding to // nametag and also set this column to be the current column. ColumnT* ct = getOrCreateColumnT(nametag,defval,tuple); if (ct == NULL) { // something bad happened and the exception has been ignored. return false; } return ct->setDesignatedMethod(function); // TODO - don't forget that captureValue must check appropriate // dimensions and that the column was not already captured. } /* columnT */ #define columnVia_MACRO(TYPE) \ HepNtuple& \ HepNtuple::columnVia( \ const string& nametag, \ ZMuseMethod* function, \ TYPE defval ) \ { \ if (isValid()) { \ isValid(columnViaM (nametag, function, defval, this) ); \ } \ return *this; \ } columnVia_MACRO ( Int1 ) columnVia_MACRO ( Int2 ) columnVia_MACRO ( Int4 ) #ifdef Int8 columnVia_MACRO ( Int8 ) #endif columnVia_MACRO ( Float4 ) columnVia_MACRO ( Float8 ) #ifdef Float16 columnVia_MACRO ( Float16 ) #endif columnVia_MACRO ( bool ) columnVia_MACRO ( void * ) // *************************** // // // // ColumnVia // // for user functions // // // // *************************** // // Given a (user supplied) function that produces a value for the column // specified by nametag, create the column if necessary, and insert the // value for this row. // N. B. The user specified function may not be a member function of some // class and may not take any arguments. template static bool columnViaF( const string& nametag, T (*function)(), T defval, HepNtuple* tuple) { // Get (eventually a new one) the column corresponding to // nametag and also set this column to be the current column. ColumnT* ct = getOrCreateColumnT(nametag,defval,tuple); if (ct == NULL) { // something bad happened and the exception has been ignored. return false; } return ct->setDesignatedFunction(function); } /* columnT */ #define columnVia_MACRO2(TYPE) \ HepNtuple& \ HepNtuple::columnVia( \ const string& nametag, \ TYPE (*function)(), \ TYPE defval ) \ { \ if ( isValid() ) { \ isValid(columnViaF (nametag, function, defval, this) ); \ } \ return *this; \ } columnVia_MACRO2 ( Int1 ) columnVia_MACRO2 ( Int2 ) columnVia_MACRO2 ( Int4 ) #ifdef Int8 columnVia_MACRO2 ( Int8 ) #endif columnVia_MACRO2 ( Float4 ) columnVia_MACRO2 ( Float8 ) #ifdef Float16 columnVia_MACRO2 ( Float16 ) #endif columnVia_MACRO2 ( bool ) columnVia_MACRO2 ( void * ) // *************************** // // // // ColumnDirect // // // // *************************** // // Create or set the given column to take its value only from direct template static bool columnDirectF( const string& nametag, T defval, HepNtuple* tuple) { // Get (eventually a new one) the column corresponding to // nametag and also set this column to be the current column. ColumnT* ct = getOrCreateColumnT(nametag,defval,tuple); if (ct == NULL) { // something bad happened and the exception has been ignored. return false; } // The following disable any designated variable/function/method return ct->setDesignatedVariable(NULL); } /* columnDirectF */ #define columnDirect_MACRO(TYPE) \ HepNtuple& \ HepNtuple::columnDirect( \ const string& nametag, \ TYPE defval ) \ { \ if (isValid()) { \ isValid(columnDirectF (nametag, defval, this) ); \ }; \ return *this; \ } columnDirect_MACRO ( Int1 ) columnDirect_MACRO ( Int2 ) columnDirect_MACRO ( Int4 ) #ifdef Int8 columnDirect_MACRO ( Int8 ) #endif columnDirect_MACRO ( Float4 ) columnDirect_MACRO ( Float8 ) #ifdef Float16 columnDirect_MACRO ( Float16 ) #endif columnDirect_MACRO ( bool ) columnDirect_MACRO ( void * ) // *************************** // // // // columnArray // // // // *************************** // // Create 1 Dimension column array template static bool columnArrayF( const string& nametag, int ncolumns, T defval, HepNtuple* tuple) { // Get (eventually a new one) the column corresponding to // nametag and also set this column to be the current column. ColumnT* ct = getOrCreateColumnT(nametag,defval,tuple); if (ct == NULL) { // something bad happened and the exception has been ignored. return false; } return ct->setDimension(ncolumns); } /* columnArrayF */ #define columnArray_MACRO(TYPE) \ HepNtuple& \ HepNtuple::columnArray( \ const string& nametag, \ int ncolumns, \ TYPE defval ) \ { \ if ( isValid() ) { \ isValid(columnArrayF (nametag, ncolumns, defval, this) ); \ }; \ return *this; \ } columnArray_MACRO ( Int1 ) columnArray_MACRO ( Int2 ) columnArray_MACRO ( Int4 ) #ifdef Int8 columnArray_MACRO ( Int8 ) #endif columnArray_MACRO ( Float4 ) columnArray_MACRO ( Float8 ) #ifdef Float16 columnArray_MACRO ( Float16 ) #endif columnArray_MACRO ( bool ) columnArray_MACRO ( void * ) // 5 // *************************** // // // // capture (name, value) // // // // *************************** // // Direct capture of the supplied value into the named column. This // will work whether or not the column has a designated variable. Return // false if the column is not found. It is possible that other exceptions // might be thrown, for example, if the name is not a valid one. #define capture_MACRO(TYPE) \ bool \ HepNtuple::capture( \ const string& nametag, \ const TYPE value ) \ { \ if ( isValid() ) { \ return captureF (nametag, value, this); \ }; \ return false; \ } template static bool captureF (const string& nametag, T value, HepNtuple* hep) { Column * c = hep->findColumn(nametag); if ( !c ) { ZMthrow ( ZMxHepUnknownColumn (string("Attempt to capture data for undefined column: ") +string(nametag) )); return false; } if (!c->checkType(value)) { ZMthrow(ZMxHepTypeMismatch (string("Capture with wrong type for column: ") +string(nametag))); return false; } ColumnT * ct = (ColumnT *) c; return ct->captureValue(value); } /* capture (name, value) */ bool HepNtuple::capture( const string& nametag, const void * value ) { if ( isValid() ) { return captureF (nametag, const_cast(value),this); }; return false; } capture_MACRO ( Int1 ) capture_MACRO ( Int2 ) capture_MACRO ( Int4 ) #ifdef Int8 capture_MACRO ( Int8 ) #endif capture_MACRO ( Float4 ) capture_MACRO ( Float8 ) #ifdef Float16 capture_MACRO ( Float16 ) #endif capture_MACRO ( bool ) // *************************** // // // // capture (name, value[]) // // // // *************************** // // Direct capture of the supplied value into the named column. This // will work whether or not the column has a designated variable. Return // false if the column is not found. It is possible that other exceptions // might be thrown, for example, if the name is not a valid one. #define captureArr_MACRO(TYPE) \ bool \ HepNtuple::capture( \ const string& nametag, \ const TYPE value[] ) \ { \ if ( isValid() ) { \ return captureArrF (nametag, value,0,this); \ }; \ return false; \ } \ bool \ HepNtuple::capture( \ const string& nametag, \ const TYPE value[], \ int indexVal) \ { \ if ( isValid() ) { \ return captureArrF (nametag, value,indexVal,this); \ }; \ return false; \ } template static bool captureArrF (const string& nametag, const T value[], int indexVal, HepNtuple* hep) { Column * c = hep->findColumn(nametag); if ( !c ) { ZMthrow ( ZMxHepUnknownColumn (string("Attempt to capture data for undefined column: ") +string(nametag) )); return false; } if (!c->checkType(T())) { ZMthrow(ZMxHepTypeMismatch (string("Capture with wrong type for column:") +string(nametag))); return false; } ColumnAttribs attribs = c->attributes(); if( (attribs.index).length() != 0 ) { string indexColName = attribs.index; Column * ci = c->block()->findColumn(indexColName); // JMM 11 Sep. 2002 if ( !ci ) { ZMthrow ( ZMxHepUnknownColumn (string("Attempt to index data with undefined column: ") +string(indexColName) )); return false; } ColumnAttribs attribsi = ci->attributes(); if( indexVal > attribsi.indexHi ) { ZMthrow(ZMxHepOutOfRangeValue (string("Attempted capture with invalid index value for column: ") +string(nametag))); return false; } } // ------------------------------------------- ColumnT * ct = (ColumnT *) c; return ct->captureValues(value,indexVal); } /* capture (name, value) */ captureArr_MACRO ( Int1 ) captureArr_MACRO ( Int2 ) captureArr_MACRO ( Int4 ) #ifdef Int8 captureArr_MACRO ( Int8 ) #endif captureArr_MACRO ( Float4 ) captureArr_MACRO ( Float8 ) #ifdef Float16 captureArr_MACRO ( Float16 ) #endif captureArr_MACRO ( bool ) // 6 // *************************** // // // // capture () // // // // *************************** // // Capture by designated variables (or designated accessors) all variables in // the HepNtuple which have not already been captured. // Does NOT fail if any or all columns have already been captured! bool HepNtuple::capture ( ) { if ( ! isValid() ) { return false; } Block* bk; /* blocksMap::iterator iterateBlock; for ( iterateBlock = blocks.begin(); iterateBlock != blocks.end(); iterateBlock++ ) { bk = (*iterateBlock).second; if ( bk->isCaptured() ) { ZMthrow ( ZMxHepAlreadyDone (string("Attempt to capture designated data for block ") +bk->name() +string(" multiple times for one row "))); return false; } } // NOTE - If ANY block cannot be captured, no capture will occur! // That is why we do the awkward 2 separate loops. */ blocksMap::iterator iterateBlock; for ( iterateBlock = blocks.begin(); iterateBlock != blocks.end(); iterateBlock++ ) { bk = (*iterateBlock).second; if (!bk->isCaptured()) { bool b = bk->capture(); if ( !b ) { return false; } } } return true; } /* capture() */ // 4 // *************************** // // // // setExistingColumn // // // // *************************** // // Try to find the given label in the set of columns. If it exists, capture // the value and return 1. If not, return 0. Per the inherited interface... // NO EXCEPTION OR WARNING OUTPUT SHOULD BE PRODUCED BY THIS ROUTINE. // Therefore, we have to imbed this in a try loop in case the program framework // normally does not ignore ZMxCapture -- we still want to ignore it! // Logging specified in the ZM exception mechanism will still be enabled. #define setExistingColumn_MACRO(TYPE) \ int \ HepNtuple::setExistingColumn( \ const string& lbl, \ TYPE val ) \ { \ if ( ! isValid() ) { \ return 0; \ } \ return setExistingColumnF(lbl, val, this); \ } template static bool setExistingColumnF (const string& lbl, T value, HepNtuple* tuple) { // Note -- instead of this try/catch we should probably use the // ZM exception mechanism to push the ZMignore handler onto ZMxCapture // handler and pop it back off when finished. bool b; #ifdef HANDLE_EXCEPTION_ENABLE try { b = captureF ( lbl, value, tuple ); } catch (ZMxHepTuple) { return 0; } #else // HepNtuple::ZMxCapture::setHandler(ZMignore); b = captureF ( lbl, value, tuple ); #endif if (b) { return 1; } else { return 0; } } setExistingColumn_MACRO ( Int1 ) setExistingColumn_MACRO ( Int2 ) setExistingColumn_MACRO ( Int4 ) #ifdef Int8 setExistingColumn_MACRO ( Int8 ) #endif setExistingColumn_MACRO ( Float4 ) setExistingColumn_MACRO ( Float8 ) #ifdef Float16 setExistingColumn_MACRO ( Float16 ) #endif setExistingColumn_MACRO ( bool ) setExistingColumn_MACRO ( void * ) // 7 // *************************** // // // // captureBlock (blockName) // // // // *************************** // // Capture by designated variables (or designated accessors) all variables in // this block of the HepNtuple which have not already been captured. Some // or all of the column may already have been captured; Should not // be called twice for same block for one row (unless cleared). bool HepNtuple::captureBlock ( const string& blockName) { if ( ! isValid() ) { return false; } Block * bk = findBlock(blockName); if ( !bk ) { ZMthrow (ZMxHepUnknownBlock (string("Could not find ")+ string(blockName)+ string("indicated block to capture") )); return false; } return bk->capture(); } /* CaptureBlock */ // 8 // *************************** // // // // captureColumn // // // // *************************** // // Try to find the given label in the set of columns. If it exists, capture // the designated variable and return true1. If not, ir if there is no // designated variable or accessor, return false. bool HepNtuple::captureColumn (const string& nametag) { if ( ! isValid() ) { return false; } TupleNameTag tag; parseNameTag( tag, nametag); if (!tag.isValid()) { ZMthrow ( ZMxHepUnknownColumn (string("Improper form for column name tag: ")+ string(nametag)) ); return false; } Column* c = findColumn( nametag ); if ( !c ) { ZMthrow (ZMxHepUnknownColumn (string("Attempt to capture a non-existent column: ")+ string(nametag)) ); return false; } setCurrentColumn(c); return c->captureDesignatedValues(); // TODO - dont forget this form of captureValue must check that there // is a designated variable or accessor, before using it. It should // throw if there are none. } /* captureColumn */ // 8 // *************************** // // // // storeCapturedData // // // // *************************** // // Prepare and put the captured data into the actual Ntuple storage. // Returns the number of blocks captured. // If all blocks the storage will be done for all entire row at once, to // take advantage of the underlying manager method. Otherwise, we store a // block at a time. // if all blocks have been captured, or // all blocks that bool HepNtuple::storeCapturedData () { if ( ! isValid() ) { ZMthrow(ZMxHepVacuousItem("attempt to book an invalidated ntuple")); return false; } if ( !mayUse() ) { ZMthrow(ZMxHepUnmanagedItem("attempt to store an unmanaged ntuple")); return false; } if ( manager()->isReadOnly() ) { ZMthrow(ZMxHepCantWriteFile( manager()->fileName() + " is read only. Can not capture Ntuple data." )); return false; } if ( isDefinitionChanged() ) { // bookNewColumns does what is necessarily // for each block and or column that // has not yet been 'booked' book(); #ifdef IDEAS Any new defines? decide form of booking base this on strategies etc. loop over columns: check if already booked check ok if not ok invoke consistency-check if not ok error create-new-col-when-store-happens loop over blocks format from attribs book the block using that format #endif // IDEAS } Block* bk; //bool allCaptured = true; bool b; for ( blocksMap::iterator iterateBlock = blocks.begin(); iterateBlock != blocks.end(); iterateBlock++ ) { bk = (*iterateBlock).second; // Always store the block (whether or not it has been captured) // Since we do a clearData() after store and a setToDefault at // the creation of the column, we are insured that the value // of the columns that have not been captured is the default // value. prepareBlockForStoring(bk); } b = storeWholeRow(); /* The following code allow for storing of only the block that have been entirely captured. for ( blocksMap::iterator iterateBlock = blocks.begin(); iterateBlock != blocks.end(); iterateBlock++ ) { bk = (*iterateBlock).second; b = bk->isCaptured(); allCaptured &= b; if ( b ) { prepareBlockForStoring(bk); } } if (allCaptured) { b = storeWholeRow(); } else { for ( blocksMap::iterator iterateBlock = blocks.begin(); iterateBlock != blocks.end(); iterateBlock++ ) { bk = (*iterateBlock).second; if (bk->isCaptured () ) { b = storeSingleBlock (bk); } else { // b = copeWithUncapturedBlock (bk); } } } // HERE should insure any storing closure // like hs_cwn_advance for Histoscope */ _nrows++; isDirty(true); // Restore all columns as not captured and with default values. clearData(); return b; } bool HepNtuple::captureThenStore ( ) { if ( capture() ) { return storeCapturedData(); } return false; } // ---------------------------------------------------------------------- // Private Methodes // *************************** // // // // prepareBlockForStoring // // // // *************************** // // Copy the captured data to the proper location for the manager. // We assume that booking already happened and capturedData // already creating the need data array with the needed padding. bool HepNtuple::prepareBlockForStoring(Block* bk) { if ( ! isValid() ) { return false; } bk->capturedData(); return true; } /****************/ /* */ /* book */ /* */ /****************/ bool HepNtuple::book() { if ( ! isValid() ) { return false; } _changedDefinition = false; return true; } /****************/ /* */ /* clearData() */ /* */ /****************/ bool HepNtuple::clearData ( ) { if ( ! isValid() ) { return false; } Block *bk; for ( blocksMap::iterator iterateBlock = blocks.begin(); iterateBlock != blocks.end(); iterateBlock++ ) { bk = (*iterateBlock).second; bk->clear(); } return true; } bool HepNtuple::clearDataBlock (const string& blockName) { if ( ! isValid() ) { return false; } Block *bk = findBlock(blockName); if (bk == NULL) { ZMthrow ( ZMxHepUnknownBlock (string("Could not find indicated block to clear ") +blockName) ); return false; } bk->clear(); return true; } bool HepNtuple::clearDataColumn (const string& colName) { if ( ! isValid() ) { return false; } Column *col = findColumn(colName); if (col == NULL) { ZMthrow ( ZMxHepUnknownColumn (string("Could not find indicated column to clear ") +colName) ); return false; } col->clear(); return true; } /**************************************************************************** function that has not been implemented * captureN loop on N capture the value mark captured mark once-captured 6 proptotypes ****************************************************************************/ ZM_END_NAMESPACE( zmht ) /* } // namespace zmht */