00001
00008
00009 #include "GaudiKernel/MsgStream.h"
00010 #include "GaudiKernel/AlgFactory.h"
00011 #include "GaudiKernel/IDataProviderSvc.h"
00012 #include "GaudiKernel/SmartDataPtr.h"
00013 #include "GaudiKernel/Algorithm.h"
00014 #include "GaudiKernel/ISvcLocator.h"
00015
00016
00017 #include "ntupleWriterSvc/INTupleWriterSvc.h"
00018
00019
00020 #include "AnalysisNtuple/IValsTool.h"
00021
00022
00023 #include "GlastSvc/GlastDetSvc/IGlastDetSvc.h"
00024
00025 #include "Event/TopLevel/EventModel.h"
00026 #include "Event/TopLevel/Event.h"
00027
00028 #include <algorithm>
00029
00030
00035 class NtupleVisitor : virtual public IValsTool::Visitor
00036 {
00037 public:
00039 NtupleVisitor(INTupleWriterSvc* ntupleSvc=0, std::string ntupleName="")
00040 : m_ntupleSvc(ntupleSvc), m_ntupleName(ntupleName) {}
00041
00042
00043
00044 virtual IValsTool::Visitor::eVisitorRet
00045 analysisValue(std::string varName, const double& value) const;
00046 virtual IValsTool::Visitor::eVisitorRet
00047 analysisValue(std::string varName, const float& value) const;
00048 virtual IValsTool::Visitor::eVisitorRet
00049 analysisValue(std::string varName, const int& value) const;
00050 virtual IValsTool::Visitor::eVisitorRet
00051 analysisValue(std::string varName, const unsigned int& value) const;
00052 virtual IValsTool::Visitor::eVisitorRet
00053 analysisValue(std::string varName, const unsigned long long& value) const;
00054 virtual IValsTool::Visitor::eVisitorRet
00055 analysisValue(std::string varName, const char* value) const;
00056 virtual ~NtupleVisitor() {}
00057
00058 private:
00060 INTupleWriterSvc* m_ntupleSvc;
00062 std::string m_ntupleName;
00063 };
00064
00065
00066
00067 IValsTool::Visitor::eVisitorRet NtupleVisitor::analysisValue(std::string varName,
00068 const double& value) const
00069 {
00070 StatusCode sc;
00071 if (m_ntupleSvc) {
00072 sc = m_ntupleSvc->addItem(m_ntupleName, varName, &value );
00073 if (sc.isFailure()) return IValsTool::Visitor::ERROR;
00074 }
00075 return IValsTool::Visitor::CONT;
00076 }
00077
00078 IValsTool::Visitor::eVisitorRet NtupleVisitor::analysisValue(std::string varName,
00079 const float& value) const
00080 {
00081 StatusCode sc;
00082 if (m_ntupleSvc) {
00083 sc = m_ntupleSvc->addItem(m_ntupleName, varName, &value );
00084 if (sc.isFailure()) return IValsTool::Visitor::ERROR;
00085 }
00086 return IValsTool::Visitor::CONT;
00087 }
00088
00089 IValsTool::Visitor::eVisitorRet NtupleVisitor::analysisValue(std::string varName,
00090 const int& value) const
00091 {
00092 StatusCode sc;
00093 if (m_ntupleSvc) {
00094 sc = m_ntupleSvc->addItem(m_ntupleName, varName, &value );
00095 if (sc.isFailure()) return IValsTool::Visitor::ERROR;
00096 }
00097 return IValsTool::Visitor::CONT;
00098 }
00099
00100 IValsTool::Visitor::eVisitorRet NtupleVisitor::analysisValue(std::string varName,
00101 const unsigned int& value) const
00102 {
00103 StatusCode sc;
00104 if (m_ntupleSvc) {
00105 sc = m_ntupleSvc->addItem(m_ntupleName, varName, &value );
00106 if (sc.isFailure()) return IValsTool::Visitor::ERROR;
00107 }
00108 return IValsTool::Visitor::CONT;
00109 }
00110
00111
00112 IValsTool::Visitor::eVisitorRet NtupleVisitor::analysisValue(std::string varName,
00113 const unsigned long long& value) const
00114 {
00115 StatusCode sc;
00116 if (m_ntupleSvc) {
00117 sc = m_ntupleSvc->addItem(m_ntupleName, varName, &value );
00118 if (sc.isFailure()) return IValsTool::Visitor::ERROR;
00119 }
00120 return IValsTool::Visitor::CONT;
00121 }
00122
00123 IValsTool::Visitor::eVisitorRet NtupleVisitor::analysisValue(std::string varName,
00124 const char* value) const
00125 {
00126 StatusCode sc;
00127 if (m_ntupleSvc) {
00128 sc = m_ntupleSvc->addItem(m_ntupleName, varName, value );
00129 if (sc.isFailure()) return IValsTool::Visitor::ERROR;
00130 }
00131 return IValsTool::Visitor::CONT;
00132 }
00133
00139 class AnalysisNtupleAlg : public Algorithm {
00140 public:
00141 AnalysisNtupleAlg(const std::string& name, ISvcLocator* pSvcLocator);
00143 StatusCode initialize();
00145 StatusCode execute();
00147 StatusCode finalize();
00148
00149 private:
00151 void fixLoadOrder();
00152 void removeMc();
00153 void printHeader(MsgStream& log);
00154
00156 double m_count;
00157
00159 INTupleWriterSvc *m_ntupleSvc;
00161 std::string m_tupleName;
00162
00164 std::vector<IValsTool*> m_toolvec;
00166 std::vector<std::string> m_toolnames;
00168 bool m_doNtuple;
00169 bool m_doDebug;
00170 bool m_countCalcs;
00171 bool m_realData;
00172
00173 IDataProviderSvc* m_pEventSvc;
00174
00175 IValsTool::Visitor* m_visitor;
00176 };
00177
00178 static const AlgFactory<AnalysisNtupleAlg> Factory;
00179 const IAlgFactory& AnalysisNtupleAlgFactory = Factory;
00180
00181 AnalysisNtupleAlg::AnalysisNtupleAlg(const std::string& name, ISvcLocator* pSvcLocator)
00182 :Algorithm(name, pSvcLocator)
00183 ,m_count(0)
00184 {
00185
00186 declareProperty("tupleName", m_tupleName="MeritTuple");
00187
00188
00189
00190 declareProperty("toolList", m_toolnames);
00191 declareProperty("doNtuple", m_doNtuple=true);
00192 declareProperty("enableDebugCalc", m_doDebug=false);
00193 declareProperty("countCalcs", m_countCalcs=false);
00194 declareProperty("realData", m_realData=false);
00195 }
00196
00197 StatusCode AnalysisNtupleAlg::initialize(){
00198 StatusCode sc = StatusCode::SUCCESS;
00199 StatusCode fail = StatusCode::FAILURE;
00200
00201 MsgStream log(msgSvc(), name());
00202 log << MSG::INFO << "initialize" << endreq;
00203
00204
00205
00206
00207 m_toolnames.clear();
00208
00209 setProperties();
00210
00211
00212
00213 std::string toolnames [] = {"Mc", "Glt", "Acd", "TkrHit", "Tkr", "Vtx", "Cal", "Evt", "Obf", "McTkrHit", ""};
00214 unsigned int i;
00215 unsigned int namesSize = m_toolnames.size();
00216
00217
00218 if(m_toolnames.empty()) {
00219 for (i=0; ; ++i) {
00220 if (toolnames[i]=="") break;
00221 m_toolnames.push_back(toolnames[i]);
00222 }
00223
00224 } else if (m_toolnames.size()>0&&m_toolnames[0]!="+") {
00225 for (i=0; i<namesSize; ++i) {
00226 m_toolnames[i] = m_toolnames[i];
00227 }
00228
00229 } else if (namesSize>1&&m_toolnames[0]=="+") {
00230 m_toolnames.erase(m_toolnames.begin());
00231
00232 namesSize = m_toolnames.size();
00233 for (i=0; i<namesSize; ++i) {
00234 m_toolnames[i] = m_toolnames[i];
00235 }
00236
00237 for (i=0; ; ++i) {
00238 if (toolnames[i]=="") break;
00239 m_toolnames.push_back(toolnames[i]);
00240 }
00241 }
00242
00243 log << MSG::INFO << endreq;
00244 namesSize = m_toolnames.size();
00245 log << MSG::INFO << namesSize << " Tools requested: ";
00246 for (i=0; i<namesSize; ++i) {
00247 log << m_toolnames[i]+"ValsTool" << " " ;
00248 }
00249 log << endreq;
00250
00251 if( m_tupleName.empty()) {
00252 log << MSG::INFO << "tupleName property not set! No ntuple output"<<endreq;
00253 }
00254
00255 IToolSvc* pToolSvc = 0;
00256
00257 sc = service("ToolSvc", pToolSvc, true);
00258 if (!sc.isSuccess ()){
00259 log << MSG::ERROR << "Can't find ToolSvc, will quit now" << endreq;
00260 return StatusCode::FAILURE;
00261 }
00262
00263
00264
00265 fixLoadOrder();
00266
00267
00268
00269
00270 if(m_realData) removeMc();
00271
00272 namesSize = m_toolnames.size();
00273 for (i =0; i!=namesSize; ++i){
00274 m_toolvec.push_back(0);
00275 m_toolnames[i]+="ValsTool";
00276 sc = pToolSvc->retrieveTool(m_toolnames[i], m_toolvec.back());
00277 m_toolvec.back()->setLoadOrder(i);
00278 if( sc.isFailure() ) {
00279 log << MSG::ERROR << "Unable to find tool: "
00280 << m_toolnames[i] << endreq;
00281 return sc;
00282 }
00283 }
00284
00285
00286 m_ntupleSvc = 0;
00287 if (!m_tupleName.empty()&& m_doNtuple) {
00288 if (service("RootTupleSvc", m_ntupleSvc, true).isFailure()) {
00289 log << MSG::ERROR
00290 << "AnalysisNtupleAlg failed to get the RootTupleSvc"
00291 << endreq;
00292 return fail;
00293 }
00294 }
00295
00296 m_visitor = new NtupleVisitor(m_ntupleSvc, m_tupleName);
00297
00298 if (!m_tupleName.empty() && m_doNtuple) {
00299
00300 int size = m_toolvec.size();
00301 for( int i =0; i<size; ++i){
00302 if(m_toolvec[i]->traverse(m_visitor, false)==IValsTool::Visitor::ERROR) {
00303 log << MSG::ERROR << m_toolvec[i] << " traversal failed" << endreq;
00304 return fail;
00305 }
00306 }
00307 IDataProviderSvc* eventsvc = 0;
00308 sc = serviceLocator()->service( "EventDataSvc", eventsvc, true );
00309 if(sc.isFailure()){
00310 log << MSG::ERROR << "Could not find EventDataSvc" << std::endl;
00311 return sc;
00312 }
00313 m_pEventSvc = eventsvc;
00314
00315 }
00316
00317 return sc;
00318 }
00319
00320 StatusCode AnalysisNtupleAlg::execute()
00321 {
00322 StatusCode sc = StatusCode::SUCCESS;
00323
00324
00325 MsgStream log( msgSvc(), name() );
00326
00327 bool countCalc = m_countCalcs;
00328
00329
00330 ++m_count;
00331 m_ntupleSvc->storeRowFlag(m_tupleName, true);
00332
00333
00334 int toolCounter = 0;
00335 bool isException = false;
00336 std::vector<IValsTool*>::iterator i = m_toolvec.begin();
00337 for( ; i != m_toolvec.end(); ++i, ++toolCounter){
00338 try {
00339 (*i)->doCalcIfNotDone();
00340 } catch( std::exception& e) {
00341 printHeader(log);
00342 log << "Non-propagator exception from " << m_toolnames[toolCounter]<< endreq;
00343 log << e.what() << endreq;
00344 } catch (...) {
00345 printHeader(log);
00346 log << "Non-propagator exception from " << m_toolnames[toolCounter]<< endreq;
00347 isException = true;
00348 }
00349 }
00350 if(isException) {
00351
00352 SmartDataPtr<Event::EventHeader> header(m_pEventSvc, EventModel::EventHeader);
00353 if (header) header->setAnalysisNtupleError();
00354
00355 for(i=m_toolvec.begin() ; i != m_toolvec.end(); ++i){
00356 (*i)->zeroVals();
00357 }
00358 return sc;
00359 }
00360
00361
00362
00364
00365 bool debugStuff = m_doDebug;
00366
00367 if (countCalc || debugStuff) {
00368 if (m_count < 5) {
00369 log << MSG::INFO << "number of calculations per event: " << endreq;
00370 unsigned int i;
00371 for(i =0; i<m_toolvec.size(); ++i){
00372 log << MSG::INFO << m_toolnames[i] << ": " << m_toolvec[i]->getCalcCount()<< endreq;
00373 }
00374 log << MSG::INFO << endreq;
00375 }else {
00376 log << MSG::INFO << "call count message suppressed. " << endreq;
00377 }
00378 }
00379
00380 if(debugStuff) {
00381
00382 int namesSize = m_toolnames.size();
00383 int i;
00384
00385
00386
00387 for (i=0;i<namesSize; ++i) {
00388 log << MSG::INFO << "Dump of variables in " << m_toolnames[i] << endreq;
00389 m_toolvec[i]->browse(log);
00390 }
00391
00392 std::string varname;
00393 std::vector<std::string> varnames;
00394 varnames.clear();
00395 for (i=0; i<namesSize; ++i) {
00396 std::string toolname = m_toolnames[i];
00397 if (toolname=="McValsTool" ) {varname = "McXErr";}
00398 else if (toolname=="GltValsTool" ) {varname = "GltTotal";}
00399 else if (toolname=="TkrHitValsTool" ) {varname = "TkrHitsInLyr00";}
00400 else if (toolname=="TkrValsTool" ) {varname = "TkrSumKalEne";}
00401 else if (toolname=="VtxValsTool" ) {varname = "VtxZDir";}
00402 else if (toolname=="CalValsTool" ) {varname = "CalEnergyRaw";}
00403 else if (toolname=="CalMipValsTool" ) {varname = "CalMipNum";}
00404
00405
00406 else if (toolname=="AcdValsTool" ) {varname = "AcdTileCount";}
00407 else if (toolname=="EvtValsTool" ) {varname = "EvtEnergyRaw";}
00408 else if (toolname=="McAnalValsTool" ) {varname = "McaPrmEnegy";}
00409 else {varname = "";}
00410 varnames.push_back(varname);
00411 }
00412
00413
00414
00415 int vecSize = m_toolvec.size();
00416 for(i=0; i<vecSize; ++i){
00417 varname = varnames[i];
00418 if (varname=="") continue;
00419 std::string answerString;
00420 sc = m_toolvec[i]->getVal(varname, answerString, NOCALC);
00421 log << MSG::INFO << varname << " = " << answerString << " " << endreq;
00422 m_toolvec[i]->browse(log, varnames[i]);
00423 }
00424 }
00425 log << MSG::DEBUG;
00426 if (log.isActive()) {
00427 log << MSG::DEBUG << "number of calculations per event: " << endreq;
00428 unsigned int i;
00429 for(i =0; i<m_toolvec.size(); ++i){
00430 log << MSG::DEBUG << m_toolnames[i] << ": " << m_toolvec[i]->getCalcCount()<< endreq;
00431 }
00432 }
00433 log << endreq;
00434 return sc;
00435 }
00436
00437 StatusCode AnalysisNtupleAlg::finalize(){
00438 StatusCode sc = StatusCode::SUCCESS;
00439 MsgStream log(msgSvc(), name());
00440 log << MSG::INFO << "finalize after " << m_count << " calls." << endreq;
00441
00442 return sc;
00443 }
00444
00445 void AnalysisNtupleAlg::fixLoadOrder()
00446 {
00447 MsgStream log(msgSvc(), name());
00448 std::vector<std::string>::iterator tkrIter, acdIter, endIter;
00449
00450 tkrIter = find(m_toolnames.begin(), m_toolnames.end(), "Tkr");
00451 acdIter = find(m_toolnames.begin(), m_toolnames.end(), "Acd");
00452 endIter = m_toolnames.end();
00453
00454 if(acdIter!=endIter&&tkrIter!=endIter&&acdIter-tkrIter>0) {
00455 m_toolnames.erase(acdIter);
00456 m_toolnames.insert(tkrIter, "Acd");
00457 log << MSG::WARNING << endreq <<
00458 "Load order of ValsTools changed" << endreq
00459 << "AcdValsTool inserted beforeTkrValsTool" << endreq;
00460 unsigned int i;
00461 unsigned int namesSize = m_toolnames.size();
00462 log << MSG::WARNING << "New order: " << endreq;
00463 for (i=0; i<namesSize; ++i) {
00464 log << m_toolnames[i]+"ValsTool" << " " ;
00465 }
00466 log << endreq;
00467 }
00468 }
00469
00470 void AnalysisNtupleAlg::removeMc()
00471 {
00472 MsgStream log(msgSvc(), name());
00473 std::vector<std::string>::iterator endIter, lastIter, listIter, thisIter, mckIter;
00474 mckIter = find(m_toolnames.begin(), m_toolnames.end(), "McKludge");
00475 endIter = m_toolnames.end();
00476 lastIter = endIter;
00477 --lastIter;
00478
00479 for(listIter=lastIter; listIter!=--m_toolnames.begin(); --listIter) {
00480 if(*listIter=="Mc") {
00481 thisIter = m_toolnames.erase(listIter);
00482 if(mckIter==endIter) { m_toolnames.insert(thisIter, "McKludge");}
00483 } else if (listIter->find("Mc")!=std::string::npos) {
00484 m_toolnames.erase(listIter);
00485 }
00486 }
00487 unsigned int namesSize = m_toolnames.size();
00488 unsigned int i;
00489 log << MSG::WARNING << endreq <<
00490 "Real Data Run: Mc tools removed or modified" << endreq
00491 << "Final Order: " << endreq;
00492 for (i=0; i<namesSize; ++i) {
00493 log << m_toolnames[i]+"ValsTool" << " " ;
00494 }
00495 log << endreq;
00496
00497 log << endreq;
00498 return;
00499 }
00500
00501 void AnalysisNtupleAlg::printHeader(MsgStream& log)
00502 {
00503 SmartDataPtr<Event::EventHeader> header(m_pEventSvc, EventModel::EventHeader);
00504 unsigned long evtId = (header) ? header->event() : 0;
00505 long runId = (header) ? header->run() : -1;
00506 log << MSG::WARNING << "Caught exception (run,event): ( "
00507 << runId << ", " << evtId << " ) " << endreq;
00508 }