| 1 | mocchiut | 1.1 | /** | 
| 2 |  |  | * \file RunGlue.cpp | 
| 3 |  |  | * \author Emiliano Mocchiutti | 
| 4 |  |  | * | 
| 5 |  |  | * The file contains implementation of the methods to query the DB. | 
| 6 |  |  | */ | 
| 7 |  |  | // | 
| 8 |  |  | #include <sstream> | 
| 9 |  |  | #include <iostream> | 
| 10 |  |  | // | 
| 11 |  |  | #include <TFile.h> | 
| 12 |  |  | #include <TTree.h> | 
| 13 |  |  | #include <TTimeStamp.h> | 
| 14 | mocchiut | 1.5 | #include <TTreeCloner.h> | 
| 15 | mocchiut | 1.1 | #include <RunGlue.h> | 
| 16 |  |  | // | 
| 17 |  |  | ClassImp(RunGlue); | 
| 18 |  |  | // | 
| 19 |  |  | using namespace std; | 
| 20 |  |  |  | 
| 21 |  |  | RunGlue::RunGlue() { | 
| 22 |  |  | this->Clear(); | 
| 23 |  |  | } | 
| 24 |  |  |  | 
| 25 |  |  | RunGlue::RunGlue(TSQLServer *da, UInt_t ru, TString di, TString wrkdi) { | 
| 26 |  |  | fDBG = false; | 
| 27 |  |  | li = new PamLevel2(); | 
| 28 |  |  | this->Clear(); | 
| 29 |  |  | dbc = da; | 
| 30 |  |  | run = ru; | 
| 31 |  |  | dir = di; | 
| 32 |  |  | // | 
| 33 |  |  | TString wd = gSystem->WorkingDirectory(); | 
| 34 |  |  | // | 
| 35 |  |  | outdir = wrkdi; | 
| 36 |  |  | if ( !strcmp(outdir.Data(),"") ) outdir = wd; | 
| 37 |  |  | fList = 0; | 
| 38 |  |  | if ( run ){ | 
| 39 |  |  | runmode = true; | 
| 40 |  |  | } else { | 
| 41 |  |  | runmode = false; | 
| 42 |  |  | createlist = true; | 
| 43 |  |  | }; | 
| 44 |  |  | // | 
| 45 |  |  | //  lList = new TList(); | 
| 46 |  |  | // | 
| 47 |  |  | }; | 
| 48 |  |  |  | 
| 49 |  |  |  | 
| 50 |  |  | void RunGlue::Clear() { | 
| 51 |  |  | fEnd = false; | 
| 52 |  |  | run = 0; | 
| 53 |  |  | dir = ""; | 
| 54 |  |  | outdir = ""; | 
| 55 |  |  | fFilename = ""; | 
| 56 |  |  | }; | 
| 57 |  |  |  | 
| 58 |  |  | void RunGlue::Clean() { | 
| 59 |  |  | if ( !merged ) gSystem->Unlink(fFilename); | 
| 60 |  |  | lList->Delete(); | 
| 61 |  |  | delete Target; | 
| 62 |  |  | }; | 
| 63 |  |  |  | 
| 64 |  |  | void RunGlue::SetDebug(Bool_t dbg) { | 
| 65 |  |  | fDBG = dbg; | 
| 66 |  |  | }; | 
| 67 |  |  |  | 
| 68 |  |  | void RunGlue::SetDList(TString list) { | 
| 69 |  |  | // | 
| 70 |  |  | RUN = true; | 
| 71 |  |  | // | 
| 72 |  |  | if (list.Contains("-RUN", TString::kIgnoreCase)) RUN = false; | 
| 73 |  |  | if (list.Contains("-ALL", TString::kIgnoreCase)) RUN = false; | 
| 74 |  |  | if (list.Contains("+RUN", TString::kIgnoreCase)) RUN = true; | 
| 75 |  |  | if (list.Contains("+ALL", TString::kIgnoreCase)) RUN = true; | 
| 76 |  |  | // | 
| 77 |  |  | fDList = list; | 
| 78 |  |  | li->SetWhichTrees(fDList); | 
| 79 |  |  | // | 
| 80 |  |  | if ( DebugMode() ) printf(" Detector list is %s \n",fDList.Data()); | 
| 81 |  |  | // | 
| 82 |  |  | }; | 
| 83 |  |  |  | 
| 84 |  |  | TList *RunGlue::GetRunList(){ | 
| 85 |  |  | // | 
| 86 |  |  | lList = new TList(); | 
| 87 |  |  | lList->Clear(); | 
| 88 |  |  | TString thisrun; | 
| 89 |  |  | TFile *su; | 
| 90 |  |  | // | 
| 91 |  |  | TSQLResult *pResult; | 
| 92 |  |  | TSQLRow *Row; | 
| 93 |  |  | // | 
| 94 |  |  | if ( run && runmode ){ | 
| 95 |  |  | // | 
| 96 |  |  | // Qurey the GL_RUN table to obtain RUN infos | 
| 97 |  |  | // | 
| 98 |  |  | GL_RUN *glrun = new GL_RUN(); | 
| 99 |  |  | glrun->Query_GL_RUN(run,dbc); | 
| 100 |  |  | // | 
| 101 |  |  | // convert RUNHEADER_TIME into a UTC date | 
| 102 |  |  | // | 
| 103 |  |  | GL_TIMESYNC *dbtime = new GL_TIMESYNC(); | 
| 104 |  |  | // | 
| 105 |  |  | TString UTC="UTC"; | 
| 106 |  |  | TString rhdate=dbtime->ConvertTime(UTC,glrun->RUNHEADER_TIME); | 
| 107 |  |  | // | 
| 108 |  |  | TDatime ti = TDatime(rhdate.Data()); | 
| 109 |  |  | // | 
| 110 |  |  | YY=(UInt_t)ti.GetYear(); | 
| 111 |  |  | MM=(UInt_t)ti.GetMonth(); | 
| 112 |  |  | DD=(UInt_t)ti.GetDay(); | 
| 113 |  |  | // | 
| 114 |  |  | TTimeStamp *llim = new TTimeStamp(YY,MM,DD,0,0,0,0,true,0); | 
| 115 |  |  | // | 
| 116 |  |  | UInt_t lowerlimit = llim->GetSec(); | 
| 117 |  |  | UInt_t upperlimit = lowerlimit + 86401; | 
| 118 |  |  | // | 
| 119 |  |  | if ( DebugMode() ) printf(" YY %u MM %u DD %u ll %u ul %u \n",YY,MM,DD,lowerlimit,upperlimit); | 
| 120 |  |  | // | 
| 121 |  |  | YY -= 2000; | 
| 122 |  |  | stringstream tmpf; | 
| 123 |  |  | tmpf.str(""); | 
| 124 |  |  | tmpf << "L2PAM"; | 
| 125 |  |  | if ( YY < 10 ){ | 
| 126 |  |  | tmpf<< "0" << YY; | 
| 127 |  |  | } else { | 
| 128 |  |  | tmpf<< YY; | 
| 129 |  |  | }; | 
| 130 |  |  | if ( MM < 10 ){ | 
| 131 |  |  | tmpf<< "0" << MM; | 
| 132 |  |  | } else { | 
| 133 |  |  | tmpf<< MM; | 
| 134 |  |  | }; | 
| 135 |  |  | if ( DD < 10 ){ | 
| 136 |  |  | tmpf << "0" << DD << ".root"; | 
| 137 |  |  | } else { | 
| 138 |  |  | tmpf << DD << ".root"; | 
| 139 |  |  | }; | 
| 140 |  |  | TString fpath = ""; | 
| 141 |  |  | if ( !strcmp(outdir,"") ){ | 
| 142 |  |  | fpath="./"; | 
| 143 |  |  | } else { | 
| 144 |  |  | fpath += outdir; | 
| 145 |  |  | fpath += "/"; | 
| 146 |  |  | }; | 
| 147 |  |  | // | 
| 148 |  |  | fFilename = fpath + tmpf.str().c_str(); | 
| 149 |  |  | // | 
| 150 |  |  | printf(" Output filename is %s \n",fFilename.Data()); | 
| 151 |  |  | // | 
| 152 | mocchiut | 1.4 | if ( !this->OpenFile() ){ | 
| 153 |  |  | fEnd = true; | 
| 154 |  |  | return(0); | 
| 155 |  |  | }; | 
| 156 |  |  | // | 
| 157 |  |  | stringstream myquery; | 
| 158 |  |  | myquery.str(""); | 
| 159 |  |  | myquery << "SELECT ID FROM GL_RUN WHERE RUNHEADER_TIME>=" << (UInt_t)lowerlimit | 
| 160 |  |  | << " AND RUNHEADER_TIME<" << (UInt_t)upperlimit << " ORDER BY RUNHEADER_TIME ASC;"; | 
| 161 |  |  | // | 
| 162 |  |  | pResult = dbc->Query(myquery.str().c_str()); | 
| 163 |  |  | for( UInt_t r=0; r < 1000; r++){ | 
| 164 |  |  | Row = pResult->Next(); | 
| 165 |  |  | if( Row == NULL ) break; | 
| 166 |  |  | if ( DebugMode() ) printf(" %u RUN %s \n",r,Row->GetField(0)); | 
| 167 |  |  | // | 
| 168 |  |  | thisrun=dir+(TString)Row->GetField(0)+".Level2.root"; | 
| 169 |  |  | // | 
| 170 |  |  | if ( DebugMode() ) printf(" Filename is %s \n",thisrun.Data()); | 
| 171 |  |  | // | 
| 172 |  |  | su = TFile::Open(thisrun); | 
| 173 |  |  | if ( li->CheckLevel2File(thisrun) ){ | 
| 174 |  |  | lList->Add(su); | 
| 175 |  |  | } else { | 
| 176 |  |  | if ( DebugMode() ) printf(" RUN %s DISCARDED \n",Row->GetField(0)); | 
| 177 |  |  | }; | 
| 178 |  |  | // | 
| 179 |  |  | }; | 
| 180 |  |  | // | 
| 181 |  |  | // | 
| 182 | mocchiut | 1.1 | delete glrun; | 
| 183 |  |  | delete dbtime; | 
| 184 |  |  | // | 
| 185 |  |  | }; | 
| 186 |  |  | // | 
| 187 |  |  | if ( strcmp(dir.Data(),"" )){ | 
| 188 |  |  | // | 
| 189 |  |  | if ( createlist ){ | 
| 190 |  |  | fList = new TList(); | 
| 191 |  |  | fDoneList = new TList(); | 
| 192 |  |  | fNlist = 0; | 
| 193 |  |  | fNlistdone = 0; | 
| 194 |  |  | // | 
| 195 |  |  | // read files in the directory | 
| 196 |  |  | // | 
| 197 |  |  | if ( DebugMode() ) printf("\n No input run given\n Check for existing root files. \n"); | 
| 198 |  |  | // | 
| 199 |  |  | TSystemDirectory *datadir = new TSystemDirectory(gSystem->BaseName(dir),dir); | 
| 200 |  |  | TList *temp = datadir->GetListOfFiles(); | 
| 201 |  |  | // | 
| 202 |  |  | TIter next(temp); | 
| 203 |  |  | TSystemFile *questo = 0; | 
| 204 |  |  | // | 
| 205 |  |  | while ( (questo = (TSystemFile*)next()) ) { | 
| 206 |  |  | TString name =  questo->GetName(); | 
| 207 |  |  | if( name.EndsWith(".Level2.root") ){ | 
| 208 |  |  | char *fullpath0; | 
| 209 |  |  | gSystem->IsFileInIncludePath(name,&fullpath0); | 
| 210 |  |  | TString fullpath = fullpath0; | 
| 211 |  |  | // | 
| 212 |  |  | if ( DebugMode() ) printf(" fullpath = %s     name %s \n",fullpath.Data(),name.Data()); | 
| 213 |  |  | // | 
| 214 |  |  | // | 
| 215 |  |  | su = TFile::Open(fullpath); | 
| 216 |  |  | if ( li->CheckLevel2File((TString)fullpath) ){ | 
| 217 |  |  | fList->Add(su); | 
| 218 |  |  | fNlist++; | 
| 219 |  |  | } else { | 
| 220 |  |  | if ( DebugMode() ) printf(" RUN %s DISCARDED \n",fullpath.Data()); | 
| 221 |  |  | }; | 
| 222 |  |  | // | 
| 223 |  |  | }; | 
| 224 |  |  | }; | 
| 225 |  |  | createlist = false; | 
| 226 |  |  | nrun = 0; | 
| 227 |  |  | }; | 
| 228 |  |  | // | 
| 229 |  |  | // | 
| 230 |  |  | // | 
| 231 |  |  | Bool_t stop = true; | 
| 232 |  |  | UInt_t drun = 0; | 
| 233 |  |  | while ( nrun < fNlist && stop ){ | 
| 234 |  |  | TString myrun = (TString)((TString)(gSystem->BaseName(((TFile*)fList->At(nrun))->GetName()))).ReplaceAll(".Level2.root",12,"",0); | 
| 235 |  |  | if ( DebugMode() ) printf(" nrun %u myrun is %s \n",nrun,(myrun.ReplaceAll(".Level2.root",12,"",0)).Data()); | 
| 236 |  |  | run = (UInt_t)(myrun.Atoi()); | 
| 237 |  |  | nrun++; | 
| 238 |  |  | // | 
| 239 |  |  | TString donerun = ""; | 
| 240 |  |  | for (UInt_t ll=0; ll<fNlistdone; ll++){ | 
| 241 |  |  | donerun = ""; | 
| 242 |  |  | donerun = (TString)((TString)(gSystem->BaseName(((TFile*)fDoneList->At(ll))->GetName()))).ReplaceAll(".Level2.root",12,"",0); | 
| 243 |  |  | if ( DebugMode() ) printf(" donerun is %s \n",(donerun.ReplaceAll(".Level2.root",12,"",0)).Data()); | 
| 244 |  |  | drun = (UInt_t)(donerun.Atoi()); | 
| 245 |  |  | // | 
| 246 |  |  | if ( run == drun ) goto jump; | 
| 247 |  |  | // | 
| 248 |  |  | }; | 
| 249 |  |  | // | 
| 250 |  |  | stop = false; | 
| 251 |  |  | // | 
| 252 |  |  | jump: | 
| 253 |  |  | drun = 0; | 
| 254 |  |  | // | 
| 255 |  |  | }; | 
| 256 |  |  | // | 
| 257 |  |  | if ( nrun >= fNlist && stop ){ | 
| 258 |  |  | fEnd = true; | 
| 259 |  |  | return(0); | 
| 260 |  |  | }; | 
| 261 |  |  | // | 
| 262 |  |  | // Qurey the GL_RUN table to obtain RUN infos | 
| 263 |  |  | // | 
| 264 |  |  | printf(" PROCESSING RUN %u AND ITS FRIENDS\n",run); | 
| 265 |  |  | GL_RUN *glrun = new GL_RUN(); | 
| 266 |  |  | glrun->Query_GL_RUN(run,dbc); | 
| 267 |  |  | // | 
| 268 |  |  | // convert RUNHEADER_TIME into a UTC date | 
| 269 |  |  | // | 
| 270 |  |  | GL_TIMESYNC *dbtime = new GL_TIMESYNC(); | 
| 271 |  |  | // | 
| 272 |  |  | TString UTC="UTC"; | 
| 273 |  |  | TString rhdate=dbtime->ConvertTime(UTC,glrun->RUNHEADER_TIME); | 
| 274 |  |  | // | 
| 275 |  |  | TDatime ti = TDatime(rhdate.Data()); | 
| 276 |  |  | // | 
| 277 |  |  | YY=(UInt_t)ti.GetYear(); | 
| 278 |  |  | MM=(UInt_t)ti.GetMonth(); | 
| 279 |  |  | DD=(UInt_t)ti.GetDay(); | 
| 280 |  |  | // | 
| 281 |  |  | TTimeStamp *llim = new TTimeStamp(YY,MM,DD,0,0,0,0,true,0); | 
| 282 |  |  | // | 
| 283 |  |  | UInt_t lowerlimit = llim->GetSec(); | 
| 284 |  |  | UInt_t upperlimit = lowerlimit + 86401; | 
| 285 |  |  | // | 
| 286 |  |  | if ( DebugMode() ) printf(" YY %u MM %u DD %u ll %u ul %u \n",YY,MM,DD,lowerlimit,upperlimit); | 
| 287 |  |  | // | 
| 288 |  |  | YY -= 2000; | 
| 289 |  |  | stringstream tmpf; | 
| 290 |  |  | tmpf.str(""); | 
| 291 |  |  | tmpf << "L2PAM"; | 
| 292 |  |  | if ( YY < 10 ){ | 
| 293 |  |  | tmpf<< "0" << YY; | 
| 294 |  |  | } else { | 
| 295 |  |  | tmpf<< YY; | 
| 296 |  |  | }; | 
| 297 |  |  | if ( MM < 10 ){ | 
| 298 |  |  | tmpf<< "0" << MM; | 
| 299 |  |  | } else { | 
| 300 |  |  | tmpf<< MM; | 
| 301 |  |  | }; | 
| 302 |  |  | if ( DD < 10 ){ | 
| 303 |  |  | tmpf << "0" << DD << ".root"; | 
| 304 |  |  | } else { | 
| 305 |  |  | tmpf << DD << ".root"; | 
| 306 |  |  | }; | 
| 307 |  |  | TString fpath = ""; | 
| 308 |  |  | if ( !strcmp(outdir,"") ){ | 
| 309 |  |  | fpath="./"; | 
| 310 |  |  | } else { | 
| 311 |  |  | fpath += outdir; | 
| 312 |  |  | fpath += "/"; | 
| 313 |  |  | }; | 
| 314 |  |  | // | 
| 315 |  |  | fFilename = fpath + tmpf.str().c_str(); | 
| 316 |  |  | // | 
| 317 |  |  | printf(" Output filename is %s \n",fFilename.Data()); | 
| 318 |  |  | // | 
| 319 | mocchiut | 1.4 | if ( !this->OpenFile() ) return(0); | 
| 320 |  |  | // | 
| 321 |  |  | stringstream myquery; | 
| 322 |  |  | myquery.str(""); | 
| 323 |  |  | myquery << "SELECT ID FROM GL_RUN WHERE RUNHEADER_TIME>=" << (UInt_t)lowerlimit | 
| 324 |  |  | << " AND RUNHEADER_TIME<" << (UInt_t)upperlimit << " ORDER BY RUNHEADER_TIME ASC;"; | 
| 325 |  |  | // | 
| 326 |  |  | pResult = dbc->Query(myquery.str().c_str()); | 
| 327 |  |  | for( UInt_t r=0; r < 1000; r++){ | 
| 328 |  |  | Row = pResult->Next(); | 
| 329 |  |  | if( Row == NULL ) break; | 
| 330 |  |  | if ( DebugMode() ) printf(" %u RUN %s \n",r,Row->GetField(0)); | 
| 331 |  |  | // | 
| 332 |  |  | thisrun=dir+(TString)Row->GetField(0)+".Level2.root"; | 
| 333 |  |  | // | 
| 334 |  |  | if ( DebugMode() ) printf(" Filename is %s \n",thisrun.Data()); | 
| 335 |  |  | // | 
| 336 |  |  | su = TFile::Open(thisrun); | 
| 337 |  |  | if ( su ){ | 
| 338 |  |  | TFile *su0 = TFile::Open(thisrun); | 
| 339 |  |  | fDoneList->Add(su0); | 
| 340 |  |  | fNlistdone++; | 
| 341 |  |  | }; | 
| 342 |  |  | if ( li->CheckLevel2File(thisrun) ){ | 
| 343 |  |  | lList->Add(su); | 
| 344 |  |  | if ( DebugMode() ) printf(" RUN %s ADDED \n",Row->GetField(0)); | 
| 345 |  |  | } else { | 
| 346 |  |  | if ( DebugMode() ) printf(" RUN %s DISCARDED \n",Row->GetField(0)); | 
| 347 |  |  | }; | 
| 348 |  |  | // | 
| 349 |  |  | }; | 
| 350 |  |  | // | 
| 351 | mocchiut | 1.1 | if ( DebugMode() ){ | 
| 352 |  |  | UInt_t ll = 0; | 
| 353 |  |  | while ( (TFile*)lList->At(ll) ){ | 
| 354 |  |  | TString donerun = ""; | 
| 355 |  |  | donerun = (TString)((TString)(gSystem->BaseName(((TFile*)lList->At(ll))->GetName()))).ReplaceAll(".Level2.root",12,"",0); | 
| 356 |  |  | printf(" XXX file is %s \n",donerun.Data()); | 
| 357 |  |  | ll++; | 
| 358 |  |  | // | 
| 359 |  |  | }; | 
| 360 |  |  | }; | 
| 361 |  |  | // | 
| 362 |  |  | delete glrun; | 
| 363 |  |  | delete dbtime; | 
| 364 |  |  | // | 
| 365 |  |  | }; | 
| 366 |  |  | // | 
| 367 |  |  | // is it the end? | 
| 368 |  |  | // | 
| 369 |  |  | if ( runmode ){ | 
| 370 |  |  | fEnd = true; | 
| 371 |  |  | } else { | 
| 372 |  |  | // | 
| 373 |  |  | // did we use all the run in the directory? if so exit | 
| 374 |  |  | // | 
| 375 |  |  | if ( nrun >= fNlist ) fEnd = true; | 
| 376 |  |  | }; | 
| 377 |  |  | // | 
| 378 |  |  | return(lList); | 
| 379 |  |  | }; | 
| 380 |  |  |  | 
| 381 |  |  | Bool_t RunGlue::OpenFile(){ | 
| 382 |  |  | // | 
| 383 | mocchiut | 1.4 | fOpen = false; | 
| 384 | mocchiut | 1.1 | printf(" Check if output file already exists \n"); | 
| 385 |  |  | Target = TFile::Open((this->GetFilename()).Data(), "READ" ); | 
| 386 |  |  | // | 
| 387 |  |  | if ( Target ){ | 
| 388 |  |  | Target->Close(); | 
| 389 |  |  | printf("Error opening target file, %s  already exist!\n",(this->GetFilename()).Data()); | 
| 390 |  |  | return(false); | 
| 391 |  |  | } else { | 
| 392 |  |  | // | 
| 393 |  |  | printf(" Output file does not exist, creating it\n"); | 
| 394 |  |  | // | 
| 395 | mocchiut | 1.5 | Long64_t maxsize = 99900000000LL; | 
| 396 | mocchiut | 1.1 | // | 
| 397 |  |  | Target = TFile::Open((this->GetFilename()).Data(), "RECREATE" ); | 
| 398 | mocchiut | 1.3 | //fastMethod = kTRUE; | 
| 399 |  |  | fastMethod = kFALSE; | 
| 400 | mocchiut | 1.1 | // | 
| 401 |  |  | // | 
| 402 |  |  | if ( !Target || Target->IsZombie()) { | 
| 403 |  |  | printf("Error opening target file (does %s exist?)\n",(this->GetFilename()).Data()); | 
| 404 |  |  | exit(1); | 
| 405 |  |  | } | 
| 406 |  |  | // | 
| 407 |  |  | TTree::SetMaxTreeSize(maxsize); | 
| 408 | mocchiut | 1.5 | Target->SetCompressionLevel(2); | 
| 409 | mocchiut | 1.1 | // | 
| 410 | mocchiut | 1.4 | fOpen = true; | 
| 411 | mocchiut | 1.1 | return(true); | 
| 412 |  |  | // | 
| 413 |  |  | }; | 
| 414 |  |  | // | 
| 415 |  |  | return(true); | 
| 416 |  |  | // | 
| 417 |  |  | }; | 
| 418 |  |  |  | 
| 419 |  |  |  | 
| 420 |  |  | void RunGlue::DeleteRunFiles(TList *dlist){ | 
| 421 |  |  | // | 
| 422 |  |  | TString donerun = ""; | 
| 423 |  |  | // | 
| 424 |  |  | printf(" Deleting runs: \n"); | 
| 425 |  |  | // | 
| 426 |  |  | UInt_t ll = 0; | 
| 427 |  |  | // | 
| 428 |  |  | while ( (TFile*)dlist->At(ll) ){ | 
| 429 |  |  | donerun = (TString)(((TFile*)dlist->At(ll))->GetName()); | 
| 430 |  |  | gSystem->Unlink(donerun); | 
| 431 |  |  | printf(" Deleted file is %s \n",donerun.Data()); | 
| 432 |  |  | ll++; | 
| 433 |  |  | // | 
| 434 |  |  | }; | 
| 435 |  |  | }; | 
| 436 |  |  |  | 
| 437 |  |  | void RunGlue::UpdateDB(TList *dlist){ | 
| 438 |  |  | // | 
| 439 |  |  | TSQLResult *pResult; | 
| 440 |  |  | TSQLRow *Row; | 
| 441 |  |  | stringstream myquery; | 
| 442 |  |  | // | 
| 443 |  |  | TString donerun = ""; | 
| 444 |  |  | // | 
| 445 |  |  | if ( DebugMode() ) printf(" Updating GL_RUN: \n"); | 
| 446 |  |  | // | 
| 447 |  |  | UInt_t ll = 0; | 
| 448 |  |  | UInt_t idl2 = 0; | 
| 449 | mocchiut | 1.2 | UInt_t idr = 0; | 
| 450 | mocchiut | 1.1 | // | 
| 451 |  |  | // | 
| 452 |  |  | myquery.str(""); | 
| 453 | mocchiut | 1.2 | myquery << "select ID from GL_RAW where NAME='level2 files';"; | 
| 454 |  |  | if ( DebugMode() ) printf(" query is %s \n",myquery.str().c_str()); | 
| 455 |  |  | // | 
| 456 |  |  | pResult = dbc->Query(myquery.str().c_str()); | 
| 457 |  |  | if ( !pResult ){ | 
| 458 |  |  | printf(" ERROR QUERYING ON DB!\n"); | 
| 459 |  |  | return; | 
| 460 |  |  | }; | 
| 461 |  |  | Row = pResult->Next(); | 
| 462 |  |  | if( Row == NULL ){ | 
| 463 |  |  | printf(" ERROR QUERYING THE DB!\n"); | 
| 464 |  |  | return; | 
| 465 |  |  | } else { | 
| 466 |  |  | idr = (UInt_t)atoll(Row->GetField(0)); | 
| 467 |  |  | }; | 
| 468 |  |  | // | 
| 469 |  |  | myquery.str(""); | 
| 470 |  |  | myquery << "insert into GL_ROOT (ID_RAW,PATH,NAME) values (" << idr << ",'" << outdir.Data() << "','" << ((TString)gSystem->BaseName(this->GetFilename())).Data() << "');"; | 
| 471 | mocchiut | 1.1 | if ( DebugMode() ) printf(" query is %s \n",myquery.str().c_str()); | 
| 472 |  |  | // | 
| 473 |  |  | pResult = dbc->Query(myquery.str().c_str()); | 
| 474 |  |  | if ( !pResult ){ | 
| 475 |  |  | printf(" ERROR WRITING ON DB!\n"); | 
| 476 |  |  | return; | 
| 477 |  |  | }; | 
| 478 |  |  | myquery.str(""); | 
| 479 |  |  | myquery << "select ID from GL_ROOT where NAME='" << ((TString)gSystem->BaseName(this->GetFilename())).Data() << "';"; | 
| 480 |  |  | if ( DebugMode() ) printf(" query is %s \n",myquery.str().c_str()); | 
| 481 |  |  | // | 
| 482 |  |  | pResult = dbc->Query(myquery.str().c_str()); | 
| 483 |  |  | if ( !pResult ){ | 
| 484 |  |  | printf(" ERROR WRITING ON DB!\n"); | 
| 485 |  |  | return; | 
| 486 |  |  | }; | 
| 487 |  |  | Row = pResult->Next(); | 
| 488 |  |  | if( Row == NULL ){ | 
| 489 |  |  | printf(" ERROR QUERYING THE DB!\n"); | 
| 490 |  |  | return; | 
| 491 |  |  | } else { | 
| 492 |  |  | idl2 = (UInt_t)atoll(Row->GetField(0)); | 
| 493 |  |  | }; | 
| 494 |  |  | // | 
| 495 |  |  | // | 
| 496 |  |  | // | 
| 497 |  |  | UInt_t drun = 0; | 
| 498 |  |  | // | 
| 499 |  |  | while ( (TFile*)dlist->At(ll) ){ | 
| 500 |  |  | donerun = ""; | 
| 501 |  |  | donerun = (TString)((TString)(gSystem->BaseName(((TFile*)dlist->At(ll))->GetName()))).ReplaceAll(".Level2.root",12,"",0); | 
| 502 |  |  | drun = (UInt_t)(donerun.Atoi()); | 
| 503 |  |  | // | 
| 504 |  |  | if ( DebugMode() ) printf(" Run is %s \n",donerun.Data()); | 
| 505 |  |  | // | 
| 506 |  |  | myquery.str(""); | 
| 507 |  |  | myquery << "update GL_RUN set ID_ROOT_L2=" << idl2 << " where ID=" << drun << ";"; | 
| 508 |  |  | if ( DebugMode() ) printf(" query is %s \n",myquery.str().c_str()); | 
| 509 |  |  | // | 
| 510 |  |  | pResult = dbc->Query(myquery.str().c_str()); | 
| 511 |  |  | if ( !pResult ){ | 
| 512 |  |  | printf(" ERROR WRITING ON DB!\n"); | 
| 513 |  |  | return; | 
| 514 |  |  | }; | 
| 515 |  |  | // | 
| 516 |  |  | ll++; | 
| 517 |  |  | // | 
| 518 |  |  | }; | 
| 519 |  |  | }; | 
| 520 |  |  |  | 
| 521 |  |  | // | 
| 522 |  |  | // method stolen to ROOT's "hadd" and modified | 
| 523 |  |  | // | 
| 524 |  |  | void RunGlue::MergeRootfile(TList *sourcelist) { | 
| 525 |  |  | // | 
| 526 |  |  | merged = false; | 
| 527 |  |  | // | 
| 528 |  |  | TDirectory *target = Target; | 
| 529 |  |  | // | 
| 530 |  |  | if ( DebugMode() ) printf("\nTarget path is: %s \n",target->GetPath()); | 
| 531 |  |  | // | 
| 532 |  |  | TString path( (char*)strstr( target->GetPath(), ":" ) ); | 
| 533 |  |  | path.Remove(0,2); | 
| 534 |  |  | // | 
| 535 |  |  | TDirectory *first_source = (TDirectory*)sourcelist->First(); | 
| 536 |  |  | THashList allNames; | 
| 537 |  |  | // | 
| 538 |  |  | while ( first_source ){ | 
| 539 |  |  | // | 
| 540 |  |  | TDirectory *current_sourcedir = first_source->GetDirectory(path); | 
| 541 |  |  | // | 
| 542 |  |  | if ( !current_sourcedir ){ | 
| 543 |  |  | first_source = (TDirectory*)sourcelist->After(first_source); | 
| 544 |  |  | continue; | 
| 545 |  |  | } | 
| 546 |  |  | // | 
| 547 |  |  | // loop over all keys in this directory | 
| 548 |  |  | // | 
| 549 | mocchiut | 1.6 | TChain *globChain = 0; | 
| 550 | mocchiut | 1.1 | TIter nextkey( current_sourcedir->GetListOfKeys() ); | 
| 551 | mocchiut | 1.5 | TKey *key = 0; | 
| 552 |  |  | TKey *oldkey = 0; | 
| 553 | mocchiut | 1.1 | TH1::AddDirectory(kFALSE); // gain time, do not add the objects in the list in memory | 
| 554 |  |  | // | 
| 555 |  |  | while ( (key = (TKey*)nextkey()) ) { | 
| 556 |  |  | // | 
| 557 | mocchiut | 1.5 | //      printf(" target ls \n"); | 
| 558 |  |  | //      Target->ls(); | 
| 559 |  |  | // | 
| 560 | mocchiut | 1.1 | if ( current_sourcedir == target ) break; | 
| 561 |  |  | // | 
| 562 | mocchiut | 1.5 | if ( oldkey && !strcmp(oldkey->GetName(),key->GetName()) ) continue; //keep only the highest cycle number for each key | 
| 563 | mocchiut | 1.1 | // | 
| 564 | mocchiut | 1.5 | if ( allNames.FindObject(key->GetName()) ) continue; | 
| 565 | mocchiut | 1.1 | // | 
| 566 |  |  | if ( DebugMode() ) printf(" Key name is -%s- \n",key->GetName()); | 
| 567 |  |  | // | 
| 568 |  |  | // | 
| 569 |  |  | // | 
| 570 |  |  | if ( !strcmp(key->GetName(),"Tracker") && !li->TRK2 && !li->TRK1 && !li->TRKh ) continue; | 
| 571 |  |  | // | 
| 572 |  |  | if ( !strcmp(key->GetName(),"Calorimeter") && !li->CAL2 && !li->CAL1 ) continue; | 
| 573 |  |  | // | 
| 574 |  |  | if ( !strcmp(key->GetName(),"ToF") && !li->TOF ) continue; | 
| 575 |  |  | // | 
| 576 |  |  | if ( !strcmp(key->GetName(),"Trigger") && !li->TRG ) continue; | 
| 577 |  |  | // | 
| 578 |  |  | if ( !strcmp(key->GetName(),"Anticounter") && !li->AC ) continue; | 
| 579 |  |  | // | 
| 580 |  |  | if ( !strcmp(key->GetName(),"S4") && !li->S4 ) continue; | 
| 581 |  |  | // | 
| 582 |  |  | if ( !strcmp(key->GetName(),"NeutronD") && !li->ND ) continue; | 
| 583 |  |  | // | 
| 584 |  |  | if ( !strcmp(key->GetName(),"OrbitalInfo") && !li->ORB ) continue; | 
| 585 |  |  | // | 
| 586 |  |  | if ( !strcmp(key->GetName(),"Run") && !RUN ) continue; | 
| 587 |  |  | // | 
| 588 |  |  | if ( strcmp(key->GetName(),"Calorimeter") && strcmp(key->GetName(),"Tracker") && strcmp(key->GetName(),"ToF") && strcmp(key->GetName(),"Trigger") && strcmp(key->GetName(),"Anticounter") && strcmp(key->GetName(),"S4") && strcmp(key->GetName(),"NeutronD") && strcmp(key->GetName(),"OrbitalInfo") && strcmp(key->GetName(),"Run") && strcmp(key->GetName(),"ProcessID0") ){ | 
| 589 |  |  | if ( DebugMode() ) printf(" ERROR UNKNOWN KEY %s !\n",key->GetName()); | 
| 590 |  |  | continue; | 
| 591 |  |  | }; | 
| 592 |  |  | // | 
| 593 |  |  | allNames.Add(new TObjString(key->GetName())); | 
| 594 |  |  | // | 
| 595 |  |  | // read object from first source file | 
| 596 |  |  | // | 
| 597 |  |  | current_sourcedir->cd(); | 
| 598 |  |  | TObject *obj = key->ReadObj(); | 
| 599 |  |  | // | 
| 600 |  |  | if ( obj->IsA()->InheritsFrom("TTree") ){ | 
| 601 |  |  | // | 
| 602 |  |  | // loop over all source files create a chain of Trees "globChain" | 
| 603 |  |  | // | 
| 604 |  |  | TString obj_name; | 
| 605 |  |  | // | 
| 606 |  |  | if ( path.Length() ) { | 
| 607 |  |  | obj_name = path + "/" + obj->GetName(); | 
| 608 |  |  | } else { | 
| 609 |  |  | obj_name = obj->GetName(); | 
| 610 |  |  | }; | 
| 611 |  |  | // | 
| 612 |  |  | globChain = new TChain(obj_name); | 
| 613 |  |  | // | 
| 614 | mocchiut | 1.6 | globChain->SetCacheSize(0); | 
| 615 |  |  | // | 
| 616 | mocchiut | 1.1 | globChain->Add(first_source->GetName()); | 
| 617 |  |  | // | 
| 618 |  |  | TFile *nextsource = (TFile*)sourcelist->After( first_source ); | 
| 619 |  |  | // | 
| 620 |  |  | while ( nextsource ) { | 
| 621 |  |  | // | 
| 622 |  |  | //do not add to the list a file that does not contain this Tree | 
| 623 |  |  | // | 
| 624 |  |  | TFile *curf = TFile::Open(nextsource->GetName()); | 
| 625 |  |  | // | 
| 626 |  |  | if ( curf ) { | 
| 627 |  |  | // | 
| 628 |  |  | Bool_t mustAdd = kFALSE; | 
| 629 |  |  | // | 
| 630 |  |  | if (curf->FindKey(obj_name)) { | 
| 631 |  |  | // | 
| 632 |  |  | mustAdd = kTRUE; | 
| 633 |  |  | // | 
| 634 |  |  | } else { | 
| 635 |  |  | // | 
| 636 |  |  | //we could be more clever here. No need to import the object | 
| 637 |  |  | //we are missing a function in TDirectory | 
| 638 |  |  | // | 
| 639 |  |  | TObject *aobj = curf->Get(obj_name); | 
| 640 |  |  | // | 
| 641 |  |  | if ( aobj ){ | 
| 642 |  |  | mustAdd = kTRUE; | 
| 643 |  |  | delete aobj; | 
| 644 |  |  | }; | 
| 645 |  |  | }; | 
| 646 |  |  | if (mustAdd) { | 
| 647 |  |  | globChain->Add(nextsource->GetName()); | 
| 648 |  |  | }; | 
| 649 |  |  | }; | 
| 650 |  |  | delete curf; | 
| 651 |  |  | nextsource = (TFile*)sourcelist->After(nextsource); | 
| 652 |  |  | }; | 
| 653 |  |  | // | 
| 654 | mocchiut | 1.5 | delete nextsource; | 
| 655 |  |  | // | 
| 656 | mocchiut | 1.1 | } else { | 
| 657 |  |  | // | 
| 658 |  |  | // object is of no type that we know or can handle | 
| 659 |  |  | // | 
| 660 |  |  | if ( DebugMode() ) cout << "Unknown object type, name: " | 
| 661 |  |  | << obj->GetName() << " title: " << obj->GetTitle() << endl; | 
| 662 |  |  | }; | 
| 663 |  |  | // | 
| 664 |  |  | // now write the merged histogram (which is "in" obj) to the target file | 
| 665 |  |  | // note that this will just store obj in the current directory level, | 
| 666 |  |  | // which is not persistent until the complete directory itself is stored | 
| 667 |  |  | // by "target->Write()" below | 
| 668 |  |  | // | 
| 669 |  |  | if ( obj ){ | 
| 670 |  |  | // | 
| 671 |  |  | target->cd(); | 
| 672 |  |  | // | 
| 673 |  |  | if( obj->IsA()->InheritsFrom("TTree") ) { | 
| 674 |  |  | // | 
| 675 | mocchiut | 1.5 | Long64_t nfiles = 0; | 
| 676 | mocchiut | 1.1 | if ( fastMethod ){ | 
| 677 | mocchiut | 1.5 | //      globChain->Merge(target->GetFile(),0,"C keep fast"); | 
| 678 |  |  | nfiles=this->Mergy((TChain*)globChain,target->GetFile(),0,"C keep fast"); | 
| 679 | mocchiut | 1.1 | } else { | 
| 680 | mocchiut | 1.5 | //globChain->Merge(target->GetFile(),0,"C keep"); | 
| 681 |  |  | nfiles=this->Mergy((TChain*)globChain,target->GetFile(),0,"C keep"); | 
| 682 | mocchiut | 1.1 | }; | 
| 683 |  |  | // | 
| 684 |  |  | merged = true; | 
| 685 |  |  | // | 
| 686 | mocchiut | 1.5 | if ( DebugMode() ){ | 
| 687 |  |  | printf(" Merged %i files\n",(int)nfiles); | 
| 688 |  |  | globChain->ls(); | 
| 689 |  |  | }; | 
| 690 | mocchiut | 1.1 | // | 
| 691 |  |  | delete globChain; | 
| 692 | mocchiut | 1.5 | //      return; | 
| 693 | mocchiut | 1.1 | // | 
| 694 |  |  | } else { | 
| 695 |  |  | // | 
| 696 |  |  | //      obj->Write( key->GetName() ); // <================================================================================== | 
| 697 |  |  | // | 
| 698 |  |  | }; | 
| 699 |  |  | }; | 
| 700 | mocchiut | 1.5 | delete obj; | 
| 701 | mocchiut | 1.1 | oldkey = key; | 
| 702 |  |  | }; | 
| 703 |  |  | // | 
| 704 |  |  | first_source = (TDirectory*)sourcelist->After(first_source); | 
| 705 |  |  | // | 
| 706 |  |  | }; | 
| 707 |  |  | // save modifications to target file | 
| 708 | mocchiut | 1.5 | // | 
| 709 | mocchiut | 1.1 | target->SaveSelf(kTRUE); | 
| 710 |  |  | // | 
| 711 | mocchiut | 1.5 | }; | 
| 712 |  |  |  | 
| 713 |  |  |  | 
| 714 |  |  | Long64_t RunGlue::Mergy(TChain *mychain, TFile* file, Int_t basketsize, Option_t* option){ | 
| 715 |  |  | // We must have been passed a file, we will use it | 
| 716 |  |  | // later to reset the compression level of the branches. | 
| 717 |  |  | if (!file) { | 
| 718 |  |  | // FIXME: We need an error message here. | 
| 719 |  |  | return 0; | 
| 720 |  |  | } | 
| 721 |  |  |  | 
| 722 |  |  | // Options | 
| 723 |  |  | Bool_t fastClone = kFALSE; | 
| 724 |  |  | TString opt = option; | 
| 725 |  |  | opt.ToLower(); | 
| 726 |  |  | if (opt.Contains("fast")) { | 
| 727 |  |  | fastClone = kTRUE; | 
| 728 |  |  | } | 
| 729 |  |  |  | 
| 730 |  |  | // The chain tree must have a list of branches | 
| 731 |  |  | // because we may try to change their basket | 
| 732 |  |  | // size later. | 
| 733 |  |  | TObjArray* lbranches = mychain->GetListOfBranches(); | 
| 734 |  |  | if (!lbranches) { | 
| 735 |  |  | // FIXME: We need an error message here. | 
| 736 |  |  | return 0; | 
| 737 |  |  | } | 
| 738 |  |  |  | 
| 739 |  |  | // The chain must have a current tree because | 
| 740 |  |  | // that is the one we will clone. | 
| 741 |  |  | //   if (!fTree) { | 
| 742 |  |  | // -- LoadTree() has not yet been called, no current tree. | 
| 743 |  |  | // FIXME: We need an error message here. | 
| 744 |  |  | //      return 0; | 
| 745 |  |  | //   } | 
| 746 |  |  |  | 
| 747 |  |  | // Copy the chain's current tree without | 
| 748 |  |  | // copying any entries, we will do that later. | 
| 749 |  |  | TTree* newTree = mychain->CloneTree(0); | 
| 750 |  |  | if (!newTree) { | 
| 751 |  |  | // FIXME: We need an error message here. | 
| 752 |  |  | return 0; | 
| 753 |  |  | } | 
| 754 |  |  |  | 
| 755 |  |  | // Strip out the (potential) directory name. | 
| 756 |  |  | // FIXME: The merged chain may or may not have the | 
| 757 |  |  | //        same name as the original chain.  This is | 
| 758 |  |  | //        bad because the chain name determines the | 
| 759 |  |  | //        names of the trees in the chain by default. | 
| 760 |  |  | newTree->SetName(gSystem->BaseName(mychain->GetName())); | 
| 761 |  |  |  | 
| 762 |  |  | // FIXME: Why do we do this? | 
| 763 |  |  | //   newTree->SetAutoSave(-1); | 
| 764 |  |  | newTree->SetAutoSave(900000000000000LL); | 
| 765 |  |  |  | 
| 766 |  |  | // Circularity is incompatible with merging, it may | 
| 767 |  |  | // force us to throw away entries, which is not what | 
| 768 |  |  | // we are supposed to do. | 
| 769 |  |  | newTree->SetCircular(0); | 
| 770 |  |  |  | 
| 771 |  |  | // Reset the compression level of the branches. | 
| 772 |  |  | if (opt.Contains("c")) { | 
| 773 |  |  | TBranch* branch = 0; | 
| 774 |  |  | TIter nextb(newTree->GetListOfBranches()); | 
| 775 |  |  | while ((branch = (TBranch*) nextb())) { | 
| 776 |  |  | branch->SetCompressionLevel(file->GetCompressionLevel()); | 
| 777 |  |  | } | 
| 778 |  |  | } | 
| 779 |  |  |  | 
| 780 |  |  | // Reset the basket size of the branches. | 
| 781 |  |  | if (basketsize > 1000) { | 
| 782 |  |  | TBranch* branch = 0; | 
| 783 |  |  | TIter nextb(newTree->GetListOfBranches()); | 
| 784 |  |  | while ((branch = (TBranch*) nextb())) { | 
| 785 |  |  | branch->SetBasketSize(basketsize); | 
| 786 |  |  | } | 
| 787 |  |  | } | 
| 788 |  |  |  | 
| 789 |  |  | Long64_t nentries = mychain->GetEntriesFast(); | 
| 790 |  |  |  | 
| 791 |  |  | // Copy the entries. | 
| 792 |  |  | if (fastClone) { | 
| 793 |  |  | // For each tree in the chain. | 
| 794 |  |  | for (Long64_t i = 0; i < nentries; i += mychain->GetTree()->GetEntries()) { | 
| 795 |  |  | if (mychain->LoadTree(i) < 0) { | 
| 796 |  |  | break; | 
| 797 |  |  | } | 
| 798 |  |  | TTreeCloner cloner(mychain->GetTree(), newTree, option); | 
| 799 |  |  | if (cloner.IsValid()) { | 
| 800 |  |  | newTree->SetEntries(newTree->GetEntries() + mychain->GetTree()->GetEntries()); | 
| 801 |  |  | cloner.Exec(); | 
| 802 |  |  | } else { | 
| 803 |  |  | if (mychain->GetFile()) { | 
| 804 |  |  | printf("Merge Skipped file %s\n", mychain->GetFile()->GetName()); | 
| 805 |  |  | //            } else { | 
| 806 |  |  | //               Warning("Merge", "Skipped file number %d\n", fTreeNumber); | 
| 807 |  |  | } | 
| 808 |  |  | } | 
| 809 |  |  | } | 
| 810 |  |  | } else { | 
| 811 |  |  | for (Long64_t i = 0; i < nentries; i++) { | 
| 812 |  |  | if (mychain->GetEntry(i) <= 0) { | 
| 813 |  |  | break; | 
| 814 |  |  | } | 
| 815 |  |  | newTree->Fill(); | 
| 816 |  |  | } | 
| 817 |  |  | } | 
| 818 |  |  |  | 
| 819 |  |  | // Write the new tree header. | 
| 820 |  |  | newTree->Write(); | 
| 821 |  |  |  | 
| 822 |  |  | // Get our return value. | 
| 823 |  |  | Int_t nfiles = newTree->GetFileNumber() + 1; | 
| 824 |  |  |  | 
| 825 |  |  | // Close and delete the current file of the new tree. | 
| 826 |  |  | if (!opt.Contains("keep")) { | 
| 827 |  |  | // FIXME: What happens to fDirectory in newTree here? | 
| 828 |  |  | delete newTree->GetCurrentFile(); | 
| 829 |  |  | } | 
| 830 |  |  | return nfiles; | 
| 831 | mocchiut | 1.1 | } |