Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

ntupleWriterSvc.cxx

Go to the documentation of this file.
00001 
00002 #include "GaudiKernel/SvcFactory.h"
00003 #include "GaudiKernel/MsgStream.h"
00004 
00005 #include "GaudiKernel/Incident.h"
00006 #include "GaudiKernel/IIncidentSvc.h"
00007 #include "GaudiKernel/Property.h"
00008 
00009 #include "GaudiKernel/INTuple.h"
00010 #include "GaudiKernel/NTuple.h"
00011 #include "GaudiKernel/SmartDataPtr.h"
00012 #include "GaudiKernel/StatusCode.h"
00013 
00014 #include "ntupleWriterSvc/ntupleWriterSvc.h"
00015 
00016 #include <string>
00017 #include <vector>
00018 #include <stdlib.h>
00019 
00020 #ifdef WIN32
00021 #include <float.h> // used to check for NaN
00022 #else
00023 #include <math.h>
00024 #endif
00025 
00026 // Storage location for ntuples within the TDS
00027 static std::string tupleRoot("/NTUPLES/");
00028 
00029 // A value to insert into the ntuple when NaN or inf is
00030 // passed in to be written
00031 static float badValue = -99999.0;
00032 
00033 unsigned int ntupleWriterSvc::m_tupleCounter;
00034 
00035 // declare the service factories for the ntupleWriterSvc
00036 static SvcFactory<ntupleWriterSvc> a_factory;
00037 const ISvcFactory& ntupleWriterSvcFactory = a_factory;
00038 
00039 
00040 // ------------------------------------------------
00041 // Implementation of the ntupleWriterSvc class
00042 // ------------------------------------------------
00044 ntupleWriterSvc::ntupleWriterSvc(const std::string& name,ISvcLocator* svc)
00045 : Service(name,svc)
00046 {
00047     
00048     // declare the properties and set defaults
00049     declareProperty("tuple_name",  m_tuple_name);
00050 
00051     m_tupleCounter = 0;  // initialize the count to 0;
00052 }
00053 
00054 
00055 // initialize
00056 StatusCode ntupleWriterSvc::initialize () 
00057 {
00058     StatusCode  status =  Service::initialize ();
00059      
00060     // bind all of the properties for this service
00061     setProperties ();
00062     
00063     // open the message log
00064     MsgStream log( msgSvc(), name() );
00065  
00066     // use the incident service to register "end" events
00067     IIncidentSvc* incsvc = 0;
00068     status = serviceLocator()->getService ("IncidentSvc",
00069         IID_IIncidentSvc, reinterpret_cast<IInterface*&>( incsvc ));
00070     
00071     if( status.isFailure() ) return status;
00072 
00073     incsvc->addListener(this, "BeginEvent", 100);
00074     incsvc->addListener(this, "EndEvent", 0);
00075 
00076     // get a pointer to the Gaudi NTupleSvc
00077     status = serviceLocator()->getService("NTupleSvc", 
00078         IID_INTupleSvc, reinterpret_cast<IInterface*&>( ntupleSvc));
00079 
00080     if( status.isFailure() ) {
00081         log << MSG::ERROR << "ntupleWriterSvc failed to get the NTupleSvc" << endreq;
00082         return status;
00083     }
00084 
00085     // Storing the number of events to be generated in the TNtuple title
00086     IProperty* glastPropMgr=0;
00087     status = serviceLocator()->getService("ApplicationMgr", IID_IProperty,
00088                          reinterpret_cast<IInterface*&>( glastPropMgr ));
00089     if( status.isFailure() ) return status;
00090       
00091     IntegerProperty evtMax("EvtMax",0);
00092     status = glastPropMgr->getProperty( &evtMax );
00093     if (status.isFailure()) return status;
00094     
00095     // setup the title
00096     std::string title("gen(");
00097     char numEventsStr[20];
00098     _itoa(evtMax, numEventsStr, 10);
00099     title += numEventsStr;
00100     title += ")";
00101 
00102     // Setup the ntuples asked for in the job options file
00103     int index = 0;
00104     for (index = 0; index < m_tuple_name.size(); index++) {
00105         ++m_tupleCounter;
00106         // store the id for this ntuple
00107         m_TDS_tuple_name.push_back("/");
00108         // convert the id number into a string and append to the path name
00109         char tdsName[5];
00110         _itoa(m_tupleCounter, tdsName, 10);
00111         m_TDS_tuple_name[index] += tdsName;
00112 
00113         // Try to book the ntuple
00114         if( !m_tuple_name[index].empty() ) {
00115             // add this path into the map
00116             m_tuples[m_tuple_name[index]] = (tupleRoot+m_tuple_name[index]+m_TDS_tuple_name[index]);
00117             // create the ntuple
00118             status = bookNTuple(index, title.c_str());
00119         } else {
00120             log << MSG::INFO << "No tuple name supplied, no ntuple created "<< endreq;
00121         }
00122     }
00123 
00124     m_storeFlag = true;
00125 
00126     return status;
00127 }
00128 
00129 
00130 StatusCode ntupleWriterSvc::bookNTuple(int index, const char* title) {
00131 
00132     StatusCode sc = StatusCode::SUCCESS;
00133     MsgStream log(msgSvc(), name());
00134 
00135     if (!m_tuple_name[index].empty()) {
00136         m_fileName.push_back(tupleRoot+m_tuple_name[index]);
00137 
00138         NTupleDirPtr dir(ntupleSvc, m_fileName[index]);
00139         if( dir ) {
00140             NTuplePtr *m_nt = new NTuplePtr( dir, m_TDS_tuple_name[index].c_str()); 
00141             if(!(*m_nt)){
00142                 (*m_nt) = ntupleSvc->book(m_fileName[index],(index+1),CLID_RowWiseTuple, title);
00143             } else {
00144                 log << MSG::ERROR  << "could not book Ntuple" << endreq;
00145             }
00146         } else {
00147             log << MSG::ERROR << "NTUPLE directory could not be created " << endreq;
00148         }   
00149     }
00150 
00151     log << MSG::INFO << "Booked the ntuple " << m_fileName[index] << m_TDS_tuple_name[index] << endreq;
00152     return sc;
00153 }
00154 
00155 
00156 
00157 
00158 // handle "incidents"
00159 void ntupleWriterSvc::handle(const Incident &inc)
00160 {
00161     if(inc.type()=="BeginEvent") beginEvent();
00162     if(inc.type()=="EndEvent") endEvent();
00163 }
00164 
00165 void ntupleWriterSvc::beginEvent()
00166 {
00168     storeRowFlag(true);
00169 }
00170 
00171 void ntupleWriterSvc::endEvent()  // must be called at the end of an event to update, allow pause
00172 {            
00173     
00174     StatusCode  sc = StatusCode::SUCCESS;
00175     MsgStream   log( msgSvc(), name() );
00176 
00177     if (m_storeFlag == false) return;
00178     
00179     // fill and write out the Gaudi tuple   
00180     int index = 0;
00181     for (index = 0; index < m_tuple_name.size(); index++) {
00182         sc = writeNTuple(index);
00183         if (sc.isFailure()) log << MSG::ERROR << "Could not write out ntuple " << (index+1) << endreq;
00184     }
00185    
00186 }
00187 
00188 StatusCode ntupleWriterSvc::writeNTuple(int index) {
00189     StatusCode  sc = StatusCode::SUCCESS;
00190     
00191     MsgStream log(msgSvc(), name());
00192     
00193     sc = ntupleSvc->writeRecord(m_fileName[index]+m_TDS_tuple_name[index]);
00194 
00195     log << MSG::INFO << "Wrote this event to the ntuple " << m_fileName[index] << m_TDS_tuple_name[index] << endreq;
00196     return sc;
00197 }
00198 
00199 StatusCode ntupleWriterSvc::saveNTuples() {
00200 
00201     MsgStream log(msgSvc(), name());
00202     StatusCode sc;
00203 
00204     unsigned int index = 0;
00205     for (index = 0; index < m_tuple_name.size(); index++) {
00206         sc = ntupleSvc->save(m_fileName[index]+m_TDS_tuple_name[index]);
00207     }
00208     log << MSG::INFO << "Saving ntuples to disk" << endreq;
00209     return sc;
00210 }
00211 
00212 // finalize
00213 StatusCode ntupleWriterSvc::finalize ()
00214 {
00215     StatusCode  status = StatusCode::SUCCESS;
00216        
00217     status = saveNTuples();
00218     return status;
00219 }
00221 StatusCode ntupleWriterSvc::queryInterface(const IID& riid, void** ppvInterface)  {
00222   if ( IID_INTupleWriterSvc.versionMatch(riid) )  {
00223     *ppvInterface = (INTupleWriterSvc*)this;
00224   }
00225   else  {
00226     return Service::queryInterface(riid, ppvInterface);
00227   }
00228   addRef();
00229   return SUCCESS;
00230 }
00231 
00232 SmartDataPtr<NTuple::Tuple> ntupleWriterSvc::getNTuple(const char *tupleName) {
00233     SmartDataPtr<NTuple::Tuple> m_nt(ntupleSvc, m_tuples[tupleName]);
00234     return m_nt;
00235 }
00236 
00237 StatusCode ntupleWriterSvc::addValue(const char *tupleName, const char *item, double val) {
00238     StatusCode sc = StatusCode::SUCCESS;
00239     MsgStream log(msgSvc(), name());
00240 
00241     SmartDataPtr<NTuple::Tuple> m_nt(ntupleSvc, m_tuples[tupleName]);
00242 
00243     NTuple::Item<float> ntItem;
00245     sc = m_nt->item(item, ntItem);
00246     if (sc != StatusCode::SUCCESS) {
00247         log << MSG::ERROR << "failed to retrieve our ntuple item " << endreq;
00248         return sc;
00249     }
00250     if (!isFinite(val)) {
00251         log << MSG::INFO << "Attempt to add a non-finite value into " << item << ", inserting -99999.0 instead." << endreq;
00252         ntItem = badValue;
00253     } else {
00254         ntItem = val;
00255     }
00256 
00257     return sc;
00258 }
00259 
00260 
00261 StatusCode ntupleWriterSvc::addItem(const char *tupleName, const char *item, double val) {
00262 
00263     StatusCode sc = StatusCode::SUCCESS;
00264     MsgStream log(msgSvc(), name());
00265 
00266     SmartDataPtr<NTuple::Tuple> m_nt(ntupleSvc, m_tuples[tupleName]);
00267 
00268     if (m_nt) {
00269         NTuple::Item<float> ntItem;
00270         // Check to see if this item has already been added into the ntuple
00271         sc = m_nt->item(item, ntItem);
00272         if (sc.isFailure()) {
00273             log << MSG::INFO << "Adding a new item to the ntuple " << item << endreq;
00274             m_nt->addItem(item, ntItem);
00275             if (!isFinite(val)) {
00276                 log << MSG::INFO << "Attempt to add a non-finite value into " << item << ", inserting -99999.0 instead" << endreq;
00277                 ntItem = badValue;
00278             } else {
00279                 ntItem = val;
00280             }
00281             sc = StatusCode::SUCCESS;
00282         } else {
00283             // Otherwise, this item is already in the ntuple and we are adding a new row
00284             return addValue(tupleName, item, val);
00285         }
00286     } else {
00287         return StatusCode::FAILURE;
00288     }
00289 
00290     return sc;
00291 }
00292 
00293 int ntupleWriterSvc::isFinite(float val) {
00294 
00295 #ifdef WIN32 
00296     return (_finite(val));  // Win32 call available in float.h
00297 #else
00298     return (isfinite(val)); // gcc call available in math.h
00299 #endif
00300 
00301 }

Generated at Wed Nov 21 12:20:37 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000