// // DEventSourceROOT methods // #include #include #include #include using namespace std; #include #include #include #include #include #include #include "DEventSourceROOT.h" #include "FCAL/DFCALHit.h" //---------------- // Constructor //---------------- DEventSourceROOT::DEventSourceROOT( const char* source_name ) : JEventSource( source_name ) { // Open ROOT file and get pointer to TTree TThread::Lock(); tree = NULL; file = new TFile( source_name ); if(!file)return; // Get the TTree TObject *obj = (TObject*)file->Get( "FCALTree" ); if( obj ){ tree = dynamic_cast(obj); } // Set up branch addresses if( tree ){ tree->SetBranchAddress( "n_ExCells", &n_ExCells ); tree->SetBranchAddress( "row_No", row ); tree->SetBranchAddress( "column_No", column ); tree->SetBranchAddress( "n_Photons", n_Photons ); tree->SetBranchAddress( "dep_Energy", dep_Energy ); } TThread::UnLock(); } //---------------- // Destructor //---------------- DEventSourceROOT::~DEventSourceROOT() { // Close file if( tree ) delete tree; if( file ) delete file; } //---------------- // GetEvent //---------------- jerror_t DEventSourceROOT::GetEvent(JEvent &event) { /// Implementation of JEventSource::GetEvent function // For this source we do not do optimize too much. Each // request will read in the event from the file and // grab out the info. Specifically, if TDC and ADC info // are requested, it will read the event in twice from // the ROOT file. While this wastes some time, it is simple // to write and this source is not expected to be used too // terribly much. // Event number is not kept in file. Just keep a counter int event_number = ++Nevents_read; int run_number = 100; // Check that event is in range TThread::Lock(); int Nentries = tree->GetEntries(); TThread::UnLock(); if(Nevents_read>Nentries)return NO_MORE_EVENTS_IN_SOURCE; // Copy the reference info into the JEvent object event.SetJEventSource(this); event.SetEventNumber(event_number); event.SetRunNumber(run_number); event.SetRef((void*)(Nevents_read-1)); return NOERROR; } //---------------- // FreeEvent //---------------- void DEventSourceROOT::FreeEvent(JEvent &event) { // Don't need to free anything } //---------------- // GetObjects //---------------- jerror_t DEventSourceROOT::GetObjects(JEvent &event, JFactory_base *factory) { /// This gets called through the virtual method of the /// JEventSource base class. It creates the objects of the type /// on which factory is based. // As stated above, this is not done in the most efficient way. // Read in the entire event and extract the desired info from it. // We must have a factory to hold the data if( !factory ) throw RESOURCE_UNAVAILABLE; // Don't support tagged factories if( strcmp( factory->Tag(), "") ) return OBJECT_NOT_AVAILABLE; // The ref field of the JEvent is just the event number.(starting from 0) int eventNo = (int)event.GetRef(); if( !tree ) throw RESOURCE_UNAVAILABLE; // Figure out what type of data is being requested JFactory *fcalHit = dynamic_cast*>(factory); if( fcalHit ) return Extract_DFCALHit( eventNo, fcalHit ); return OBJECT_NOT_AVAILABLE; } //---------------- // Extract_DFCALHit //---------------- jerror_t DEventSourceROOT::Extract_DFCALHit(int eventNo, JFactory *fac) { if(!fac)return OBJECT_NOT_AVAILABLE; vector data; // Read in the event TThread::Lock(); tree->GetEntry( eventNo ); for( int i = 0; i < n_ExCells; ++i ){ float x = 4.0 + ( column[i] - 1 ) + 2.0; float y = 4.0 + ( row[i] - 1 ) + 2.0; DFCALHit* hit = new DFCALHit( i, x, y, dep_Energy[i], 0 ); data.push_back( hit ); } TThread::UnLock(); fac->CopyTo( data ); return NOERROR; }