#include "geometry/Chamber.hh"
#include "geometry/Board.hh"
#include "geometry/Chip.hh"
#include "geometry/Channel.hh"
#include "geometry/Dif.hh"
#include "geometry/Detector.hh"
#include "event/Run.hh"
#include "event/Event.hh"
#include "parser/AcquisitionParser.hh"
#include "parser/Centaure.hh"
#include "parser/Hardroc1Reader.hh"
#include "parser/Hardroc2XdaqReader.hh"
#include "parser/Hardroc2LabviewReader.hh"
#include "parser/MicrorocLabviewReader.hh"
#include "parser/MicrorocXDaqReader.hh"
#include "parser/DifSynchroReader.hh"
#include "parser/DiracReader.hh"
#include "parser/DiracLabview.hh"
#include "parser/CalibHR1Parser.hh"
#include "parser/CalibHR2Parser.hh"
#include "parser/CalibMicrorocParser.hh"
#include "parser/TestMicrorocParser.hh"
#include "xml/XMLTool.hh"
#include "tools/Log.hh"
#include "tools/MicroException.hh"
#include "tools/Arguments.hh"
#include "MTEvent.hh"
#include "MTRun.hh"
#include "slowControl/SlowControlManager.hh"
#include "slowControl/SlowControlEntry.hh"
#include "mysql/Mysql.hh"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <stdlib.h>
#include "TFile.h"
#include "TTree.h"
#include "IO/LCWriter.h"
#include "IMPL/LCRunHeaderImpl.h"
#include "IMPL/LCEventImpl.h"
#include "IMPL/LCTOOLS.h"
#include "lcio/MLcio.hh"
Include dependency graph for reconstruction.cpp:
Go to the source code of this file.
Functions | |
int | main (int argc, char **argv) |
int main | ( | int | argc, | |
char ** | argv | |||
) |
Definition at line 64 of file reconstruction.cpp.
00065 { 00066 string steerName; 00067 00068 00069 // set verbose level 00070 FILELog::ReportingLevel() = FILELog::FromString(INFO); 00071 00072 ui32 slowcontrolNotFound = 0; 00073 ui32 eventNotValid = 0; 00074 00075 //----- Control usage and option 00076 Arguments arg(argc,argv,"reconstruction steerfile.xml type(root|lcio) [-r runId] [-l nbEvent] -dif[id1,id2,...] [-sql 1] [-forceanalog 1] [-q 1] [-batch 1] [-v(ERROR || WARNING || INFO || DEBUG || DEBUG1)]"); 00077 00078 if ( arg.getNbOfArgs() != 2) { // steerfile.xml type 00079 arg.usage(); 00080 exit(1); 00081 } 00082 // Get command parameter : here steering file 00083 steerName.assign(arg.getArgument(1)); 00084 00085 string outputType = arg.getArgument(2); 00086 00087 bool outputLcio = true; 00088 if ( outputType.compare("root") == 0 ) 00089 { 00090 outputLcio = false; 00091 } 00092 00093 00094 bool batch = false; 00095 if ( arg.getOption("-batch").size() != 0 ) 00096 { 00097 if ( atoi(arg.getOption("-batch").c_str()) == 1) 00098 { 00099 cout << "Batch mode" << endl; 00100 batch = true; 00101 } 00102 } 00103 00104 if ( arg.getOption("-v").size() != 0 ) 00105 { 00106 cout << "VERBOSE LEVEL: " << arg.getOption("-v") << endl; 00107 FILELog::ReportingLevel() = FILELog::FromString(arg.getOption("-v")); 00108 } 00109 00110 bool sql = false; 00111 if ( arg.getOption("-sql").size() != 0 ) 00112 { 00113 cout << "Mysql database will be updated" << endl; 00114 sql = true; 00115 } 00116 ui32 limitEvent = 0; 00117 string sLimitEvent; 00118 bool limit = false; 00119 if ( arg.getOption("-l").size() != 0 ) 00120 { 00121 limitEvent = atoi(arg.getOption("-l").c_str()); 00122 sLimitEvent = arg.getOption("-l"); 00123 limit = true; 00124 FILE_LOG(logINFO) <<"Number of reconstruct event is limited to " << limitEvent << endl; 00125 } 00126 00127 set<unsigned int>*difList = NULL; 00128 if ( arg.getOption("-dif").size() != 0 ) 00129 { 00130 difList = new set<unsigned int>(); 00131 string sdifList = arg.getOption("-dif"); 00132 string difId; 00133 stringstream stream(sdifList); 00134 cout <<"Create hit only for following dif: " ; 00135 while( getline(stream, difId, ',') ) 00136 { 00137 difList->insert(atoi(difId.c_str())); 00138 cout << atoi(difId.c_str()) << ", "; 00139 } 00140 cout << endl; 00141 } 00142 00143 // Add by Renaud to limit warnings during microroc qualifaction (no database is used) 00144 bool is_qualification = false; 00145 if ( arg.getOption("-q").size() != 0 ) 00146 { 00147 is_qualification = true; 00148 } 00149 00150 /* alow to create analog hits event if no digital hit correspond. Warning hit will have no bcid information 00151 // http://lappwiki01.in2p3.fr/Linear_Collider_LAPP/index.php/MicromegasFramework#Reconstruction_de_la_lecture_analogique_avec_les_Microroc 00152 */ 00153 bool forceAnalog = false; 00154 if ( arg.getOption("-forceanalog").size() != 0 ) 00155 { 00156 forceAnalog = true; 00157 } 00158 00159 string svnVersion = "0"; 00160 // test if steer file exist 00161 FILE *file = fopen(steerName.c_str(), "r"); 00162 if(file == NULL){ 00163 FILE_LOG(logERROR) << "Steer file ["<< steerName.c_str() << "] does not exist" << endl; 00164 exit(1); 00165 fclose(file); 00166 } 00167 else 00168 { 00169 // create Run, set detector and steerDesc from steer XML file 00170 SteerDesc steerDesc; 00171 XMLTool xml; 00172 xml.parse(steerDesc, steerName); // parse steer file and fill steerDesc 00173 00174 fclose(file); 00175 00176 string slowControlPath = steerDesc.getSlowControlPath(); 00177 SlowControlManager sc; 00178 sc.build(steerDesc); 00179 sc.readDB(slowControlPath); 00180 00181 FILE_LOG(logINFO) << "slowControl entries:[" << sc.getNbEntries() << "]" << endl; 00182 00183 TFile *hfile = NULL; 00184 MTEvent *rootEvt = NULL; 00185 00186 LCWriter* lcWrt = NULL; 00187 LCRunHeaderImpl* runHdr = NULL ; 00188 00189 if ( outputLcio ) 00190 { 00191 runHdr = new LCRunHeaderImpl() ; 00192 00193 string detName("micromegas_m2") ; 00194 runHdr->setDetectorName( detName ) ; 00195 00196 string ecalName("m2") ; 00197 runHdr->addActiveSubdetector( ecalName ) ; 00198 00199 string telName("telecsope") ; 00200 runHdr->addActiveSubdetector( telName ) ; 00201 // add some parameters to the run header 00202 runHdr->parameters().setValue( "cerate lcio for micromegas" , "lcioTest.cc" ) ; 00203 IntVec iv(3) ; 00204 iv[0] = 1 ; 00205 iv[1] = 2 ; 00206 iv[2] = 3 ; 00207 runHdr->parameters().setValues( "SomeIndices" , iv ) ; 00208 runHdr->parameters().setValues( "SomeOtherIndices" , iv ) ; 00209 } 00210 else 00211 { 00212 string rootFile = "default.root"; 00213 if ( steerDesc.outputFile.length() != 0) { rootFile = steerDesc.outputFile; } 00214 hfile = new TFile(rootFile.data(),"RECREATE","Micromegas LAPP"); 00215 00216 // Start ROOT tree filling 00217 rootEvt = new MTEvent(); // MTEvent is a Root base class which can be write to a ROOT File. 00218 } 00219 unsigned int totalNbEvents = 0; 00220 unsigned int totalNbHits = 0; 00221 unsigned int totalNbEventPerRawFile = 0; 00222 UInt_t lastEventId = 0; 00223 // reconstruct event from input data files 00224 FILE_LOG(logINFO) << "Start reconstruction for " << steerName << "." << endl; 00225 FILE_LOG(logINFO) << "Output file " << steerDesc.outputFile << "." << endl; 00226 FILE_LOG(logINFO) << "Output format " << outputType << "." << endl; 00227 00228 Detector detector; 00229 if ( ! detector.build(steerDesc) == steerDesc.chambers.size() ) 00230 { 00231 FILE_LOG(logERROR) << "Geometry Error. Please check your XML file." << endl; 00232 exit(-1); 00233 } 00234 Run run(detector); 00235 svnVersion = run.getSvnrev(); 00236 if ( ! steerDesc.setRun(run)) // Set detector with xml file content 00237 { exit(1); } 00238 00239 // create the proper parser depending on file type 00240 const std::vector<input_info_t>* inputFiles = &(steerDesc.inputFiles); 00241 00242 ui16 nbFile = inputFiles->size(); 00243 for (int fileIndex = 0; fileIndex < nbFile; fileIndex++) 00244 { 00245 const input_info_t &inputInfo = inputFiles->at(fileIndex); 00246 std::string currentType = inputInfo.type; 00247 FILE *inputFile = fopen(inputInfo.path.data(),"rb"); 00248 if ( inputFile == NULL) 00249 { 00250 FILE_LOG(logERROR) << "Could not open " << inputInfo.path << endl; 00251 exit(1); 00252 continue; 00253 } 00254 00255 00256 FILE_LOG(logINFO) << "Open acquisition file: " << inputInfo.path << " of type:" << currentType << endl; 00257 AcquisitionParser *parser; 00258 00259 if (currentType == Centaure::type()) 00260 { 00261 parser = new Centaure(run, inputFile, lastEventId); 00262 } 00263 else if (currentType == Hardroc1Reader::type()) 00264 { 00265 parser = new Hardroc1Reader(run, inputFile, lastEventId); 00266 } 00267 else if (currentType == Hardroc2XdaqReader::type()) 00268 { 00269 parser = new Hardroc2XdaqReader(run, inputFile, lastEventId); 00270 } 00271 else if (currentType == Hardroc2LabviewReader::type()) 00272 { 00273 parser = new Hardroc2LabviewReader(run, inputFile, lastEventId); 00274 } 00275 else if (currentType == CalibHR1Parser::type()) 00276 { 00277 parser = new CalibHR1Parser(run, inputFile, lastEventId); 00278 } 00279 else if (currentType == CalibHR2Parser::type()) 00280 { 00281 parser = new CalibHR2Parser(run, inputFile, lastEventId); 00282 } 00283 else if (currentType == MicrorocLabviewReader::type()) 00284 { 00285 parser = new MicrorocLabviewReader(run, inputFile, lastEventId); 00286 } 00287 else if (currentType == CalibMicrorocParser::type()) 00288 { 00289 parser = new CalibMicrorocParser(run, inputFile, lastEventId); 00290 } 00291 else if (currentType == TestMicrorocParser::type()) 00292 { 00293 parser = new TestMicrorocParser(run, inputFile, lastEventId); 00294 } 00295 else if (currentType == DiracReader::type()) 00296 { 00297 parser = new DiracReader(run, inputFile, lastEventId); 00298 } 00299 else if (currentType == DiracLabview::type()) 00300 { 00301 parser = new DiracLabview(run, inputFile, lastEventId); 00302 } 00303 else if (currentType == DifSynchroReader::type()) 00304 { 00305 parser = new DifSynchroReader(run, inputFile, lastEventId); 00306 } 00307 else if (currentType == MicrorocXDaqReader::type()) 00308 { 00309 parser = new MicrorocXDaqReader(run, inputInfo.path.data(), lastEventId,forceAnalog, difList); 00310 } 00311 else if (currentType == "xdaqHR2") 00312 { 00313 parser = new MicrorocXDaqReader(run, inputInfo.path.data(), lastEventId,difList); 00314 } 00315 00316 else 00317 { // type non pris en charge 00318 FILE_LOG(logERROR) << "NOT SUPPORTED ---- type:" << currentType << endl; 00319 fclose(inputFile); 00320 continue; 00321 } 00322 00323 totalNbEventPerRawFile = 0; 00324 00325 unsigned int configNum = 1; 00326 Event *event = new Event(run); 00327 00328 ui16 parserResult = parser->getNextEvent(*event); 00329 while (parserResult == NEW_CONFIG) 00330 { 00331 size_t found=inputInfo.path.find_last_of("/\\"); 00332 string name = inputInfo.path.substr(found+1); 00333 string s = "chaine"; 00334 stringstream buffer; 00335 buffer << name << "_" << configNum ; 00336 00337 00338 TTree mt(buffer.str().c_str(),"MicroMegas event"); 00339 00340 if ( outputLcio ) 00341 { 00342 // create sio writer 00343 cout << " runHdr->setRunNumber[" << inputInfo.runId << "]" << endl; 00344 runHdr->setRunNumber(inputInfo.runId ) ; 00345 lcWrt = LCFactory::getInstance()->createLCWriter() ; 00346 string lcioFile = buffer.str(); 00347 lcWrt->open( lcioFile , LCIO::WRITE_NEW ) ; 00348 } 00349 else 00350 { 00351 // FILE_LOG(logINFO) << "Create new TTRee:["<< buffer.str() << "]" << endl; 00352 mt.SetMaxTreeSize(40000000000); // 40 GB 00353 mt.Branch("MTEvent",&rootEvt,16000,2);// second argument is class of evt!!! 00354 } 00355 00356 // now parse the whole file 00357 // now fill the run structure 00358 // mtRun = run; 00359 configNum++; 00360 00361 parserResult = parser->getNextEvent(*event); 00362 00363 run.setRawDataFilename(inputInfo.path); 00364 MTRun mtRun(run); 00365 00366 while (parserResult == EVENT_CORRECT ) // && ( !limit || totalNbEventPerRawFile < limitEvent )) 00367 { 00368 try 00369 { 00370 if ( sc.getNbEntries() > 0 ) 00371 { 00372 const double evTimeStamp = event->getTimeStamp(); 00373 try 00374 { 00375 const SlowControlEntry* slowcontrolEntry = sc.getEntry(evTimeStamp); 00376 event->setSlowControlParam(slowcontrolEntry); 00377 } 00378 catch ( MicroException e) 00379 { 00380 FILE_LOG(logWARNING) << e.getMessage() << endl; 00381 slowcontrolNotFound++; 00382 } 00383 } 00384 if ( ! outputLcio ) 00385 { 00386 *rootEvt=*event; // ! surcharge operator= 00387 } 00388 totalNbHits = totalNbHits + event->getChannelHitSize(); 00389 00390 if ( event->getId() % 1== 0) 00391 { 00392 if ( batch ) 00393 { 00394 FILE_LOG(logINFO ) << "Write Event[" << event->getId() << "] total number of reconstruted event' hits[" << event->getChannelHitSize() << "] valid[" << event->getValidFlag() << "]" << endl; 00395 } 00396 else 00397 { 00398 if ( event->getValidFlag() != VALID ) 00399 { 00400 FILE_LOG(logINFO ) << "Write Event[" << event->getId()-1 << "] total number of reconstruted event' hits[" << event->getChannelHitSize() << "] !!! not valid, FLAG[" << event->getValidFlag() << "]" << endl; 00401 } 00402 else 00403 { 00404 FILE_LOG(logINFO ) << "Write Event[" << event->getId()-1 << "] total number of reconstruted event' hits[" << event->getChannelHitSize() << "]\t\t\t\t\t\t\t\t\t\t\t\r" << flush; 00405 } 00406 } 00407 if ( event->getValidFlag() != VALID ) { eventNotValid++; } 00408 00409 } 00410 00411 lastEventId = event->getId(); 00412 00413 if ( outputLcio ) 00414 { 00415 // write the event to the file 00416 LCEventImpl* lcioEvtImpl = new LCEventImpl(); 00417 MLcio::setLCEventImp(*lcioEvtImpl,*event); 00418 lcWrt->writeEvent( lcioEvtImpl ) ; 00419 // dump the event to the screen 00420 //LCTOOLS::dumpEvent( lcioEvtImpl ) ; 00421 // ------------ IMPORTANT ------------- ! 00422 // we created the event so we need to delete it ... 00423 delete lcioEvtImpl ; 00424 } 00425 00426 else 00427 { 00428 mt.Fill(); // Fill the TTree 00429 rootEvt->Clear(); // free memory 00430 } 00431 totalNbEvents++; 00432 totalNbEventPerRawFile++; 00433 00434 } 00435 catch (MicroException e) { FILE_LOG(logWARNING) << e.getMessage() << endl; } 00436 // Save all objects in this file 00437 delete event; 00438 if ( !limit || totalNbEventPerRawFile < limitEvent ) 00439 { 00440 event = new Event(run); 00441 parserResult = parser->getNextEvent(*event); 00442 } 00443 else 00444 { 00445 parserResult = LAST_FILE_EVENT; 00446 } 00447 } // end for Events 00448 00449 if ( outputLcio ) 00450 { 00451 lcWrt->close() ; 00452 delete lcWrt; 00453 } 00454 else if ( sql ) 00455 { 00456 // get Run fronm database 00457 Mysql mysql; 00458 const input_info_t &inputInfo = inputFiles->at(0); 00459 string full = inputInfo.path.data(); 00460 size_t last_slash = full.find_last_of("/") +1 ; 00461 string name = full.substr(last_slash); 00462 string path = full.substr(0,last_slash-1); 00463 ui32 runId = mysql.getRunIdFromRawFile(path,name); 00464 if ( runId != UNDEFINED_ID ) 00465 { 00466 mtRun.SetRunId(runId); 00467 FILE_LOG(logINFO) << "Set Run Id from database[" << runId << "]" << endl; 00468 } 00469 } 00470 mt.GetUserInfo()->Add(&mtRun); // store run information in a TLIst a mt TTree 00471 TFile *curFile =mt.GetCurrentFile() ; 00472 curFile->Write("", TObject::kOverwrite); 00473 00474 run.setDataFormat(0); 00475 } 00476 00477 // free the memory and close the file 00478 delete parser; 00479 fclose(inputFile); 00480 FILE_LOG(logINFO) << endl << "-- " << inputInfo.path.data() << 00481 " Number of reconstructed Events:[" << totalNbEventPerRawFile << "]" << endl << endl; 00482 } // end for file index 00483 00484 00485 00486 FILE_LOG(logINFO) << endl << "----- Total number of reconstructed Events:[" << totalNbEvents << "]" << endl; 00487 FILE_LOG(logINFO) << endl << "----- Total number of Hits:[" << totalNbHits << "]" << endl; 00488 00489 if ( sql) 00490 { 00491 Mysql mysql; 00492 // Add reconstruction software in DB if not already exist 00493 FILE_LOG(logINFO) << " mysql.add reconstruction software to DB (" << svnVersion << "]" << endl; 00494 int softId = mysql.addReconstructionSoftware(svnVersion); 00495 00496 // Add reconstruct file 00497 string fullName = steerDesc.outputFile ; 00498 size_t last_slash = fullName.find_last_of("/") +1 ; 00499 string name = fullName.substr(last_slash); 00500 string path = fullName.substr(0,last_slash); 00501 string comment = "No comment."; 00502 if ( limitEvent != 0 ) { comment = "Reconstrcuted event limited to " + sLimitEvent + "." ; } 00503 i16 rebuildId = mysql.addRebuildFile(softId,path, name, true, totalNbEvents , totalNbHits, true, comment ); 00504 00505 // Get Raw file database Id if they are already existing 00506 for (int fileIndex = 0; fileIndex < inputFiles->size(); fileIndex++) 00507 { 00508 const input_info_t &inputInfo = inputFiles->at(fileIndex); 00509 string full = inputInfo.path.data(); 00510 size_t last_slash = full.find_last_of("/") +1 ; 00511 string name = full.substr(last_slash); 00512 string path = full.substr(0,last_slash-1); 00513 try 00514 { 00515 ui32 rawId = mysql.getRawFileId(path,name); 00516 mysql.connectRebuildAndRawFile(rawId,rebuildId); 00517 } 00518 catch ( MicroException e ) 00519 { 00520 if (is_qualification == false) 00521 FILE_LOG(logWARNING) << "Raw file[" << path + name << "] not registerd in database." << endl; 00522 } 00523 } 00524 } 00525 /* 00526 The default value for AutoSave is to save a copy of the Tree header 00527 as soon as you have written 100 Mbytes (uncompressed) to the file. 00528 When AutoSave is called, a new key is created with the current header. 00529 If the creation of the key is successful, the previous key is deleted. 00530 At the end of the job, when you do tree.Write, a new key is 00531 always created, keeping the previous cycle of the same key, if any. 00532 You can use the option kOverwrite when calling the final tree.Write 00533 if you want to keep one single key. 00534 */ 00535 if ( ! outputLcio ) 00536 { 00537 hfile->Close(); 00538 } 00539 FILE_LOG(logINFO) << "Number of slowcontrol data not found:" << slowcontrolNotFound << endl; 00540 FILE_LOG(logINFO) << "Number of non valid event: " << eventNotValid << endl; 00541 } 00542 00543 return 0; 00544 }