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>
00022 #else
00023 #include <math.h>
00024 #endif
00025
00026
00027 static std::string tupleRoot("/NTUPLES/");
00028
00029
00030
00031 static float badValue = -99999.0;
00032
00033 unsigned int ntupleWriterSvc::m_tupleCounter;
00034
00035
00036 static SvcFactory<ntupleWriterSvc> a_factory;
00037 const ISvcFactory& ntupleWriterSvcFactory = a_factory;
00038
00039
00040
00041
00042
00044
00045 : Service(name,svc)
00046 {
00047
00048
00049 declareProperty("tuple_name", m_tuple_name);
00050
00051 m_tupleCounter = 0;
00052 }
00053
00054
00055
00056 StatusCode ntupleWriterSvc::initialize ()
00057 {
00058 StatusCode status = Service::initialize ();
00059
00060
00061 setProperties ();
00062
00063
00064 MsgStream log( msgSvc(), name() );
00065
00066
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
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
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
00096 std::string title("gen(");
00097 char numEventsStr[20];
00098 _itoa(evtMax, numEventsStr, 10);
00099 title += numEventsStr;
00100 title += ")";
00101
00102
00103 int index = 0;
00104 for (index = 0; index < m_tuple_name.size(); index++) {
00105 ++m_tupleCounter;
00106
00107 m_TDS_tuple_name.push_back("/");
00108
00109 char tdsName[5];
00110 _itoa(m_tupleCounter, tdsName, 10);
00111 m_TDS_tuple_name[index] += tdsName;
00112
00113
00114 if( !m_tuple_name[index].empty() ) {
00115
00116 m_tuples[m_tuple_name[index]] = (tupleRoot+m_tuple_name[index]+m_TDS_tuple_name[index]);
00117
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
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()
00172 {
00173
00174 StatusCode sc = StatusCode::SUCCESS;
00175 MsgStream log( msgSvc(), name() );
00176
00177 if (m_storeFlag == false) return;
00178
00179
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
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
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
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));
00297 #else
00298 return (isfinite(val));
00299 #endif
00300
00301 }