//*************************************************************************** // File: APPStored.cc //-------------------------------------------------------------------------- // Author: Mike Carew // Date: 6/8/99 // //*************************************************************************** //------------- //-- Headers -- //------------- #include "Level3Mods/APPStored.hh" #include "Framework/APPFramework.hh" #include "Framework/APPPath.hh" #include "Framework/APPList.hh" #include "Framework/APPExecNode.hh" #include "Framework/APPExecutable.hh" #include "Framework/APPSequenceNode.hh" #include "Framework/AppAction.hh" #include "Framework/AppActionTime.hh" #ifdef USE_CDFEDM2 #include "TriggerObjects/TL3B_StorableBank.hh" #include "TriggerObjects/TL3D_StorableBank.hh" #include "TriggerObjects/TL3T_StorableBank.hh" #include "Edm/EventRecord.hh" #include "Edm/GenericConstHandle.hh" #include "Edm/ConstHandle.hh" #include "Edm/Handle.hh" #else #include "Trybos/TRY_Generic_Bank.hh" #include "Banks/TL3B_Bank.hh" #include "Banks/TL3D_Bank.hh" #include "Banks/TL3T_Bank.hh" #endif #include #include #include #include #include //------------------ //-- Constructors -- //------------------ APPStored::APPStored( ) { // Initialize data pathList = new APPList( ); streamList = new APPList( ); passedStats = new APPList( ); passed = 0 ; passedThisEvent = 0 ; streamPassed = 0 ; pathMatrix = 0 ; cpuTime = 0 ; _nMods = 0; _nPaths = 0; _nStreams = 0; _nEvents = 0; } // StreamNode is the class for streams StreamNode::StreamNode( ) { name = 0; paths = new APPList( ); nExec = 0; } //PathNode is the class for Paths PathNode::PathNode( ) { name = 0; mods = new APPList( ); nExec = 0; } //ModNode is the class for modules inside PathNode ModNode::ModNode( ) { name = 0; executed = false; query = false; passed = false; cpuTime = 0.0; } //StreamPathNode is the class for Paths inside StreamNode StreamPathNode::StreamPathNode( ) { name = 0; passed = false; } //--------------- //- Destructor -- //--------------- // Note: Destructors do nothing except delete new'd objects APPStored::~APPStored( ) { // First delete the multidimensional array pathMatrix if (pathMatrix != 0) { for (int i = 0; i < _nPaths; ++i ) { delete[] pathMatrix[i] ; } delete[] pathMatrix ; } // If pathList exists, call the destuctor for all of its elements // and then delete itself; if (pathList != 0) { APPListIterator iter( *pathList ); PathNode** temp; while ( temp = iter( ) ) { delete *temp; } delete pathList; } // Do the same for streamList if (streamList != 0) { APPListIterator iter( *streamList ); StreamNode** temp; while ( temp = iter( ) ) { delete *temp; } delete streamList; } // Now passedStats if (passedStats != 0) { APPListIterator iter ( *passedStats ); bool** temp; while ( temp = iter( ) ) { delete [] *temp; } delete passedStats; } if (streamPassed != 0) delete[] streamPassed; if (cpuTime != 0) delete[] cpuTime; } PathNode::~PathNode( ) { delete[] name; APPListIterator iter( *mods ); ModNode** mod; while ( mod = iter( ) ) { delete *mod; } delete mods; } ModNode::~ModNode() { delete[] name; } StreamNode::~StreamNode( ) { delete[] name; APPListIterator iter( *paths ); StreamPathNode** path; while ( path = iter( ) ) { delete *path; } delete paths; } StreamPathNode::~StreamPathNode( ) { delete[] name; } //-------------------------- // Printing methods //-------------------------- // Print out the name and executed this event // info for a module in a path void ModNode::print() { std::cout << name; std::cout << "\t\t"; std::cout << executed; std::cout << "\t\t"; std::cout << passed; } // Print out the name and passed this event // info for a path in a stream void StreamPathNode::print( ) { std::cout << name; std::cout << "\t\t\t"; std::cout << passed; } // Print out the print of the path and // the name and executed this event info for all the modules void PathNode::print() { // name std::cout << name << "\t\t" << "Executed" << "\t\t" << "Passed" << std::endl; std::cout << "--------------------------------" << std::endl; // Loop over all modules APPListIterator iter( *mods ); ModNode** path; while ( path = iter( ) ) { (*path)->print(); std::cout << std::endl; } } // Call the print function for all the paths in the class void APPStored::print() { APPListIterator iter( *pathList ); PathNode** temp; while ( temp = iter( ) ) { (*temp)->print(); std::cout << std::endl; } std::cout << std::endl << std::endl; } // Print all the streams in the path plus the paths in // each stream and their passed this event info void APPStored::printStreams() { APPListIterator iter ( *streamList ); StreamNode** temp; StreamPathNode **name; std::cout << "**********STREAMS**********" << std::endl; while ( temp = iter( ) ) { std::cout << "Name: " << (*temp)->name << std::endl; std::cout << "PathName\t\t" << "Passed" << std::endl; std::cout << "---------------------------" << std::endl; APPListIterator iter2 ( *((*temp)->paths) ); while ( name = iter2( ) ) { (*name)->print( ); std::cout << std::endl; } } std::cout << std::endl << std::endl; } // Print the name of the path and the passed this event info void APPStored::printPassedInfo( ) { std::cout << "******PASSED INFO**********" << std::endl; for (int i = 0; i < _nMods; i++) std::cout << passed[i] << std::endl; } // The summary info. Printed at the endJob method of the output module // Prints out all the classes stored info void APPStored::summary( ) { std::cout << std::endl << std::endl; std::cout << "***********SUMMARY INFO ************" << std::endl << std::endl; // Print the number of events std::cout << "Number of Events: " << _nEvents << std::endl << std::endl; // First print the stream definition and stats int i = 0, count = 0; std::cout << "STREAMS" << std::endl; std::cout << "-----------------------------------" << std::endl << std::endl; APPListIterator iter ( *streamList ); StreamNode** stream; while ( stream = iter( ) ) { // Print out the stream name and the number of times it passed if (*stream != NULL) { std::cout << (*stream)->name << "\t\t\t" << streamPassed[count++] << std::endl; std::cout << "----------------------------------" << std::endl; APPListIterator iter2 ( *((*stream)->paths) ); StreamPathNode** pathPassed; // Loop over all the paths in the stream while ( pathPassed = iter2( ) ) { if (*pathPassed != NULL) { // Print out the name std::cout << (*pathPassed)->name << "\t\t\t\t"; // The executed info for paths is stored in the pathlist // so we loop through that if (pathList != NULL) { APPListIterator pIter ( *pathList ); std::string s = (*pathPassed)->name; s[ strlen( (*pathPassed)->name )] = '\0'; PathNode **ptemp; PathNode **pfound = NULL; while ( ptemp = pIter( ) ) { if (*ptemp != NULL ) { if (s == (*ptemp)->name){ pfound = ptemp; } } } if (pfound != NULL) std::cout << (*pfound)->nExec << std::endl; } } } std::cout < iter3 ( *pathList ); PathNode** path; while ( path = iter3( ) ) { if (*path != NULL) { // Print the path name std::cout << (*path)->name << "\t\t" << "Events Passed" << std::endl; std::cout << "-----------------------------------" << std::endl; // Loop over all modules APPListIterator iter4 ( *((*path)->mods) ); ModNode** mod; while ( mod = iter4( ) ) { if (*mod != NULL) std::cout << (*mod)->name << "\t\t" << passed[i++] << std::endl; } std::cout << std::endl << std::endl; } } } //-------------------------------- // Members that fill the class //--------------------------------- // This method stores the path names and definitions into // the class void APPStored::fillNames( APPList* paths) { //Make a path iter APPListIterator iter( *paths ); APPPath** path; APPExecNode** node; ModNode* ptr; // loop over all paths in the framework while ( path = iter( ) ) { if ( (*path)->isEnabled( ) ) { //Ignore disabled paths PathNode* temp = new PathNode( ); // copy the name temp->name = new char[strlen( (*path)->name( ) )+1]; strcpy(temp->name, (*path)->name( )); // loop over all the modules in the path APPListIterator theNodeIterator( *((*path)->nodes( )) ); while ( node = theNodeIterator( ) ) { _nMods++; // increment the global mod counter ptr = new ModNode(); //declare a new Module to insert // copy the name ptr->name = new char[strlen( (*node)->target( )->name( ) )+1]; strcpy( ptr->name, (*node)->target( )->name( ) ); // Copy the exec info and append ptr->executed = (*node)->isExecuted(); temp->mods->append( &ptr ); // delete ptr; } // finally, insert the path pathList->append( &temp ); _nPaths++; // increment the global path counter // delete temp; } } } // This method stores the stream names and definitions into // the class void APPStored::fillStreamNames( APPList* streams) { APPListIterator iter( *streams ); //Make a stream iter AppStream **stream; StreamNode* temp; APPPath **path; StreamPathNode *passed; // Loop over all streams in the framework // streamList = new APPList( ); while ( stream = iter( ) ) { _nStreams++; //increment the global streams counter temp = new StreamNode( ); //declare a new StreamNode to insert // Copy the stream name temp->name = new char[strlen( (*stream)->name( )) + 1]; strcpy( temp->name, (*stream)->name( ) ); // Loop over all the paths in the stream APPListIterator iter2 ( *((*stream)->paths( ) ) ); while ( path = iter2( ) ) { // Declare a new Path, copy the name, and append passed = new StreamPathNode( ); passed->name = new char[strlen( (*path)->name( )) + 1]; strcpy( passed->name, (*path)->name( ) ); temp->paths->append( &passed ); // delete passed ; } // Finally, append the stream streamList->append( &temp ); // delete temp; } // delete streamList; } void APPStored::fillStreamPassed( APPList* streams ) { APPListIterator iter1( *streams ); APPListIterator iter2( *streamList ); AppStream **theStream; StreamNode **list; APPPath **path; StreamPathNode **passed; while ( theStream = iter1( ) ) { list = iter2( ); if ( (*theStream)->isEnabled( ) && (*theStream)->isOpen( ) ) { APPListIterator iter3 ( *((*theStream)->paths())); APPListIterator iter4 ( *((*list)->paths) ); while ( path = iter3( ) ) { passed = iter4( ); if ( (*path)->isEnabled( ) && (*path)->passed( ) ) (*passed)->passed = true; } } } } // This method gets the executed, queried, and passed information // for the current event, and fills it to each module class void APPStored::fillExecuted( APPList* paths ) { APPPath** path = 0 ; PathNode** pathlist = 0 ; _nEvents++; //Increment the event counter // Paths in the framework APPListIterator iter1( *paths ); // Paths in APPStored, same as the framework APPListIterator iter2( *pathList); // Loop over the paths while ( path = iter1( ) ) { if ( (*path)->isEnabled( ) ) { //Ignore disabled paths // Loop over the SequenceNodes in the framework APPListIterator n1Iterator( *((*path)->seqNodes( )) ); pathlist = iter2( ); APPListIterator n2Iterator( *((*pathlist)->mods) ); APPSequenceNode** seqNode = 0 ; ModNode** mod = 0 ; // Store the info while ( seqNode = n1Iterator( ) ) { mod = n2Iterator( ); (*mod)->executed = (*seqNode)->isExecThisEvent( ); (*mod)->query = (*seqNode)->isQueryThisEvent( ); (*mod)->passed = (*seqNode)->passedThisEvent( ); } } } } //--------------------------------------- // Member to clear class info //--------------------------------------- // The code has each module store what happened to it on the // last event, this method clears that info before each new event void APPStored::clearExecInfo() { APPListIterator iter ( *pathList ); PathNode** path; while ( path = iter( ) ) { APPListIterator iter2 ( *((*path)->mods) ); ModNode** mod; while ( mod = iter2( ) ) { (*mod)->executed = false; (*mod)->query = false; (*mod)->passed = false; } } } //----------------------------------- // Members to make bit masks // with class information encoded //----------------------------------- // This method is a bit of a misnomer. // It actually writes the paths and module into a long std::string // Path names are separated on either side by two whitespaces and // modules are separated by a single whitespace std::string APPStored::makeBitMask() { // Loop over all paths APPListIterator iter ( *pathList ); std::string bitMask = " "; //Initialize the std::string PathNode** path; while ( path = iter( ) ) { bitMask += (*path)->name; // Append the path name bitMask += " "; // add a whitespace APPListIterator iter2 ( *((*path)->mods) ); ModNode** mod; while ( mod = iter2( ) ) { bitMask += " "; bitMask += (*mod)->name; // Insert each module } bitMask += " "; } return bitMask; // return the std::string } // This method is indentical to makeBitMask except // it stores streams and paths instead of paths and modules std::string APPStored::makeStreamBitMask( ) { APPListIterator iter ( *streamList ); std::string bitMask = " "; StreamNode** stream; while ( stream = iter( ) ) { bitMask += (*stream)->name; bitMask += " "; APPListIterator iter2 ( *((*stream)->paths) ); StreamPathNode** path; while ( path = iter2( ) ) { bitMask += " "; bitMask += (*path)->name; } bitMask += " "; } return bitMask; } //Identical to makePassedBoolInfo except that it records the module's // executed-this-event info instead of the passed-this-event info bool* APPStored::makeExecBoolInfo( ) { APPListIterator iter1 ( *pathList ); PathNode** path; ModNode** mod; int counter = 0; int nwords; nwords = _nMods; if ( (_nMods % 32) != 0 ) nwords += 32; bool* bitMask = new bool[ nwords ]; for ( int i = 0; i < nwords; i++ ) bitMask[i] = 0; while ( path = iter1( ) ) { APPListIterator iter2 ( *((*path)->mods) ); while ( mod = iter2( ) ) bitMask[counter++] = (*mod)->executed; } return bitMask; } // Identical to makePassedBoolInfo except it records the modules // queried-this-event instead of passed-this-event bool* APPStored::makeQueryBoolInfo( ) { APPListIterator iter1 ( *pathList ); PathNode** path; ModNode** mod; int counter = 0; int nwords; nwords = _nMods; if ( (_nMods % 32) != 0 ) nwords += 32; bool* bitMask = new bool[ nwords ]; for ( int i = 0; i < nwords; i++ ) bitMask[i] = 0; while ( path = iter1( ) ) { APPListIterator iter2 ( *((*path)->mods) ); while ( mod = iter2( ) ) bitMask[counter++] = (*mod)->query; } return bitMask; } // This method takes the passed-this-event info stored in the // class and converts it to a bitMask. // The method goes through the modules in order and appends a // one to the mask if it passed-this-event and a zero otherwise bool* APPStored::makePassedBoolInfo( ) { APPListIterator iter1 ( *pathList ); PathNode** path; ModNode** mod; int counter = 0; int nBits; // Find out the number of Bits we need to store the event. // The number of bits must be a multiple of 32, since we // want to store words. nBits = _nMods; if ( _nMods % 32 != 0 ) nBits += 32; // dynamically declare the bitMask and initialize to zero. bool* bitMask = new bool[ nBits ]; for ( int i = 0; i < nBits; i++ ) bitMask[i] = 0; // Loop over all the modules and record the passed info. while ( path = iter1( ) ) { APPListIterator iter2 ( *((*path)->mods) ); while ( mod = iter2( ) ) bitMask[counter++] = (*mod)->passed; } return bitMask; } // This makes a list of pointers into the bitMask that point into // the beginning of each path int* APPStored::makePathPointers( ) { int* pathPointers = new int[ nPaths( ) ]; // Loop over all the modules and the module number at the beginning // of each path int modCounter = 0; int pathCounter = 0; PathNode** path; APPListIterator iter1 ( *pathList ); while ( path = iter1( ) ) { APPListIterator iter2 ( *((*path)->mods) ); pathPointers[pathCounter++]=modCounter; while ( iter2( ) ) modCounter++; } return pathPointers; } // This method makes an array of floats that contains // the cputTime for each of the modules for this event float* APPStored::makeTimingInfo( ) { // Declare an array the size of the number of modules float *info = new float[ nMods( ) ]; APPListIterator iter1 ( *pathList ); PathNode** path; ModNode** mod; int counter = 0; // loop over all paths while ( path = iter1( ) ) { APPListIterator iter2 ( *((*path)->mods) ); // loop over all modules while ( mod = iter2( ) ) // fill the info info[counter++] = (*mod)->cpuTime; } return info; } // This method takes the passed-this-event info for the // paths and converts it to a bit Mask. This function is // not used bool* APPStored::makeExecStreamInfo( ) { APPListIterator iter1 ( *streamList ); StreamNode** stream; StreamPathNode** temp; int counter = 0; int nBits; nBits = _nPaths; if ( (_nPaths % 32) != 0 ) nBits += 32; bool* bitMask = new bool[ nBits ]; for ( int i = 0; i < nBits; i++ ) bitMask[i] = 0; while ( stream = iter1( ) ) { APPListIterator iter2 ( *((*stream)->paths) ); while ( temp = iter2( ) ) bitMask[counter++] = (*temp)->passed; } return bitMask; } std::string APPStored::makeExecInfo() { APPListIterator iter ( *pathList ); std::string bitMask = " "; PathNode** path; while ( path = iter( ) ) { APPListIterator iter2 ( *((*path)->mods) ); ModNode** mod; while ( mod = iter2( ) ) { if ( (*mod)->executed == 1 ) bitMask += '1'; else bitMask += '0'; } } return bitMask; } //---------------------------------- // Members to decode the bit masks //---------------------------------- void APPStored::decodeExecInfo( std::string bitMask ) { std::string::iterator iter = bitMask.begin(); char c; int i = 0; iter++; APPListIterator pathIter ( *pathList ); PathNode** path; while ( path = pathIter( ) ) { APPListIterator modIter ( *((*path)->mods) ); ModNode** mod; while ( mod = modIter( ) ) { c = *iter; iter++; if ( c == '1' ) { (*mod)->executed = 1; passed[i]++; passedThisEvent[i] = true; } else { (*mod)->executed = 0; passedThisEvent[i] = false; } i++; } } APPListIterator pIter ( *pathList ); PathNode** ptemp; i = 0; while ( ptemp = pIter( ) ) { APPListIterator pIter2 ( *((*ptemp)->mods) ); while ( pIter2( ) ) { i++; } (*ptemp)->nExec = passed[ i - 1 ]; } APPListIterator sIter ( *streamList ); StreamNode** stream; i = 0; bool flag; // loop over all streams while ( stream = sIter( ) ) { flag = false; // Initially set flag to flase APPListIterator iter3 ( *((*stream)->paths) ); StreamPathNode** pathPassed; // Loop over all Paths in the stream while ( pathPassed = iter3( ) ) { std::string s = (*pathPassed)->name; //Get the path name // Loop over the path list APPListIterator iter4 ( *pathList ); while ( path = iter4( ) ) { std::string t = (*path)->name; // Get the path we are looking for if ( s == t ) { APPListIterator iter5 ( *((*path)->mods) ); ModNode** mod, **prev; while ( mod = iter5( ) ) prev = mod; // If that path passed, set flag to true if ( (*prev)->executed ) flag = true; } } } // If the flag is if ( flag == true ) streamPassed[i]++; i++; } } void APPStored::decodeQueryInfo( std::string bitMask ) { std::string::iterator iter = bitMask.begin(); char c; iter++; APPListIterator pathIter ( *pathList ); PathNode** path; while ( path = pathIter( ) ) { APPListIterator modIter ( *((*path)->mods) ); ModNode** mod; while ( mod = modIter( ) ) { c = *iter; iter++; if ( c == '1' ) (*mod)->query = 1; else (*mod)->query = 0; } } } // This method decodes the info stored in the TL3D_Bank void APPStored::decodePassedInfo( std::string bitMask ) { std::string::iterator iter = bitMask.begin(); char c; iter++; // Loop over all paths APPListIterator pathIter ( *pathList ); PathNode** path; while ( path = pathIter( ) ) { // Loop over all mods APPListIterator modIter ( *((*path)->mods) ); ModNode** mod; while ( mod = modIter( ) ) { c = *iter; iter++; // Get the info from the std::string if ( c == '1' ) (*mod)->passed = 1; else (*mod)->passed = 0; } } } void APPStored::decodeExecStreamInfo( std::string bitMask ) { std::string::iterator iter = bitMask.begin(); char c; iter++; APPListIterator streamIter ( *streamList ); StreamNode** stream; while ( stream = streamIter( ) ) { APPListIterator pathIter ( *((*stream)->paths) ); StreamPathNode** path; while ( path = pathIter( ) ) { c = *iter; iter++; if ( c == '1' ) (*path)->passed = 1; else (*path)->passed = 0; } } } // This method takes a bitMask generated by the makeBitMask method, // decodes it, and stores the info in the class void APPStored::decodeBitMask( std::string bitMask ) { PathNode* paths = new PathNode(); ModNode* mods = new ModNode(); char c, prev = ' ' ; char* word = 0 ; int count, flag = 0, pathFlag = 0, modFlag = 0; std::string::iterator iter = bitMask.begin(); std::string::iterator temp; _nMods = 0; // Loop over the std::string char by char while ( iter != bitMask.end( ) ) { c = *iter; // Tokenize the std::string if ( c != ' ') { temp = iter; count = 0; while ( *temp != ' ' ) { count++; ++temp; } // Declare a new word since we saw a space, // and get the word word = new char[ count + 1 ]; for( int i = 0 ; i < count ; i++) { word[i] = c; prev = c; ++iter; c = *iter; } word[count] = '\0'; } // If there are two spaces, there is a new path if ( c == ' ' && prev == ' ') { flag = 1; pathFlag++; prev = c; ++iter; } // If not, the last word was a mod if ( c == ' ' && prev != ' ') { if (flag == 1 && pathFlag % 2 == 1) { if ( modFlag > 1) { // insert the mod pathList->append( paths ); // delete paths; paths = new PathNode(); modFlag = 0; } paths->name = word; } else { modFlag++; mods->name = word; // insert the path paths->mods->append( mods ); _nMods++; // replacing the ModNode pointed to by mods; must delete old // delete mods; mods = new ModNode(); } flag = 0; prev = c; ++iter; } } // insert the last path pathList->append( paths ); // delete paths; // delete mods; // delete[] word ; } // This method takes a bitMask made by makeStreamBitMask, decodes it, // and stores the info. This is identical to decodeBitMask void APPStored::decodeStreamBitMask( std::string bitMask ) { StreamNode* stream = new StreamNode(); StreamPathNode* passed = new StreamPathNode(); char c, prev = ' ', *word; int count, flag = 0, streamFlag = 0, passedFlag = 0; std::string::iterator iter = bitMask.begin(); std::string::iterator temp; while ( iter != bitMask.end( ) ) { c = *iter; if ( c != ' ') { temp = iter; count = 0; while ( *temp != ' ' ) { count++; ++temp; } word = new char[count+1]; for( int i = 0 ; i < count ; i++) { word[i] = c; prev = c; ++iter; c = *iter; } } if ( c == ' ' && prev == ' ') { flag = 1; streamFlag++; prev = c; ++iter; } if ( c == ' ' && prev != ' ') { if (flag == 1 && streamFlag % 2 == 1) { if ( passedFlag > 1) { _nStreams++; streamList->append( stream ); // delete stream; // must delete the old StreamNode stream = new StreamNode(); passedFlag = 0; } stream->name = word; } else { passedFlag++; passed->name = word; stream->paths->append( passed ); // delete passed; // must delete the old StreamPathNode passed = new StreamPathNode(); } flag = 0; prev = c; ++iter; } } streamList->append( stream ); _nStreams++; // delete stream; // delete passed; // delete[] word ; } // This method decodes this event's timing info and // tablulates it to the total void APPStored::decodeTimingInfo( float *timingInfo ) { for (int i = 0; i < nMods( ); i++ ) cpuTime[i] += timingInfo[i]; } //================================= // Memebers to convey the class // size //================================= // This method returns the number of words long the // TL3B Bank will be based on the size of APPStored int APPStored::bankSize( ) { // Get the name BitMask std::string s = makeBitMask( ); // Get the Stream BitMask std::string t = makeStreamBitMask( ); // Get the number of words for the names int size = s.length( ) / 4; if ( (s.length( ) / 4) % 4 > 0 ) size++; // Get the number of words for the streams int size2 = t.length( ) / 4; if ( (t.length( ) /4) % 4 > 0 ) size2++; // Return the sum plus 4 for storing the bitMask size in the bank return size + size2 + 4; } // This method returns the number of words long the // TL3D Bank will be based on the current size of APPStored int APPStored::execBankSize( ) { // Find out how many words are needed for the number of modules int size = (int)(nMods( ) / 32); if ( (nMods( ) % 32) != 0 ) size++; // return the size plus 4 to store the bitMask size return size + 4; } //========================= //= selectors = //======================== // The number of seq modules in the run int APPStored::nMods( ) { return _nMods; } // The number of Paths in the run int APPStored::nPaths( ) { return _nPaths; } // The number Stream in the run int APPStored::nStreams( ) { return _nStreams; } // The number of events in the run int APPStored::nEvents( ) { return _nEvents; } //================================= // Members to read and write to // banks //================================= // This method writes the name information into the // class and into the TL3B bank. This is the first // method called by the Output module #ifndef USE_CDFEDM2 void #else Id #endif APPStored::writeTL3B( AppFramework *framework, APPList* streams, AbsEvent* anEvent ) { // Get the path and module names from the framework fillNames( framework->paths( ) ); // Get the stream definitions from the framework fillStreamNames( streams ); // Declare a new TL3B_Bank #ifndef USE_CDFEDM2 TRY_Bank_Name name( "TL3B" ); TRY_Bank_Number num( 1 ); TRY_Bank_Type type ( bankSize( ), 1 ); TL3B_Bank *bnk = new TL3B_Bank( name, num, type ); #else Handle bnk(new TL3B_StorableBank ); #endif // Fill the bank by making a path bitMask and a StreamBitMask bnk->setString( makeBitMask( ), makeStreamBitMask( ) ); // Write the files name.dat and streams.dat // writeFile( ); // write the bank to the event #ifdef USE_CDFEDM2 GenericConstHandle readHandle = anEvent->append( bnk ); #else anEvent->append( *bnk ); delete bnk; #endif // Declare all the exec info we will store if (passed == 0) passed = new int[ _nMods ]; if (passedThisEvent == 0) passedThisEvent = new bool[ _nMods ]; if (cpuTime == 0) cpuTime = new float[ _nMods ]; for ( int i = 0; i < _nMods; i++ ) { passed[i] = 0; passedThisEvent[i] = false ; cpuTime[i] = 0.0; } if (streamPassed == 0) streamPassed = new int[ _nStreams ]; for ( int i = 0; i < _nStreams; i++ ) { streamPassed[i] = 0; } if ( (pathMatrix == 0) && (_nPaths > 0) ) { pathMatrix = new int*[ _nPaths ]; for (int i = 0; i < _nPaths; i++ ) { pathMatrix[i] = new int[ _nPaths ]; } } for (int i = 0; i < _nPaths; i++ ) { for (int j = 0; j < _nPaths; j++ ) { pathMatrix[i][j] = 0; } } #ifdef USE_CDFEDM2 return readHandle->object_id(); #endif } // This method is called once for each event // by the OutputModule and tallies the exec info // into a TL3D bank #ifndef USE_CDFEDM2 TL3D_Bank* #else Handle #endif APPStored::writeTL3D( AppFramework *framework, APPList* streams) { // Clear the class clearExecInfo( ); //Get the exec info from the framework fillExecuted( framework->paths( ) ); fillStreamPassed( streams ); // Make a new TL3D bank #ifndef USE_CDFEDM2 TRY_Bank_Name name( "TL3D" ); TRY_Bank_Number num( 1 ); TRY_Bank_Type type( execBankSize( ), 1 ); TL3D_Bank *bnk = new TL3D_Bank( name, num, type ); #else Handle bnk(new TL3D_StorableBank ); #endif // Fill the bank // (must also destroy temporary array from makePassedBoolInfo) bool* passedInfo = makePassedBoolInfo(); int* pathPointers = makePathPointers(); #ifdef USE_CDFEDM2 bnk->setInfo( passedInfo, nMods( ), pathPointers , nPaths( )); #else bnk->setInfo( passedInfo, nMods( )); #endif delete [] passedInfo; delete [] pathPointers; // store the info storeExecInfo( ); return(bnk); // write the bank to the event } // This method writes the current events timing statistics into // the TL3T Bank #ifndef USE_CDFEDM2 void #else Id #endif APPStored::writeTL3T( AppFramework *framework, AbsEvent* anEvent ) { // Get the timing info from the framework writeTime( framework ); // declare a new bank #ifndef USE_CDFEDM2 TRY_Bank_Name name( "TL3T" ); TRY_Bank_Number num( 1 ); TRY_Bank_Type type( nMods( ) + 1, 1); // The size is the number of mods+1 TL3T_Bank *bnk = new TL3T_Bank( name, num, type ); #else Handle bnk(new TL3T_StorableBank ); #endif // Set the info into the bank // (must also delete temporary array created by makeTimingInfo) float* timingInfo = makeTimingInfo(); #ifdef USE_CDFEDM2 bnk->setArray( timingInfo, nMods( ) ); #else bnk->setString( timingInfo, nMods( ) ); #endif delete [] timingInfo; // store the total cpu time storeTime( ); // append the bank to the event #ifdef USE_CDFEDM2 GenericConstHandle readHandle = anEvent->append( bnk ); return readHandle->object_id(); #else anEvent->append( *bnk ); delete bnk; #endif } // This method will read the TL3B Bank from the Event // passed to it void APPStored::readTL3B( AbsEvent* anEvent ) { // Iterate over all the TL3B Banks #ifndef USE_CDFEDM2 TRY_Record_Iter_Same TL3B_iter( anEvent, "TL3B" ); if ( TL3B_iter.is_valid( ) ) { TL3B_Bank bnkTL3B( TL3B_iter ); TL3B_Bank* TL3B = &bnkTL3B; #else EventRecord::ConstIterator TL3B_iter( anEvent, "TL3B_StorableBank" ); if ( TL3B_iter.is_valid() ) { ConstHandle TL3B( TL3B_iter ); #endif // Get the name std::string std::string s = TL3B->getString( ) + " "; // Get the stream std::string std::string t = TL3B->getStreamString( ) + " "; // Fill the class with that info decodeBitMask( s ); decodeStreamBitMask( t ); ++TL3B_iter; } // Now clear the exec info in the class. // Make sure it is only done once static int oneTime = 0; if ( _nMods != 0 && oneTime == 0 ) { passed = new int[ _nMods ]; passedThisEvent = new bool[ _nMods ]; for (int i = 0; i < _nMods; i++ ) { passed[i] = 0; passedThisEvent[i] = false; } streamPassed = new int[ _nStreams ]; for ( int i = 0; i < _nStreams; i++ ) streamPassed[i] = 0; oneTime++; } } // This methods reads and decodes the TL3D Bank in the // event passed to it void APPStored::readTL3D( AbsEvent* anEvent ) { // Loop over all TL3D Banks #ifndef USE_CDFEDM2 TRY_Record_Iter_Same TL3D_iter( anEvent, "TL3D" ); if ( TL3D_iter.is_valid( ) ) { TL3D_Bank bnkTL3D( TL3D_iter ); TL3D_Bank* TL3D = &bnkTL3D; #else EventRecord::ConstIterator TL3D_iter( anEvent, "TL3D_StorableBank" ); if ( TL3D_iter.is_valid() ) { ConstHandle TL3D( TL3D_iter ); #endif // Get the exec info #ifdef USE_CDFEDM2 std::string s = TL3D->getInfo( ); #else std::string s = TL3D->getString( ); #endif // decode and store decodeExecInfo( s ); _nEvents++; ++TL3D_iter; } } // This method reads and decodes the TL3T Bank in // the event passed to it void APPStored::readTL3T( AbsEvent* anEvent ) { // Loop over all TL3T Banks #ifndef USE_CDFEDM2 TRY_Record_Iter_Same TL3T_iter( anEvent, "TL3T" ); if ( TL3T_iter.is_valid( ) ) { TL3T_Bank bnkTL3T( TL3T_iter ); TL3T_Bank* TL3T = &bnkTL3T; #else EventRecord::ConstIterator TL3T_iter( anEvent, "TL3T_StorableBank" ); if ( TL3T_iter.is_valid() ) { ConstHandle TL3T( TL3T_iter ); #endif #ifdef USE_CDFEDM2 float *timingInfo = TL3T->getArray( ); #else float *timingInfo = TL3T->getString( ); #endif // store its contents in the class decodeTimingInfo( timingInfo ); ++TL3T_iter; } } // This method writes the files name.dat and streams.dat void APPStored::writeFile( ) { // declare the iterators APPListIterator iter ( *pathList ); APPListIterator sIter ( *streamList ); // open the files ofstream output( "name.dat" ); ofstream output2( "streams.dat" ); StreamNode** stream; PathNode** path; char *c, *d; // loop over all paths. Separate each path by a newline and the // modules by whitespace while ( path = iter( ) ) { output.put( ' ' ); output.put( ' ' ); c = (*path)->name; while ( *c != '\0' ) { // write the path name byte by byte output.put( *c ); c++; } // loop over the modules APPListIterator iter2 ( *((*path)->mods) ); ModNode** mod; while ( mod = iter2( ) ) { d = (*mod)->name; output.put( ' ' ); while ( *d != '\0' ) { // write the module name output.put( *d ); d++; } output.put( ' ' ); } output.put( '\n' ); // put the std::endline to denote end of path } output.close( ); // close the file // loop over all the streams while ( stream = sIter( ) ) { output2.put( ' ' ); output2.put( ' ' ); c = (*stream)->name; while ( *c != '\0' ) { // write the stream name output2.put( *c ); c++; } // loop over all the paths APPListIterator sIter2 ( *((*stream)->paths ) ); StreamPathNode** pathPassed; while ( pathPassed = sIter2( ) ) { output2.put( ' ' ); d = (*pathPassed)->name; while ( *d != '\0' ) { //write the path name output2.put( *d ); d++; } output2.put( ' ' ); } output2.put( '\n' ); //separate each stream by a newline } output2.close( ); //close the file } // This method takes the exec info generate in the current event // and adds it to the overall summary void APPStored::storeExecInfo( ) { APPListIterator iter ( *pathList ); APPListIterator sIter ( *streamList ); PathNode** path; StreamNode** stream; int i = 0; // Loop over all the paths in the event // And record the results for each module // passed[ ] stores the number of times each module passed in order // and cpuTime[ ] stores the cpu time for that module while ( path = iter( ) ) { APPListIterator iter2 ( *((*path)->mods) ); ModNode** mod; while ( mod = iter2( ) ) { if ( (*mod)->passed ) { passed[i++] += 1; // if that mod passed, increment the info } else { i++; } } } // Now find out if the path itself passed. Each path class // has an int called nExec which is the number of times the path passed. // If all the modules were executed, increment this number APPListIterator pIter ( *pathList ); PathNode** ptemp; i = 0; while ( ptemp = pIter( ) ) { APPListIterator pIter2 ( *((*ptemp)->mods) ); while ( pIter2( ) ) { // Get the last module in the path i++; } (*ptemp)->nExec = passed[ i - 1 ]; } // Now update the path matrix // For every path that passed, we loop over every other passed // and increment the matrix where the two passed APPListIterator mIter ( *pathList ); PathNode** mtemp; int m = 0; int mcount = 0; // Loop over each path while ( mtemp = mIter( ) ) { ModNode **mMod, **mLast; APPListIterator mIter2 ( *((*mtemp)->mods) ); while ( mMod = mIter2( ) ) { m++; mLast = mMod; } // mLast is the last mod in the path, if it passed, the path did if ( (*mLast)->passed ) { APPListIterator nIter ( *pathList ); PathNode** ntemp; int ncount = 0; // Now loop over all the paths while ( ntemp = nIter( ) ) { int n = 0; ModNode **nMod, *nLast; APPListIterator nIter2 ( *((*ntemp)->mods) ); while ( nMod = nIter2( ) ) { n++; nLast = (*nMod); } // If nLast passed, then the both paths passed if ( nLast->passed ) { pathMatrix[mcount][ncount]++; //Increment the summary } ncount++; } } mcount++; } // Loop over each all streams. // For each path in the stream find out if it passed. // If any path passed, change flag to true. // After all paths have been loop, it flag is true, the stream passed i = 0; bool flag; // loop over all streams while ( stream = sIter( ) ) { flag = false; // Initially set flag to flase APPListIterator iter3 ( *((*stream)->paths) ); StreamPathNode** pathPassed; // Loop over all Paths in the stream while ( pathPassed = iter3( ) ) { std::string s = (*pathPassed)->name; //Get the path name // Loop over the path list APPListIterator iter4 ( *pathList ); while ( path = iter4( ) ) { std::string t = (*path)->name; // Get the path we are looking for if ( s == t ) { APPListIterator iter5 ( *((*path)->mods) ); ModNode** mod, **prev; while ( mod = iter5( ) ) prev = mod; // If that path passed, set flag to true if ( (*prev)->passed ) flag = true; } } } // If the flag is if ( flag == true ) streamPassed[i]++; i++; } } // This method writes the summary files for the event void APPStored::writePassedFile( ) { // Open the files for writing ofstream output( "pass.dat" ); ofstream output2( "sPass.dat" ); ofstream output3( "matrix.dat" ); ofstream output4( "time.dat" ); // let the first entry in pass.dat be the number of events output << _nEvents << " "; // Now output the number of times each module passed (in order) for (int i = 0; i < _nMods; i++ ) { output << passed[i] << " "; } output.close( ); // Now in sPass.dat output the number of times each stream passed for (int i = 0; i < _nStreams; i++) { output2 << streamPassed[i] << " "; } output2.close( ); // In matrix.dat output the entries filled in the path Matrix output3 << _nPaths << " "; for (int i = 0; i < _nPaths; i++ ) { for (int j = 0; j < _nPaths; j++ ) { output3 << pathMatrix[i][j] << " "; } } output3.close( ); // Finally, output the timing information for ( int i = 0; i < _nMods; i++ ) { output4 << cpuTime[i] << " "; } output4.close( ); } // This method is called once per event. It stores the cpuTime for // each module in the ModNode class for the current event void APPStored::writeTime( AppFramework *framework ) { // Loop over all the event's actions APPList *actions = framework->actions( ); APPListIterator iter ( *actions ); AppAction **action; while ( action = iter( ) ) { // If the name is framework default "Timer Action", we know we have times if ( (*action)->name() == "Timer Action") { // Dynamically cast action to AppActionTime AppActionTime *timer = dynamic_cast(*action); // Declare a map iterator to loop over all the mods TimerMap::const_iterator imod; // Loop over all paths APPListIterator iter ( *pathList ); PathNode **path; // Get the reference to the event timer const TimerMap& eventMap = timer->eventTimers( ); while ( path = iter( ) ) { // Loop over all the mods in the path APPListIterator iter2 ( *((*path)->mods) ); ModNode **mod; while ( mod = iter2( ) ) { // Get the mod name std::string modName( (*mod)->name ); // Find that name in the list of timers imod = eventMap.begin(); while ( imod != eventMap.end() ) { if ((*imod).first == modName) break; imod++; } // Record the info if ( imod != eventMap.end() ) { ZMdualTimer tim = (*imod).second; (*mod)->cpuTime = tim.cpuTime( ); } else (*mod)->cpuTime = -1.; } } } } } // This method takes the name of a module and a path and // returns the index number of the module for the overall module list // if it exists, otherwise it returns zero. This can be used // to access individual members of a bank int APPStored::moduleIndex( std::string moduleName, std::string pathName ) { APPListIterator iter ( *pathList ); PathNode **path; ModNode **mod; int count = 0; // Loop over all paths while ( path = iter( ) ) { std::string name( (*path)->name ); // Get the path name APPListIterator iter2 ( *((*path)->mods) ); // loop over all modules while ( mod = iter2( ) ) { std::string mName( (*mod)->name ); // Get the module name // See if this is the module we want if ( mName == moduleName && name == pathName) return count; count++; } } // We can't find the module return -1; } // This method takes a number of a Path from // 0 to n-1 where n is the number of Paths and a number // of a module in a path from 0 to k-1 where k is the // number of modules in that path and returns the // overall number of that module in the module List // It returns -1 if that path or module doesn't exist int APPStored::moduleIndex( int nPath, int nModInPath ) { APPListIterator iter (*pathList); PathNode **path; ModNode **mod; int pathCount = 0; int modCount = 0; while ( path = iter( ) ) { APPListIterator iter2 ( *((*path)->mods) ); if ( nPath == pathCount ) { for (int i = 0; i < nModInPath; i++ ) { mod = iter2( ); modCount++; } if ( mod ) return modCount; else return -1; } else { while ( mod = iter2( ) ) { modCount++; } pathCount++; } } return -1; } // This method takes a name of a path and returns the index // of that path is the pathList. It returns -1 if the path // cannot be found int APPStored::pathIndex( std::string pathName ) { APPListIterator iter (*pathList); PathNode **path; int count = 0; // Loop over all paths while ( path = iter( ) ) { // get the path name std::string name( (*path)->name ); if ( name == pathName ) return count; count++; } return -1; } // This method takes a integer from 0 to n-1 where n is the number // of paths in the event and returns the name of that path as // a std::string. It returns NULL if the number is outside those bounds. std::string APPStored::pathName( int index ) { APPListIterator iter (*pathList); PathNode **path; for ( int i = 0; i < index; i++ ) path = iter( ); if ( path ) return std::string( (*path)->name ); else return NULL; } // This method takes an integer from 0 to n-1 where n is the // number of streams in the event. It then returns the name // of that stream as a std::string, or if the number is outside // those bounds, it returns NULL std::string APPStored::streamName( int index ) { APPListIterator iter (*streamList); StreamNode **stream; for (int i = 0; i < index; i++) stream = iter( ); if (stream) return std::string( (*stream)->name ); else return NULL; } // This class takes a name of a module and a path and returns // a bool if that path was queried at this event bool APPStored::moduleQueried( std::string moduleName, std::string pathName ) { APPListIterator iter ( *pathList ); PathNode **path; ModNode **mod; // Loop over all paths while ( path = iter( ) ) { std::string name( (*path)->name ); // Get the path name APPListIterator iter2 ( *((*path)->mods) ); // loop over all modules while ( mod = iter2( ) ) { std::string mName( (*mod)->name ); // Get the module name // See if this is the module we want if ( mName == moduleName && name == pathName) return (*mod)->query; } } // We can't find the module return 0; } // This method takes the name of a module and a path and // returns a bool if that module passed this current event. // It returns a zero if it can't find it bool APPStored::modulePassed( std::string moduleName, std::string pathName ) { APPListIterator iter ( *pathList ); PathNode **path; ModNode **mod; // Loop over all paths while ( path = iter( ) ) { std::string name( (*path)->name ); // Get the path name APPListIterator iter2 ( *((*path)->mods) ); // loop over all modules while ( mod = iter2( ) ) { std::string mName( (*mod)->name ); // Get the module name // See if this is the module we want if ( mName == moduleName && name == pathName) return (*mod)->passed; } } // We can't find the module return 0; } // This method takes the name of a module and a path and // returns a bool if that module executed this current event. // It returns a zero if it can't find it bool APPStored::moduleExecuted( std::string moduleName, std::string pathName ) { APPListIterator iter ( *pathList ); PathNode **path; ModNode **mod; // Loop over all paths while ( path = iter( ) ) { std::string name( (*path)->name ); // Get the path name APPListIterator iter2 ( *((*path)->mods) ); // loop over all modules while ( mod = iter2( ) ) { std::string mName( (*mod)->name ); // Get the module name // See if this is the module we want if ( mName == moduleName && name == pathName) return (*mod)->executed; } } // We can't find the module return 0; } // This method adds the current events cpu Time for each // module to the total cpuTime for each module void APPStored::storeTime( ) { APPListIterator iter ( *pathList ); PathNode** path; int i = 0; // Loop over all paths while ( path = iter( ) ) { APPListIterator iter2 ( *((*path)->mods) ); ModNode** mod; // Loop over all modules while ( mod = iter2( ) ) { // store the cpuTime cpuTime[i++] += (*mod)->cpuTime; } } }