/* * asymRootFile.hh * * Created on: October 30, 2025 * Author: Hovanes Egiyan * * Modified on: * */ #ifndef ASYMROOTFILE_HH_ #define ASYMROOTFILE_HH_ #include #include #include #include #include #include #include #include #include "asymRootRecord.hh" using namespace std; class asymRootFile: public TFile { public: // Exception to throw when TTree creation failed class CreateTreeException { private: string msg; public: CreateTreeException( string errMsg ) : msg( errMsg ) { ; } ~CreateTreeException() { ; } string GetMessage() { return this->msg; } }; // Exception to throw when TBranch creation failed class CreateBranchException { private: string msg; public: CreateBranchException( string errMsg ) : msg( errMsg ) { ; } ~CreateBranchException() { ; } string GetMessage() { return this->msg; } }; private: map prfTree; // Map of the trees map prfBuffer; // Pointers to the buffers asymRootFile( const asymRootFile& file ) : // Cannot use copy constructor TFile() { MayNotUse( "asymRootFile::asymRootFile(const asymRootFile& file" ); } public: static UInt_t prfTreeBuffSize; // Buffer size for the tree static UInt_t prfAutoSaveSize; // Autosave size for the tree static string prfBranchName; // Name of the only branch on the tree asymRootFile( const char* fname, Option_t* option = "", const char* ftitle = "", Int_t compress = 1 ) : TFile( fname, option, ftitle, compress ) { ; } virtual ~asymRootFile() { // Class Destructor } ; virtual void Close(); // Close the file void CreateTree( string treeName, int nElm = 0 ); // Create tree void FillTree( string treeName, asymRootRecord& record ); // Fill the tree with a single record inline TTree* GetTree( string treeName ) { // Return the pointer to the tree if ( prfTree.count( treeName ) > 0 ) return prfTree[treeName]; return 0; } }; void asymRootFile::Close() { // write ROOT trees for ( map::iterator it = prfTree.begin(); it != prfTree.end(); it++ ) { it->second->Write( "", TObject::kOverwrite ); } // free buffer for ( map::iterator it = prfBuffer.begin(); it != prfBuffer.end(); it++ ) { if ( it->second != 0 ) free( it->second ); } TFile::Close(); return; } void asymRootFile::CreateTree( string treeName, int nElm ) { // throw exception if the tree already exists if ( this->Get( treeName.c_str() ) != 0 ) { string errMsg = "Object " + treeName + " already exists in file " + this->GetName(); cerr << errMsg << endl; throw asymRootFile::CreateTreeException( errMsg ); } // Create a ROOT tree with requested name this->cd(); prfTree[treeName] = new TTree( treeName.c_str(), "ASYM records" ); prfTree[treeName]->SetAutoSave( prfAutoSaveSize ); // throw exception if the tree cannot be created if ( prfTree[treeName] == 0 ) { string errMsg = "Could not create the ROOT Tree "; cerr << errMsg << endl; throw asymRootFile::CreateTreeException( errMsg ); } // Allocate memory for the buffer for the tree unsigned neededSpace = sizeof(__time_t) + sizeof(long int) + nElm * sizeof(long int) + sizeof(short) + 2*sizeof(float); prfBuffer[treeName] = malloc( neededSpace ); char leafList[50]; sprintf( leafList, "tsec/I:tnsec/I:data[%d]/I:delay/S:frequency/F:stableTime/F", nElm ); TBranch* br = prfTree[treeName]->Branch( prfBranchName.c_str(), prfBuffer[treeName], leafList, prfTreeBuffSize ); // throw exception if the branch cannot be created if ( br == 0 ) { string errMsg = "Could not create ROOT Tree Branch " + prfBranchName; cerr << errMsg << endl; throw asymRootFile::CreateBranchException( errMsg ); } return; } void asymRootFile::FillTree( string treeName, asymRootRecord& record ) { // If the tree does not exist or the buffer area does not exist create the tree if ( this->Get( treeName.c_str() ) == 0 || prfBuffer.count( treeName ) == 0 ) { this->CreateTree( treeName, record.GetData().GetSize() ); } record.CopyToBuffer( prfBuffer[treeName] ); prfTree[treeName]->Fill(); return; } #endif /* ASYMROOTFILE_HH_ */