00001
00002 #include <map>
00003 #include <stdlib.h>
00004 #include <string>
00005 #include <set>
00006 #include <list>
00007 #include "TKey.h"
00008 #include <TRint.h>
00009 #include <TKey.h>
00010 #include <TTree.h>
00011 #include <TFile.h>
00012 #include <TChain.h>
00013 #include <iostream>
00014 #include <sstream>
00015 #include "tools/Log.hh"
00016 #include "tools/Toolbox.hh"
00017
00018 #include "root/MTRun.hh"
00019 #include "root/MTChannel.hh"
00020 #include "root/MTEvent.hh"
00021
00022
00023
00024 #include <string>
00025
00026 #include "MicroException.hh"
00027
00028 #include "mysql/Mysql.hh"
00029
00030
00031
00032 #define GLOBALTRIGGER 1
00033 #define DIFSYNCHRO 2
00034
00035 using namespace std;
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 int merge(TString rootFileName);
00056
00057 bool FillEvent(const MTEvent& evt, MTEvent* mergedEvt)
00058 {
00059
00060
00061 mergedEvt->SetTemperature(evt.GetTemperature());
00062 mergedEvt->SetPressure(evt.GetPressure());
00063 mergedEvt->SetDifSynchro(evt.GetDifSynchro());
00064 mergedEvt->SetTimestamp(evt.GetTimestamp());
00065 mergedEvt->SetGlobalTriggerCounter(evt.GetGlobalTriggerCounter());
00066
00067 const std::map<UInt_t, std::map<UInt_t, std::map<UInt_t, Float_t>* >* >& meshs = evt.GetMeshVoltage();
00068
00069 for ( std::map<UInt_t, std::map<UInt_t, std::map<UInt_t, Float_t>* >* >::const_iterator iterChamber = meshs.begin(); iterChamber != meshs.end(); iterChamber++)
00070 {
00071 std::map<UInt_t, std::map<UInt_t, Float_t>* >&difContainer = *(iterChamber)->second;
00072 for ( std::map<UInt_t, std::map<UInt_t, Float_t>* >::const_iterator iterDif = difContainer.begin(); iterDif != difContainer.end(); iterDif++)
00073 {
00074 std::map<UInt_t, Float_t> &boardContainer = *(iterDif)->second;
00075 for ( std::map<UInt_t, Float_t>::const_iterator iterVoltage = boardContainer.begin(); iterVoltage != boardContainer.end(); iterVoltage++)
00076 {
00077 mergedEvt->SetMeshVoltage(iterChamber->first,iterDif->first,iterVoltage->first,iterVoltage->second);
00078 }
00079 }
00080
00081 }
00082
00083 const std::map<UInt_t, std::map<UInt_t, std::map<UInt_t, Float_t>* >* >& drifts = evt.GetDriftVoltage();
00084
00085 for ( std::map<UInt_t, std::map<UInt_t, std::map<UInt_t, Float_t>* >* >::const_iterator iterChamber = drifts.begin(); iterChamber != drifts.end(); iterChamber++)
00086 {
00087 std::map<UInt_t, std::map<UInt_t, Float_t>* >&difContainer = *(iterChamber)->second;
00088 for ( std::map<UInt_t, std::map<UInt_t, Float_t>* >::const_iterator iterDif = difContainer.begin(); iterDif != difContainer.end(); iterDif++)
00089 {
00090 std::map<UInt_t, Float_t> &boardContainer = *(iterDif)->second;
00091 for ( std::map<UInt_t, Float_t>::const_iterator iterVoltage = boardContainer.begin(); iterVoltage != boardContainer.end(); iterVoltage++)
00092 {
00093 mergedEvt->SetDriftVoltage(iterChamber->first,iterDif->first,iterVoltage->first,iterVoltage->second);
00094 }
00095 }
00096
00097 }
00098
00099
00100 }
00101
00102
00103
00104 bool FillChannels(const MTEvent& evt, list<MTChannel*>* hits)
00105 {
00106
00107 for(int i=0;i<evt.GetNchannel() ;i++)
00108 {
00109 MTChannel *channel = (MTChannel*)evt.GetChannels()->At(i);
00110
00111 MTChannel* tmpCh = new MTChannel();
00112
00113
00114 *tmpCh = *channel;
00115
00116 hits->push_back(tmpCh);
00117 }
00118
00119 return true;
00120 }
00121
00122
00123
00124 int main(int argc, char**argv){
00125
00126
00127
00128
00129 if ( argc < 3 || argc > 4 ) {
00130 FILE_LOG(logERROR) << "usage:" << endl;
00131 FILE_LOG(logERROR) << "-sort by globalTrigger: merge -g rootFile" << endl;
00132 FILE_LOG(logERROR) << "-sort by difSynchro : merge -d SlabsRootFile AHCALRootFile" << endl;
00133 exit(1);
00134 }
00135
00136
00137
00138 string opt;
00139 opt.assign(argv[1]);
00140 if ( opt.compare("-g") != 0 && opt.compare("-d") != 0 )
00141 {
00142 FILE_LOG(logERROR) << "usage: merge rootFile -g(globalTrigger) -d(difSynchro) " << endl;
00143 exit(-1);
00144 }
00145
00146 unsigned int criteria = GLOBALTRIGGER;
00147 string extension = "_MGT";
00148
00149 if ( opt.compare("-d") == 0 ) { criteria = DIFSYNCHRO; extension = "_MDS"; }
00150
00151
00152 vector<string> fileNames;
00153
00154 fileNames.push_back(argv[2]);
00155
00156 if ( criteria == DIFSYNCHRO )
00157 {
00158 if ( argc <4 )
00159 {
00160 FILE_LOG(logERROR) << "-sort by difSynchro : merge -d SlabsRootFile AHCALRootFile" << endl;
00161 exit(0);
00162 }
00163 fileNames.push_back(argv[3]);
00164 }
00165
00166
00167
00168
00169 vector<UInt_t> misses;
00170
00171
00172
00173 TTree* minEventTree = NULL;
00174 UInt_t minEventNum = 0xffffffff;
00175 UInt_t maxEventNum = 0x0;
00176 list<TTree*> trees;
00177 list<TFile*> files;
00178
00179 for ( vector<string>::iterator iterFile = fileNames.begin(); iterFile != fileNames.end(); iterFile++)
00180 {
00181 string rootName = *iterFile;
00182 TFile *f = new TFile(rootName.c_str(),"READONLY");
00183 files.push_back(f);
00184 TIter nextkey(f->GetListOfKeys());
00185 TKey *key;
00186
00187
00188 const MTEvent *evt = new MTEvent();
00189 ui32 lastTotalGlobalTrigerCounter = 0;
00190
00191
00192
00193 while (key = (TKey*)nextkey())
00194 {
00195 try
00196 {
00197 TTree* tmp = dynamic_cast<TTree*>(key->ReadObj());
00198 trees.push_back(tmp);
00199 cout << "Add TTree["<< tmp->GetName() <<"] with [" << tmp->GetEntries() << "] entries." << endl;
00200 if ( tmp->GetEntries() < minEventNum)
00201 {
00202 minEventNum = tmp->GetEntries() ;
00203 minEventTree = tmp;
00204 }
00205 TBranch *branch= tmp->GetBranch("MTEvent");
00206 branch->SetAddress(&evt);
00207
00208
00209 tmp->GetEntry(tmp->GetEntries()-1);
00210 if ( lastTotalGlobalTrigerCounter == 0 )
00211 {
00212 lastTotalGlobalTrigerCounter = evt->GetGlobalTriggerCounter();
00213 }
00214 else
00215 {
00216 if ( evt->GetGlobalTriggerCounter() != lastTotalGlobalTrigerCounter )
00217 {
00218 cout << "\n\n\n\n\n" << endl;
00219 FILE_LOG(logERROR) << " Last event of each TTree have not got the same GlobalTrigger counter value." << endl;
00220 FILE_LOG(logERROR) << " Synchronization failed. Data can not be merged" << endl;
00221 exit(-1);
00222 }
00223 }
00224 }
00225 catch (...) {}
00226 }
00227 }
00228
00229 if ( minEventTree != NULL )
00230 {
00231 cout << "Reference TTree[" << minEventTree->GetName() << "]" << endl;
00232 trees.remove(minEventTree);
00233 }
00234
00235 string mergeFileName = fileNames[0].substr(0,fileNames[0].find("root")-1)+extension.c_str() + ".root";
00236
00237 TFile *newFile = new TFile(mergeFileName.c_str(), "RECREATE");
00238 newFile->cd();
00239
00240 TTree* mergedTree = new TTree("mergedTTree","MicroMegas merged event");
00241
00242 cout << "Create new TFile for merge result[" <<mergeFileName << "]" << endl;
00243
00244
00245 MTEvent *mergedEvt = new MTEvent();
00246 if ( mergedTree->GetBranch("MTEvent") == 0)
00247 {
00248 mergedTree->Branch("MTEvent",mergedEvt);
00249 }
00250
00251
00252 TTree* refTree = minEventTree;
00253 MTRun * run = (MTRun*)refTree->GetUserInfo()->FindObject("MTRun");
00254 TString svnVersion;
00255 if ( run != NULL ) { svnVersion = run->GetSvnVersion();}
00256 mergedTree->GetUserInfo()->Add(run);
00257 int lastEventId = 0;
00258 ui32 nbchannelOrig = 0;
00259
00260 map<string , UInt_t> lastEventIdMap;
00261 UInt_t nbChannels = 0;
00262 for ( int evtNum = 0; evtNum < refTree->GetEntries() ; evtNum++)
00263 {
00264 mergedEvt->SetCrcIsCorrect(true);
00265 const MTEvent *evt = new MTEvent();
00266 TBranch *branch= refTree->GetBranch("MTEvent");
00267 branch->SetAddress(&evt);
00268 refTree->GetEntry(evtNum);
00269
00270 FillEvent(*evt,mergedEvt);
00271 mergedEvt->SetEventId(evtNum);
00272 if ( evt->GetCrcIsCorrect() == false )
00273 {
00274 mergedEvt->SetCrcIsCorrect(false);
00275 }
00276
00277 UInt_t globalTrigger = evt->GetGlobalTriggerCounter() ;
00278 ULong64_t difSynchro = evt->GetDifSynchro();
00279 UInt_t difTrigger = evt->GetDifTriggerCounter() ;
00280
00281
00282 list<MTChannel*>* hits = new list<MTChannel*>();
00283 FillChannels(*evt,hits);
00284
00285 nbchannelOrig = nbchannelOrig+evt->GetNchannel();
00286
00287 int evtNum2 = 0;
00288 for ( list<TTree*>::iterator iterTree = trees.begin(); iterTree != trees.end(); iterTree++)
00289 {
00290 TTree* tree = (TTree*)*iterTree;
00291 const MTEvent *evt = new MTEvent();
00292 TBranch *branch= tree->GetBranch("MTEvent");
00293 branch->SetAddress(&evt);
00294
00295 bool find = false;
00296 string treeName = string(tree->GetName());
00297
00298
00299 for ( evtNum2 = lastEventIdMap[treeName]; evtNum2< tree->GetEntries() ; evtNum2++)
00300 {
00301
00302
00303
00304
00305
00306 tree->GetEntry(evtNum2);
00307 if ( evt != NULL)
00308 {
00309 if ( ( criteria == GLOBALTRIGGER && evt->GetGlobalTriggerCounter() == globalTrigger )
00310 ||( criteria == DIFSYNCHRO && evt->GetDifSynchro() == difSynchro ))
00311 {
00312 find = true;
00313
00314
00315 FillChannels(*evt,hits);
00316 if ( evt->GetCrcIsCorrect() == false )
00317 {
00318 mergedEvt->SetCrcIsCorrect(false);
00319 }
00320
00321
00322
00323 break;
00324 }
00325 }
00326 }
00327 if ( ! find )
00328 {
00329 if ( criteria == GLOBALTRIGGER )
00330 {
00331
00332 misses.push_back(globalTrigger);
00333 }
00334 else if ( criteria == DIFSYNCHRO )
00335 {
00336 cout << "difSynchro[" << tree->GetName() << " " << difSynchro << "] not found" << endl;
00337 misses.push_back(difSynchro);
00338 }
00339 }
00340 else
00341 {
00342
00343 lastEventIdMap[treeName] = evtNum2;
00344 }
00345
00346 delete evt;
00347 }
00348
00349
00350 for ( list<MTChannel*>::iterator iterCh = hits->begin(); iterCh != hits->end(); iterCh++)
00351 {
00352 MTChannel* ch = *iterCh;
00353 mergedEvt->AddChannel(ch);
00354 }
00355 nbChannels = nbChannels + hits->size();
00356
00357
00358
00359 mergedTree->Fill();
00360 if ( evtNum % 1 == 0)
00361 {
00362 FILE_LOG(logINFO ) << "Done for entry " << evtNum +1 << " / " << refTree->GetEntries() << "\r" << flush;
00363 }
00364
00365
00366
00367 mergedEvt->SetNchannel(0);
00368 for ( list<MTChannel*>::iterator iterCh = hits->begin(); iterCh != hits->end(); iterCh++)
00369 {
00370
00371 delete (*iterCh) ;
00372 }
00373 delete hits;
00374 mergedEvt->Clear();
00375
00376
00377 delete evt;
00378 }
00379
00380 for ( list<TTree*>::iterator iterTree = trees.begin(); iterTree != trees.end(); iterTree++)
00381 {
00382 TTree* tree = (TTree*)*iterTree;
00383 MTRun * run = (MTRun*)tree->GetUserInfo()->FindObject("MTRun");
00384 mergedTree->GetUserInfo()->Add(run);
00385 }
00386
00387
00388
00389 mergedTree->Write("", TObject::kOverwrite);
00390 mergedTree->SetDirectory(0);
00391 newFile->Close();
00392
00393
00394
00395
00396 string comment = "No comment";
00397 bool behavior = true;
00398 if ( misses.size() > 0 )
00399 {
00400 behavior = false;
00401 string msg = "WARNING !!! Some event has not been merges. Find bellow list of criteria not found.";
00402 cout << msg << endl;
00403 comment = msg;
00404 for ( vector<UInt_t>::const_iterator iter = misses.begin(); iter != misses.end() ; iter++)
00405 {
00406 cout << "["<< *iter << "]";
00407 ostringstream out;
00408 out << *iter;
00409 string sIndex = out.str();
00410 msg = msg + "[" + sIndex + "]";
00411 }
00412 cout << endl;
00413 }
00414 cout << endl << "Done." << endl;
00415
00416
00417
00418 Mysql mysql;
00419
00420 string svn(svnVersion.Data());
00421 FILE_LOG(logINFO) << " mysql.add merge Software to DB (" << svn << "]" << endl;
00422 ui32 softId = mysql.addMergeSoftware(svn);
00423
00424
00425 size_t last_slash = mergeFileName.find_last_of("/") +1 ;
00426 string name = mergeFileName.substr(last_slash);
00427 string path = mergeFileName.substr(0,last_slash);
00428 int mergeId = mysql.addMergeFile(softId,path,name,behavior,refTree->GetEntries(),nbChannels,true,comment);
00429 cout << "mergeId[" << mergeId << "]" << endl;
00430
00431 for ( vector<string>::iterator iterFile = fileNames.begin(); iterFile != fileNames.end(); iterFile++)
00432 {
00433 string full = *iterFile;
00434 size_t last_slash = full.find_last_of("/") +1 ;
00435 string name = full.substr(last_slash);
00436 string path = full.substr(0,last_slash);
00437 try {
00438 ui32 rebuildId = mysql.getRebuildFile(path,name);
00439 mysql.connectMergeAndRebuildFile(rebuildId,mergeId);
00440 }
00441 catch ( MicroException e )
00442 {
00443 FILE_LOG(logWARNING) << "Rebuild file[" << path + name << "] not registerd in database." << endl;
00444 }
00445
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455 }