]>
Commit | Line | Data |
---|---|---|
2f331ac9 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | // $Id$ | |
17 | ||
e538121a | 18 | // |
19 | // AliAnalysisTriggerScalers : utility class to play with OCDB scalers. | |
20 | // | |
21 | // Can use it to e.g. : | |
22 | // | |
23 | // - get the integrated luminosity for a given period | |
24 | // (see IntegratedLuminosity method) | |
58b19963 | 25 | // |
e538121a | 26 | // - plot the trigger rates (see PlotTriggerEvolution) |
27 | // | |
58b19963 | 28 | // Please note that this class is doing an OCDB "scan" (for as many run |
29 | // as you put in the SetRunList method), so it can be really long | |
30 | // if you're using the raw:// OCDB. If you're planning on using this | |
31 | // class for anything more than a brief test, you'd better think | |
32 | // or making a local copy of the OCDB objects required by this class : | |
33 | // | |
34 | // GRP/CTP/Config | |
35 | // GRP/CTP/Scalers | |
36 | // | |
37 | // and also (to get the fill and period ranges, mainly for drawing) | |
38 | // | |
39 | // GRP/GRP/Data | |
40 | // GRP/GRP/LHCData | |
41 | // | |
42 | // | |
43 | // Please note also that this class evolved from a set a quick macros to | |
44 | // follow the luminosity and trigger rates during data taking to this stage. | |
45 | // | |
46 | // Now (Feb 2013) would probably be a good time to regroup a bit, think about it and | |
47 | // make it more general, more robust and just less "had-hoc"... | |
48 | // | |
49 | // Ideas for improvement : | |
50 | // | |
51 | // - make sure the "what" parameter mean the same thing in all methods | |
52 | // and so can take the same values in all methods | |
53 | // | |
54 | // - get the lumi trigger name and cross-section from e.g. OADB instead of | |
55 | // hard-coding them ? | |
56 | // | |
57 | // - organize the class so that the CTP Scalers and Config can be fetched | |
58 | // from elsewhere (e.g. from a run based container available in some | |
59 | // distant future in the ESDs/AODs ?) | |
60 | // | |
61 | // - robustify the PAC fraction computation | |
62 | // | |
63 | // | |
e538121a | 64 | // L. Aphecetche (Subatech) |
65 | // | |
66 | ||
2f331ac9 | 67 | #include "AliAnalysisTriggerScalers.h" |
68 | #include "AliCDBEntry.h" | |
69 | #include "AliCDBManager.h" | |
70 | #include "AliGRPObject.h" | |
71 | #include "AliLog.h" | |
72 | #include "AliTimeStamp.h" | |
73 | #include "AliTriggerBCMask.h" | |
74 | #include "AliTriggerClass.h" | |
75 | #include "AliTriggerCluster.h" | |
76 | #include "AliTriggerConfiguration.h" | |
77 | #include "AliTriggerDescriptor.h" | |
78 | #include "AliTriggerInput.h" | |
79 | #include "AliTriggerRunScalers.h" | |
80 | #include "AliTriggerScalers.h" | |
81 | #include "AliTriggerScalersESD.h" | |
82 | #include "AliTriggerScalersRecord.h" | |
83 | #include "Riostream.h" | |
84 | #include "TDatime.h" | |
85 | #include "TError.h" | |
86 | #include "TGraph.h" | |
acbe06d5 | 87 | #include "TGraphErrors.h" |
c665b011 | 88 | #include "TH2.h" |
2f331ac9 | 89 | #include "TObjArray.h" |
90 | #include "TObjString.h" | |
91 | #include <set> | |
92 | #include <map> | |
93 | #include "TStyle.h" | |
94 | #include "AliLHCData.h" | |
95 | #include "TMath.h" | |
96 | #include "TAxis.h" | |
e538121a | 97 | #include "TBox.h" |
2f331ac9 | 98 | #include "TCanvas.h" |
e538121a | 99 | #include "TText.h" |
c2aad3ae | 100 | using std::make_pair; |
2f331ac9 | 101 | ClassImp(AliAnalysisTriggerScalers) |
102 | ||
103 | namespace { | |
104 | ||
105 | //______________________________________________________________________________ | |
106 | UChar_t GetIndex(ULong64_t mask) | |
107 | { | |
108 | for ( Int_t i = 0; i < 64; ++i ) | |
109 | { | |
110 | if ( mask & ( 1ull << i ) ) return i+1; | |
111 | } | |
112 | return 0; | |
113 | } | |
114 | ||
115 | ||
116 | //______________________________________________________________________________ | |
117 | Double_t Mu(Double_t L0B, Double_t Nb) | |
118 | { | |
119 | /// L0B = trigger rate before any veto | |
120 | /// Nb = number of crossing bunches | |
121 | ||
122 | Double_t p0 = 1-L0B/(Nb*11245.0); // proba to get *no* collision per bunch crossing | |
123 | ||
124 | return -TMath::Log(p0); | |
125 | } | |
126 | ||
127 | //______________________________________________________________________________ | |
128 | TCanvas* NewCanvas(const char* name) | |
129 | { | |
130 | TCanvas* c = new TCanvas(name,name); | |
131 | c->SetLeftMargin(0.15); | |
132 | return c; | |
133 | } | |
134 | ||
135 | //______________________________________________________________________________ | |
136 | void TimeAxis(TGraph* g) | |
137 | { | |
138 | // g->GetXaxis()->SetTimeDisplay(1); | |
139 | // g->GetXaxis()->SetTimeFormat("%d/%m %H:%M%F2010-12-31 24:00:00"); | |
140 | // g->GetXaxis()->SetNdivisions(505); | |
141 | g->GetYaxis()->SetTitleOffset(1.5); | |
142 | ||
143 | g->GetXaxis()->SetTimeDisplay(1); | |
144 | // g->GetXaxis()->SetTimeFormat("%d/%m %H:%M%F2010-12-31 24:00:00"); | |
145 | g->GetXaxis()->SetTimeFormat("%d/%m %H:%M"); | |
146 | g->GetXaxis()->SetTimeOffset(0,"gmt"); | |
147 | g->GetXaxis()->SetNdivisions(505); | |
148 | ||
149 | } | |
150 | ||
151 | } | |
152 | ||
153 | //_____________________________________________________________________________ | |
58b19963 | 154 | AliAnalysisTriggerScalers::AliAnalysisTriggerScalers(Int_t runNumber, const char* ocdbPath) : fRunList(), fOCDBPath(ocdbPath), fShouldCorrectForPileUp(kTRUE), fCrossSectionUnit("UB") |
2f331ac9 | 155 | { |
156 | // ctor using a single run number | |
157 | SetRunList(runNumber); | |
158 | } | |
159 | ||
e538121a | 160 | //_____________________________________________________________________________ |
58b19963 | 161 | AliAnalysisTriggerScalers::AliAnalysisTriggerScalers(const std::vector<int>& runs, const char* ocdbPath) : fRunList(), fOCDBPath(ocdbPath), fShouldCorrectForPileUp(kTRUE), fCrossSectionUnit("UB") |
e538121a | 162 | { |
163 | // ctor using a vector of run numbers | |
164 | SetRunList(runs); | |
165 | } | |
166 | ||
167 | //_____________________________________________________________________________ | |
58b19963 | 168 | AliAnalysisTriggerScalers::AliAnalysisTriggerScalers(const std::set<int>& runs, const char* ocdbPath) : fRunList(), fOCDBPath(ocdbPath), fShouldCorrectForPileUp(kTRUE), fCrossSectionUnit("UB") |
e538121a | 169 | { |
170 | // ctor using a set of run numbers | |
171 | SetRunList(runs); | |
172 | } | |
173 | ||
2f331ac9 | 174 | //_____________________________________________________________________________ |
58b19963 | 175 | AliAnalysisTriggerScalers::AliAnalysisTriggerScalers(const char* runlist, const char* ocdbPath) : fRunList(), fOCDBPath(ocdbPath), fShouldCorrectForPileUp(kTRUE), fCrossSectionUnit("UB") |
2f331ac9 | 176 | { |
177 | // ctor from a run list (txt file) | |
178 | SetRunList(runlist); | |
179 | } | |
180 | ||
181 | //_____________________________________________________________________________ | |
182 | AliAnalysisTriggerScalers::~AliAnalysisTriggerScalers() | |
183 | { | |
e538121a | 184 | // dtor |
2f331ac9 | 185 | } |
186 | ||
58b19963 | 187 | //______________________________________________________________________________ |
188 | Bool_t AliAnalysisTriggerScalers::CheckRecord(const AliTriggerScalersRecord& record, | |
189 | UInt_t index, | |
190 | UInt_t refb, | |
191 | UInt_t refa, | |
192 | UInt_t timelapse) const | |
193 | { | |
194 | /// Check if a trigger scaler record should be kept for our | |
195 | /// luminosity computations | |
196 | ||
197 | const AliTriggerScalers* scaler = record.GetTriggerScalersForClass(index); | |
198 | ||
199 | UInt_t a = scaler->GetLOCA() - refa; | |
200 | UInt_t b = scaler->GetLOCB() - refb; | |
201 | ||
202 | Bool_t ok(kTRUE); | |
203 | ||
204 | if ( b <= 2 || ( a <= 2 ) || timelapse <= 9 ) // empirical cuts | |
205 | { | |
206 | ok = kFALSE; | |
207 | } | |
208 | ||
209 | return ok; | |
210 | } | |
211 | ||
212 | ||
e538121a | 213 | //______________________________________________________________________________ |
214 | void AliAnalysisTriggerScalers::DrawFill(Int_t run1, Int_t run2, double ymin, double ymax, const char* label) | |
215 | { | |
216 | // Draw a yellow box to indicate a run range | |
217 | ||
218 | AliDebugClass(1,Form("RUN1 %09d RUN2 %09d YMIN %e YMAX %e %s", | |
219 | run1,run2,ymin,ymax,label)); | |
220 | TBox* b = new TBox(run1*1.0,ymin,run2*1.0,ymax); | |
221 | b->SetFillColor(5); | |
222 | b->Draw(); | |
58b19963 | 223 | TText* text = new TText((run1+run2)/2.0,ymin + (ymax-ymin)*0.85,label); |
e538121a | 224 | text->SetTextSize(0.025); |
225 | text->SetTextFont(42); | |
226 | text->SetTextAlign(23); | |
227 | text->SetTextAngle(45); | |
228 | text->Draw(); | |
229 | } | |
230 | ||
231 | //_____________________________________________________________________________ | |
232 | void AliAnalysisTriggerScalers::DrawFills(Double_t ymin, Double_t ymax) | |
233 | { | |
234 | /// Draw the fill ranges corresponding to the list of runs | |
235 | /// Note that this method will scan the OCDB to get the run -> fill number relationship, | |
236 | /// so it's better in this case to use a local copy of the OCDB if you have one. Otherwise | |
237 | /// it will be long. | |
238 | /// | |
239 | std::map<int, std::pair<int,int> > fills; | |
240 | ||
241 | GetFillBoundaries(fills); | |
242 | ||
243 | std::map<int, std::pair<int,int> >::const_iterator it; | |
244 | ||
245 | for ( it = fills.begin(); it != fills.end(); ++it ) | |
246 | { | |
247 | const std::pair<int,int>& p = it->second; | |
248 | TString fillnumber; | |
249 | fillnumber.Form("%d",it->first); | |
250 | DrawFill(p.first,p.second,ymin,ymax,fillnumber.Data()); | |
251 | } | |
252 | } | |
253 | ||
58b19963 | 254 | //_____________________________________________________________________________ |
255 | void AliAnalysisTriggerScalers::GetCTPObjects(Int_t runNumber, | |
256 | AliTriggerConfiguration*& tc, | |
257 | AliTriggerRunScalers*& trs, | |
258 | AliLHCData*& lhc) const | |
259 | { | |
260 | /// For a given run, get the CTP objects we need to do our work | |
261 | /// | |
262 | /// FIXME: this is the method that should probably be virtualized so | |
263 | /// we can get those objects from either OCDB or run based container in AODs/ESDs | |
264 | ||
265 | tc = static_cast<AliTriggerConfiguration*>(GetOCDBObject("GRP/CTP/Config",runNumber)); | |
266 | trs = static_cast<AliTriggerRunScalers*>(GetOCDBObject("GRP/CTP/Scalers",runNumber)); | |
267 | lhc = static_cast<AliLHCData*>(GetOCDBObject("GRP/GRP/LHCData",runNumber)); | |
268 | } | |
269 | ||
e538121a | 270 | //_____________________________________________________________________________ |
271 | void AliAnalysisTriggerScalers::GetFillBoundaries(std::map<int, std::pair<int,int> >& fills) | |
272 | { | |
273 | /// Given a list of runs get the fills they are in | |
274 | ||
275 | fills.clear(); | |
276 | ||
277 | for ( std::vector<int>::const_iterator it = fRunList.begin(); it != fRunList.end(); ++it ) | |
278 | { | |
279 | int runnumber = *it; | |
280 | ||
281 | int fill = GetFillNumberFromRunNumber(runnumber); | |
282 | ||
283 | if (fills.count(fill)) | |
284 | { | |
285 | std::pair<int,int>& p = fills[fill]; | |
286 | p.first = TMath::Min(runnumber,p.first); | |
287 | p.second = TMath::Max(runnumber,p.second); | |
288 | } | |
289 | else | |
290 | { | |
291 | fills[fill] = make_pair<int,int>(runnumber,runnumber); | |
292 | } | |
293 | } | |
294 | } | |
295 | ||
296 | ||
c665b011 | 297 | //______________________________________________________________________________ |
298 | Int_t AliAnalysisTriggerScalers::GetFillNumberFromRunNumber(Int_t runNumber) | |
299 | { | |
300 | /// Get the fill number of a run | |
301 | ||
302 | AliLHCData* lhcData = static_cast<AliLHCData*>(GetOCDBObject("GRP/GRP/LHCData",runNumber)); | |
303 | if (lhcData) | |
304 | { | |
305 | Int_t fillNumber = lhcData->GetFillNumber(); | |
306 | if ( fillNumber == 0 && runNumber == 189694) | |
307 | { | |
308 | // manual hack because GRP info incorrect for this run ? | |
309 | fillNumber = 3135; | |
310 | } | |
311 | ||
312 | return fillNumber; | |
313 | } | |
314 | return -1; | |
315 | } | |
316 | ||
2f331ac9 | 317 | //______________________________________________________________________________ |
58b19963 | 318 | TObject* AliAnalysisTriggerScalers::GetOCDBObject(const char* path, Int_t runNumber) const |
2f331ac9 | 319 | { |
e538121a | 320 | // Helper method to get an object from the OCDB |
321 | ||
2f331ac9 | 322 | if ( !AliCDBManager::Instance()->IsDefaultStorageSet() ) |
323 | { | |
324 | AliCDBManager::Instance()->SetDefaultStorage(fOCDBPath.Data()); | |
325 | } | |
326 | ||
327 | AliCDBManager::Instance()->SetRun(runNumber); | |
328 | ||
329 | gErrorIgnoreLevel=kWarning; // to avoid all the TAlienFile::Open messages... | |
330 | ||
331 | AliCDBEntry* e = AliCDBManager::Instance()->Get(path); | |
332 | return e ? e->GetObject() : 0x0; | |
333 | } | |
334 | ||
335 | ||
58b19963 | 336 | //______________________________________________________________________________ |
337 | TString AliAnalysisTriggerScalers::GetLHCPeriodFromRunNumber(Int_t runNumber) const | |
338 | { | |
339 | /// Get a list of LHC periods from a list of run numbers | |
340 | ||
341 | AliGRPObject* grp = static_cast<AliGRPObject*>(GetOCDBObject("GRP/GRP/Data",runNumber)); | |
342 | ||
343 | if (!grp) return ""; | |
344 | ||
345 | return grp->GetLHCPeriod(); | |
346 | } | |
347 | ||
348 | //_____________________________________________________________________________ | |
349 | void | |
350 | AliAnalysisTriggerScalers::GetLuminosityTriggerAndCrossSection(Int_t runNumber, | |
351 | TString& lumiTriggerClassName, | |
352 | Double_t& lumiTriggerCrossSection, | |
353 | Double_t& lumiTriggerCrossSectionError) const | |
354 | { | |
355 | /// For one given run, get the trigger class name to be used as the luminometer, | |
356 | /// and its corresponding cross-section | |
357 | /// | |
358 | /// FIXME: all is hard-coded for now... (use OADB for this ?) | |
359 | ||
360 | lumiTriggerClassName=""; | |
361 | lumiTriggerCrossSection=0.0; | |
362 | lumiTriggerCrossSectionError=0.0; // FIXME | |
363 | ||
364 | TString period = GetLHCPeriodFromRunNumber(runNumber); | |
365 | ||
366 | if ( period.BeginsWith("LHC11") ) | |
367 | { | |
368 | AliError("Not implemented yet"); | |
369 | } | |
370 | else if ( period.BeginsWith("LHC12") ) | |
371 | { | |
372 | if ( period == "LHC12h" || period == "LHC12i" ) | |
373 | { | |
374 | // pp 8 TeV main-satellites | |
375 | lumiTriggerClassName = "C0TVX-S-NOPF-ALLNOTRD"; | |
376 | lumiTriggerCrossSection = 28.0; // FIXME: not from a vdM yet | |
377 | } | |
378 | else | |
379 | { | |
380 | AliError("Not implemented yet"); | |
381 | } | |
382 | } | |
383 | else if ( period.BeginsWith("LHC13") ) | |
384 | { | |
385 | if ( period == "LHC13g" ) | |
386 | { | |
387 | // pp 2.76 TeV | |
388 | lumiTriggerClassName = "C0TVX-B-NOPF-ALLNOTRD"; | |
389 | lumiTriggerCrossSection = 18.0; // FIXME: not from a vdM yet | |
390 | } | |
391 | else | |
392 | { | |
393 | // p-Pb or Pb-p 5.02 TeV | |
394 | lumiTriggerClassName = "C0TVX-B-NOPF-ALLNOTRD"; | |
395 | lumiTriggerCrossSection = 0.755*2000; // FIXME: not from a vdM yet | |
396 | } | |
397 | } | |
398 | else | |
399 | { | |
400 | AliError("Not implemented yet"); | |
401 | } | |
402 | ||
403 | float csMult(1.0); | |
404 | ||
405 | if ( fCrossSectionUnit=="PB" ) | |
406 | { | |
407 | csMult=1E9; | |
408 | } | |
409 | else if (fCrossSectionUnit=="NB") | |
410 | { | |
411 | csMult=1E6; | |
412 | } | |
413 | else if ( fCrossSectionUnit=="UB" ) | |
414 | { | |
415 | csMult=1E3; | |
416 | } | |
417 | else if ( fCrossSectionUnit=="MB" ) | |
418 | { | |
419 | csMult=1.0; | |
420 | } | |
421 | ||
422 | lumiTriggerCrossSection *= csMult; | |
423 | lumiTriggerCrossSectionError *= csMult; | |
424 | } | |
425 | ||
426 | //_____________________________________________________________________________ | |
427 | void AliAnalysisTriggerScalers::GetLHCPeriodBoundaries(std::map<std::string, std::pair<int,int> >& periods) | |
428 | { | |
429 | /// Given a list of runs get the fills they are in | |
430 | ||
431 | periods.clear(); | |
432 | ||
433 | for ( std::vector<int>::const_iterator it = fRunList.begin(); it != fRunList.end(); ++it ) | |
434 | { | |
435 | int runnumber = *it; | |
436 | ||
437 | std::string period = GetLHCPeriodFromRunNumber(runnumber).Data(); | |
438 | ||
439 | if (periods.count(period)) | |
440 | { | |
441 | std::pair<int,int>& p = periods[period]; | |
442 | p.first = TMath::Min(runnumber,p.first); | |
443 | p.second = TMath::Max(runnumber,p.second); | |
444 | } | |
445 | else | |
446 | { | |
447 | periods[period] = make_pair<int,int>(runnumber,runnumber); | |
448 | } | |
449 | } | |
450 | } | |
451 | ||
452 | ||
2f331ac9 | 453 | //______________________________________________________________________________ |
454 | Int_t AliAnalysisTriggerScalers::GetTriggerInput(Int_t runNumber, const char* inputname) | |
455 | { | |
e538121a | 456 | /// Get one trigger input for a given run |
2f331ac9 | 457 | AliTriggerConfiguration* tc = static_cast<AliTriggerConfiguration*>(GetOCDBObject("GRP/CTP/Config",runNumber)); |
458 | if (!tc) return -1; | |
459 | ||
460 | const TObjArray& inputs = tc->GetInputs(); | |
461 | ||
462 | AliTriggerInput* ti = static_cast<AliTriggerInput*>(inputs.FindObject(inputname)); | |
463 | ||
464 | if (!ti) return -1; | |
465 | ||
466 | return ti->GetSignature(); | |
467 | } | |
468 | ||
e538121a | 469 | //______________________________________________________________________________ |
470 | Float_t | |
471 | AliAnalysisTriggerScalers::GetPauseAndConfigCorrection(Int_t runNumber, const char* triggerClassName) | |
472 | { | |
473 | /// Tries to estimate the duration of the Pause and Configure phase(s) in a given run | |
474 | /// Probably not really accurate for the moment though. | |
475 | ||
476 | ULong64_t total(0); | |
477 | ULong64_t nopac(0); | |
478 | ||
479 | AliTriggerConfiguration* tc = static_cast<AliTriggerConfiguration*>(GetOCDBObject("GRP/CTP/Config",runNumber)); | |
480 | ||
481 | AliTriggerRunScalers* trs = static_cast<AliTriggerRunScalers*>(GetOCDBObject("GRP/CTP/Scalers",runNumber)); | |
482 | const TObjArray* scalers = trs->GetScalersRecords(); | |
483 | ||
484 | TIter next(scalers); | |
485 | AliTriggerScalersRecord* record; | |
486 | UInt_t reft(0); | |
487 | UInt_t refl0b(0); | |
488 | UInt_t refl0a(0); | |
489 | Bool_t first(kTRUE); | |
490 | ||
491 | Int_t classIndex = tc->GetClassIndexFromName(triggerClassName); | |
492 | ||
493 | while ( ( record = static_cast<AliTriggerScalersRecord*>(next()) ) ) | |
494 | { | |
495 | const AliTriggerScalers* scaler = record->GetTriggerScalersForClass(classIndex); | |
496 | ||
497 | const AliTimeStamp* ats = record->GetTimeStamp(); | |
498 | ||
499 | UInt_t seconds = ats->GetSeconds();// - TTimeStamp::GetZoneOffset(); | |
500 | ||
501 | TTimeStamp ts(seconds,ats->GetMicroSecs()); | |
502 | ||
503 | UInt_t l0b = scaler->GetLOCB() - refl0b; | |
504 | UInt_t l0a = scaler->GetLOCA() - refl0a; | |
505 | UInt_t timelapse = seconds - reft; | |
506 | ||
507 | if ( l0b <=2 || timelapse < 9 ) continue; | |
508 | ||
509 | reft = seconds; | |
510 | refl0b = scaler->GetLOCB(); | |
511 | refl0a = scaler->GetLOCA(); | |
512 | ||
513 | if ( first ) | |
514 | { | |
515 | first = kFALSE; | |
516 | continue; | |
517 | } | |
518 | ||
519 | total += l0b; | |
520 | ||
521 | if ( l0a > 0 ) | |
522 | { | |
523 | nopac += l0b; | |
524 | } | |
525 | } | |
526 | ||
527 | return total > 0 ? nopac*1.0/total : 0.0; | |
528 | } | |
529 | ||
2f331ac9 | 530 | //______________________________________________________________________________ |
531 | AliAnalysisTriggerScalerItem* | |
532 | AliAnalysisTriggerScalers::GetTriggerScaler(Int_t runNumber, const char* level, const char* triggerClassName) | |
533 | { | |
534 | // Get the scaler for a given trigger class and a given trigger level. | |
535 | // Returned object must be deleted by the user. | |
536 | ||
537 | AliTriggerConfiguration* tc = static_cast<AliTriggerConfiguration*>(GetOCDBObject("GRP/CTP/Config",runNumber)); | |
538 | AliTriggerRunScalers* trs = static_cast<AliTriggerRunScalers*>(GetOCDBObject("GRP/CTP/Scalers",runNumber)); | |
539 | AliGRPObject* grp = static_cast<AliGRPObject*>(GetOCDBObject("GRP/GRP/Data",runNumber)); | |
1afce1ce | 540 | |
541 | if (!tc || !trs || !grp) return 0x0; | |
2f331ac9 | 542 | |
543 | TString diCurrent(Form("L3:%5.0f;DIP:%5.0f [L3:%d;DIP:%d]", | |
544 | grp->GetL3Current((AliGRPObject::Stats)0), | |
545 | grp->GetDipoleCurrent((AliGRPObject::Stats)0), | |
546 | grp->GetL3Polarity(), | |
547 | grp->GetDipolePolarity())); | |
548 | ||
2f331ac9 | 549 | const TObjArray& trClasses = tc->GetClasses(); |
550 | ||
551 | const TObjArray* scalers = trs->GetScalersRecords(); | |
552 | const AliTriggerScalersRecord* begin = (AliTriggerScalersRecord*)(scalers->First()); | |
553 | const AliTriggerScalersRecord* end = (AliTriggerScalersRecord*)(scalers->Last()); | |
e538121a | 554 | |
81dfe194 | 555 | time_t duration = TMath::Nint((end->GetTimeStamp()->GetBunchCross() - begin->GetTimeStamp()->GetBunchCross())*AliTimeStamp::fNanosecPerBC*1E-9); |
2f331ac9 | 556 | |
557 | AliTriggerClass* triggerClass = static_cast<AliTriggerClass*>(trClasses.FindObject(triggerClassName)); | |
558 | if (!triggerClass) | |
559 | { | |
560 | return 0x0; | |
561 | } | |
562 | UChar_t index = GetIndex(triggerClass->GetMask()); | |
563 | ||
564 | ULong64_t value(0); | |
565 | ||
566 | const AliTriggerScalers* sbegin = begin->GetTriggerScalersForClass(index); | |
567 | const AliTriggerScalers* send = end->GetTriggerScalersForClass(index); | |
568 | ||
569 | TString swhat(level); | |
570 | swhat.ToUpper(); | |
571 | ||
572 | if ( swhat.BeginsWith("L0A") ) | |
573 | { | |
574 | value = send->GetLOCA() - sbegin->GetLOCA(); | |
575 | } | |
576 | else if ( swhat.BeginsWith("L0B") ) | |
577 | { | |
578 | value = send->GetLOCB() - sbegin->GetLOCB(); | |
579 | } | |
e538121a | 580 | else if ( swhat.BeginsWith("L1A") ) |
2f331ac9 | 581 | { |
582 | value = send->GetL1CA() - sbegin->GetL1CA(); | |
583 | } | |
e538121a | 584 | else if ( swhat.BeginsWith("L1B") ) |
2f331ac9 | 585 | { |
586 | value = send->GetL1CB() - sbegin->GetL1CB(); | |
587 | } | |
e538121a | 588 | else if ( swhat.BeginsWith("L2A") ) |
2f331ac9 | 589 | { |
590 | value = send->GetL2CA() - sbegin->GetL2CA(); | |
591 | } | |
e538121a | 592 | else if ( swhat.BeginsWith("L2B") ) |
2f331ac9 | 593 | { |
594 | value = send->GetL2CB() - sbegin->GetL2CB(); | |
595 | } | |
2f331ac9 | 596 | Int_t ds(1); |
597 | ||
598 | // FIXME: get the downscaling factor here for all cases (only BC1 supported here so far) | |
599 | if ( TString(triggerClassName).Contains("_B1") ) | |
600 | { | |
601 | ds = GetTriggerInput(runNumber,"BC1"); | |
602 | if (!ds) ds=1; | |
603 | } | |
604 | ||
605 | swhat.ReplaceAll("RATE",""); | |
606 | ||
607 | return new AliAnalysisTriggerScalerItem(runNumber,swhat.Data(),diCurrent.Data(),triggerClass->GetName(),value,triggerClass->GetBCMask(),ds,duration); | |
608 | } | |
609 | ||
58b19963 | 610 | //______________________________________________________________________________ |
611 | TGraph* | |
612 | AliAnalysisTriggerScalers::IntegratedLuminosityGraph(const char* triggerClassName, const char* triggerClassNameForPACEstimate) | |
613 | { | |
614 | // Get the integrated luminosity graph for one trigger | |
615 | ||
616 | if ( fRunList.empty() ) | |
617 | { | |
618 | AliError("Cannot work without a run list"); | |
619 | return 0x0; | |
620 | } | |
621 | ||
622 | Double_t offset(0.0); | |
623 | ||
624 | std::vector<double> vx; | |
625 | std::vector<double> vy; | |
626 | ||
627 | Double_t x,y; | |
628 | ||
629 | for ( std::vector<int>::size_type i = 0; i < fRunList.size(); ++i ) | |
630 | { | |
631 | TGraph* g = IntegratedLuminosityGraph(fRunList[i],triggerClassName,triggerClassNameForPACEstimate); | |
632 | ||
633 | if (!g) continue; | |
634 | ||
635 | for ( Int_t j = 0 ; j < g->GetN(); ++j ) | |
636 | { | |
637 | g->GetPoint(j,x,y); | |
638 | vx.push_back(x); | |
639 | vy.push_back(y+offset); | |
640 | } | |
641 | ||
642 | offset += y; | |
643 | ||
644 | delete g; | |
645 | } | |
646 | ||
647 | TGraph* g = new TGraph(vx.size(),&vx[0],&vy[0]); | |
648 | ||
649 | TimeAxis(g); | |
650 | ||
651 | return g; | |
652 | } | |
653 | ||
654 | //______________________________________________________________________________ | |
655 | TGraph* | |
656 | AliAnalysisTriggerScalers::IntegratedLuminosityGraph(Int_t runNumber, const char* triggerClassName, const char* triggerClassNameForPACEstimate) | |
657 | { | |
658 | // Get the integrated luminosity graph for one trigger for the given run | |
659 | // | |
660 | // the triggerClassNameForPACEstimate is only used if triggerClassName is, | |
661 | // for the given run, the same as the luminometer trigger class name, | |
662 | // and should be the trigger class with the higher and non-zero L0A rate (except during PACs) | |
663 | // | |
664 | ||
665 | AliTriggerConfiguration* tc(0x0); | |
666 | AliTriggerRunScalers* trs(0x0); | |
667 | AliLHCData* lhc(0x0); | |
668 | ||
669 | GetCTPObjects(runNumber,tc,trs,lhc); | |
670 | ||
671 | if (!tc || !trs || !lhc) | |
672 | { | |
673 | return 0x0; | |
674 | } | |
675 | ||
676 | const TObjArray* scalerRecords= trs->GetScalersRecords(); | |
677 | const TObjArray& triggerClasses = tc->GetClasses(); | |
678 | ||
679 | TString lumiTriggerClassName; | |
680 | Double_t lumiTriggerCrossSection(0.0); | |
681 | Double_t lumiTriggerCrossSectionError(0.0); | |
682 | ||
683 | GetLuminosityTriggerAndCrossSection(runNumber,lumiTriggerClassName,lumiTriggerCrossSection,lumiTriggerCrossSectionError); | |
684 | ||
685 | AliTriggerClass* lumiTriggerClass = static_cast<AliTriggerClass*>(triggerClasses.FindObject(lumiTriggerClassName)); | |
686 | ||
687 | if (!lumiTriggerClass) | |
688 | { | |
689 | AliError(Form("Could not find lumiTriggerClass=%s",lumiTriggerClassName.Data())); | |
690 | return 0x0; | |
691 | } | |
692 | ||
693 | if (lumiTriggerCrossSection==0.0) | |
694 | { | |
695 | AliError(Form("Could not get cross-section for lumiTriggerClass=%s",lumiTriggerClassName.Data())); | |
696 | return 0x0; | |
697 | } | |
698 | ||
699 | AliTriggerClass* triggerClass = static_cast<AliTriggerClass*>(triggerClasses.FindObject(triggerClassName)); | |
700 | ||
701 | if (!triggerClass) | |
702 | { | |
703 | AliError(Form("Could not find triggerClass=%s",triggerClassName)); | |
704 | return 0x0; | |
705 | } | |
706 | ||
707 | Int_t nbcx = NumberOfInteractingBunches(*lhc); | |
708 | ||
709 | if (nbcx <= 0 && ShouldCorrectForPileUp()) | |
710 | { | |
711 | AliError("Could not get the number of bunches, so won't be able to correct for pile-up"); | |
712 | } | |
713 | ||
714 | TIter nextScaler(scalerRecords); | |
715 | AliTriggerScalersRecord* record; | |
716 | UInt_t reft(0); | |
717 | ||
718 | UInt_t refl0b[] = { 0, 0 }; | |
719 | UInt_t refl0a[] = { 0, 0 }; | |
720 | ||
721 | UInt_t l0b[] = { 0, 0 }; | |
722 | UInt_t l0a[] = { 0, 0 }; | |
723 | ||
724 | Bool_t first(kTRUE); | |
725 | ||
726 | UChar_t classIndices[2]; | |
727 | ||
728 | // class 0 = class for luminomiter | |
729 | // class 1 = class for livetime estimate | |
730 | // or for PAC estimate if triggerClassNameForPACEstimate | |
731 | // is given and triggerClass is the same as the lumi class | |
732 | ||
733 | classIndices[0] = GetIndex(lumiTriggerClass->GetMask()); | |
734 | classIndices[1] = GetIndex(triggerClass->GetMask()); | |
735 | ||
736 | Bool_t sameClass = ( classIndices[0] == classIndices[1] ); | |
737 | Bool_t pacRemoval(kFALSE); | |
738 | ||
739 | if ( sameClass && strlen(triggerClassNameForPACEstimate) > 0 ) | |
740 | { | |
741 | AliTriggerClass* triggerClassForPACEstimate = static_cast<AliTriggerClass*>(triggerClasses.FindObject(triggerClassNameForPACEstimate)); | |
742 | if (!triggerClassForPACEstimate) | |
743 | { | |
744 | AliError(Form("Could not find triggerClassForPACEstimate=%s. Will not correct for PAC durations",triggerClassNameForPACEstimate)); | |
745 | return 0x0; | |
746 | } | |
747 | classIndices[1] = GetIndex(triggerClassForPACEstimate->GetMask()); | |
748 | sameClass = ( classIndices[0] == classIndices[1] ); | |
749 | if (!sameClass) | |
750 | { | |
751 | pacRemoval=kTRUE; | |
752 | } | |
753 | } | |
754 | ||
755 | ULong64_t counter(0); | |
756 | ||
757 | std::vector<Double_t> vseconds; | |
758 | std::vector<Double_t> vlivetime; | |
759 | std::vector<Double_t> vlumi; | |
760 | ||
761 | while ( ( record = static_cast<AliTriggerScalersRecord*>(nextScaler()) ) ) | |
762 | { | |
763 | const AliTimeStamp* ats = record->GetTimeStamp(); | |
764 | ||
765 | UInt_t seconds = ats->GetSeconds();// - TTimeStamp::GetZoneOffset(); | |
766 | ||
767 | TTimeStamp ts(seconds,ats->GetMicroSecs()); | |
768 | ||
769 | UInt_t timelapse = seconds - reft; | |
770 | ||
771 | Bool_t ok = sameClass || CheckRecord(*record,classIndices[1],refl0b[1],refl0a[1],timelapse); | |
772 | ||
773 | if (ok) reft = seconds; | |
774 | ||
775 | for ( Int_t i = 0; i < 2; ++i ) | |
776 | { | |
777 | const AliTriggerScalers* scaler = record->GetTriggerScalersForClass(classIndices[i]); | |
778 | ||
779 | if (ok) | |
780 | { | |
781 | l0b[i] = scaler->GetLOCB() - refl0b[i]; | |
782 | } | |
783 | else | |
784 | { | |
785 | l0b[i] = 0; | |
786 | } | |
787 | l0a[i] = scaler->GetLOCA() - refl0a[i]; | |
788 | ||
789 | refl0b[i] = scaler->GetLOCB(); | |
790 | refl0a[i] = scaler->GetLOCA(); | |
791 | } | |
792 | ||
793 | if ( first ) | |
794 | { | |
795 | first = kFALSE; | |
796 | continue; | |
797 | } | |
798 | ||
81dfe194 | 799 | Double_t factor(1.0); |
800 | ||
58b19963 | 801 | if ( ShouldCorrectForPileUp() && nbcx > 0 && l0b[0] > 0 ) |
802 | { | |
803 | Double_t mu = Mu(l0b[0]/timelapse,nbcx); | |
81dfe194 | 804 | factor = mu/(1-TMath::Exp(-mu)); |
58b19963 | 805 | } |
806 | ||
807 | vseconds.push_back(seconds); | |
808 | ||
809 | Double_t lt(1.0); | |
810 | ||
811 | if ( ok && !sameClass && !pacRemoval ) | |
812 | { | |
813 | lt = (l0a[1]*1.0)/l0b[1]; | |
814 | } | |
815 | ||
81dfe194 | 816 | counter += TMath::Nint(factor*l0b[0]*lt); |
58b19963 | 817 | |
818 | vlumi.push_back( counter / lumiTriggerCrossSection ); | |
819 | ||
820 | } | |
821 | ||
822 | if ( vseconds.empty() ) return 0x0; | |
823 | ||
824 | TGraph* g = new TGraph(vseconds.size(),&vseconds[0],&vlumi[0]); | |
825 | ||
826 | TimeAxis(g); | |
827 | ||
828 | return g; | |
829 | } | |
830 | ||
2f331ac9 | 831 | //______________________________________________________________________________ |
c665b011 | 832 | void AliAnalysisTriggerScalers::IntegratedLuminosity(const char* triggerList, |
833 | const char* lumiTrigger, | |
834 | Double_t lumiCrossSection, | |
835 | const char* csvOutputFile, | |
e538121a | 836 | const char sep, |
837 | const char* csUnit) | |
2f331ac9 | 838 | { |
c665b011 | 839 | // Compute the luminosity for a set of triggers |
840 | ||
e538121a | 841 | // for T0 based lumi (end of pp 2012), use lumiTrigger = C0TVX-S-NOPF-ALLNOTRD and lumiCrossSection = 28 mb (and csUnit="nb") |
c665b011 | 842 | // |
e538121a | 843 | // for T0 based lumi (pPb 2013), use lumiTrigger = C0TVX-B-NOPF-ALLNOTRD |
58b19963 | 844 | // and lumiCrossSection = 0.755*2000 mb (and csUnit="mub") |
845 | ||
846 | // for T0 based lumi (pp 2.76 TeV 2013), use lumiTrigger = C0TVX-B-NOPF-ALLNOTRD | |
847 | // and lumiCrossSection = 18 mb (and csUnit="nb") | |
2f331ac9 | 848 | |
849 | double intLumi(0); | |
850 | ||
c665b011 | 851 | std::map<std::string,float> lumiPerTrigger; |
852 | std::map<int, std::map<std::string,float> > lumiPerFillPerTrigger; | |
853 | ||
854 | std::map<std::string,time_t> durationPerTrigger; | |
855 | ||
856 | TString sTriggerList(triggerList); | |
857 | ||
858 | if ( sTriggerList.Length()==0 ) | |
859 | { | |
58b19963 | 860 | if ( lumiCrossSection < 30 && lumiCrossSection > 20 ) |
e538121a | 861 | { |
862 | // assuming it's pp 2012 | |
863 | sTriggerList = "CMUL8-S-NOPF-ALLNOTRD,CMUL7-S-NOPF-ALLNOTRD,CMUL8-S-NOPF-MUON,CMUL7-S-NOPF-MUON"; | |
2f331ac9 | 864 | |
c665b011 | 865 | // for C0MUL-SC-NOPF-MUON must use C0TVX-SC as lumiTrigger (with same cross-section as C0TVX=28mb) |
e538121a | 866 | } |
58b19963 | 867 | else if ( lumiCrossSection < 30 ) |
868 | { | |
869 | // assuming it's pp 2013 | |
870 | sTriggerList = "CMSL7-B-NOPF-MUON,CMSH7-B-NOPF-MUON,CMUL7-B-NOPF-MUON,CMSL7-B-NOPF-ALLNOTRD,CMSH7-B-NOPF-ALLNOTRD,CMUL7-B-NOPF-ALLNOTRD"; | |
871 | } | |
e538121a | 872 | else |
873 | { | |
874 | sTriggerList = "CMSL7-B-NOPF-MUON,CMSH7-B-NOPF-MUON,CMUL7-B-NOPF-MUON,CMSL7-B-NOPF-ALLNOTRD,CMSH7-B-NOPF-ALLNOTRD,CMUL7-B-NOPF-ALLNOTRD"; | |
875 | } | |
c665b011 | 876 | } |
877 | ||
878 | TObjArray* triggerArray = sTriggerList.Tokenize(","); | |
879 | triggerArray->SetOwner(kTRUE); | |
880 | ||
881 | std::ofstream* out(0x0); | |
882 | ||
883 | if ( TString(csvOutputFile).Length() > 0 ) | |
884 | { | |
885 | out = new std::ofstream(gSystem->ExpandPathName(csvOutputFile)); | |
886 | if (!out || out->bad()) | |
887 | { | |
888 | delete out; | |
889 | out = 0x0; | |
890 | } | |
891 | } | |
2f331ac9 | 892 | |
c665b011 | 893 | TIter nextTrigger(triggerArray); |
894 | TObjString* trigger; | |
2f331ac9 | 895 | |
c665b011 | 896 | if (out) |
897 | { | |
898 | (*out) << "Fill number" << sep; | |
899 | ||
900 | nextTrigger.Reset(); | |
901 | ||
902 | std::map<std::string,float>::const_iterator it; | |
903 | ||
904 | while ( ( trigger = static_cast<TObjString*>(nextTrigger()))) | |
2f331ac9 | 905 | { |
c665b011 | 906 | lumiPerTrigger[trigger->String().Data()] = 0; |
907 | } | |
908 | ||
909 | for ( it = lumiPerTrigger.begin(); it != lumiPerTrigger.end(); ++it ) | |
910 | { | |
911 | (*out) << "lumi from " << it->first.c_str() << sep; | |
912 | } | |
2f331ac9 | 913 | |
c665b011 | 914 | (*out) << "comments" << sep; |
915 | ||
916 | for ( it = lumiPerTrigger.begin(); it != lumiPerTrigger.end(); ++it ) | |
917 | { | |
918 | (*out) << "recorded " << it->first.c_str() << " (integrated)" << sep; | |
919 | } | |
2f331ac9 | 920 | |
e538121a | 921 | (*out) << Form("LHC delivered (%s^-1) per fill ",csUnit) |
922 | << sep << Form("LHC delivered (%s^-1 integrated)",csUnit) << sep; | |
c665b011 | 923 | (*out) << "lumi tot muon" << sep << "eff (%)" << sep; |
924 | (*out) << std::endl; | |
925 | ||
926 | nextTrigger.Reset(); | |
927 | } | |
928 | ||
929 | Int_t currentFillNumber(-1); | |
930 | Int_t fillNumber(0); | |
931 | ||
e538121a | 932 | float csMult(1.0); |
933 | TString scsUnit(csUnit); | |
934 | scsUnit.ToUpper(); | |
935 | ||
936 | if ( scsUnit=="PB" ) | |
937 | { | |
938 | csMult=1E9; | |
939 | } | |
940 | else if (scsUnit=="NB") | |
941 | { | |
942 | csMult=1E6; | |
943 | } | |
944 | else if ( scsUnit=="UB" ) | |
945 | { | |
946 | csMult=1E3; | |
947 | } | |
948 | else if ( scsUnit=="MB" ) | |
949 | { | |
950 | csMult=1.0; | |
951 | } | |
952 | else | |
953 | { | |
954 | AliError(Form("Don't know how to deal with cross-section unit=%s",csUnit)); | |
955 | return; | |
956 | } | |
957 | ||
958 | ||
c665b011 | 959 | for ( std::vector<int>::size_type i = 0; i < fRunList.size(); ++i ) |
960 | { | |
961 | Int_t runNumber = fRunList[i]; | |
962 | Bool_t atLeastOneTriggerFound(kFALSE); | |
963 | ||
964 | // find out which trigger classes to use | |
965 | ||
966 | AliTriggerConfiguration* tc = static_cast<AliTriggerConfiguration*>(GetOCDBObject("GRP/CTP/Config",runNumber)); | |
967 | const TObjArray& trClasses = tc->GetClasses(); | |
968 | ||
969 | if (out) | |
970 | { | |
971 | fillNumber = GetFillNumberFromRunNumber(runNumber); | |
972 | if ( fillNumber == 0 ) | |
973 | { | |
974 | AliError(Form("Got fillNumber = 0 for run %09d !",runNumber)); | |
975 | } | |
2f331ac9 | 976 | |
c665b011 | 977 | if ( fillNumber != currentFillNumber ) |
2f331ac9 | 978 | { |
c665b011 | 979 | std::map<std::string,float>::const_iterator it; |
2f331ac9 | 980 | |
c665b011 | 981 | for ( it = lumiPerTrigger.begin(); it != lumiPerTrigger.end(); ++it ) |
2f331ac9 | 982 | { |
c665b011 | 983 | lumiPerFillPerTrigger[fillNumber][it->first.c_str()] = 0; |
2f331ac9 | 984 | } |
c665b011 | 985 | currentFillNumber = fillNumber; |
986 | } | |
987 | } | |
2f331ac9 | 988 | |
e538121a | 989 | AliTriggerRunScalers* trs = static_cast<AliTriggerRunScalers*>(GetOCDBObject("GRP/CTP/Scalers",runNumber)); |
990 | const TObjArray* scalers = trs->GetScalersRecords(); | |
991 | const AliTriggerScalersRecord* begin = (AliTriggerScalersRecord*)(scalers->First()); | |
992 | const AliTriggerScalersRecord* end = (AliTriggerScalersRecord*)(scalers->Last()); | |
c665b011 | 993 | |
81dfe194 | 994 | time_t duration = TMath::Nint((end->GetTimeStamp()->GetBunchCross() - begin->GetTimeStamp()->GetBunchCross())*AliTimeStamp::fNanosecPerBC*1E-9); |
e538121a | 995 | |
c665b011 | 996 | nextTrigger.Reset(); |
2f331ac9 | 997 | |
e538121a | 998 | TString lumiTriggerClassName(lumiTrigger); |
999 | float lumiSigma = lumiCrossSection*csMult; //in csUnit | |
1000 | AliAnalysisTriggerScalerItem* lumiB = GetTriggerScaler(runNumber,"L0B",lumiTriggerClassName.Data()); | |
1001 | ||
58b19963 | 1002 | if (!lumiB) |
1003 | { | |
1004 | AliError(Form("Did not find lumiTrigger %s for run %09d",lumiTriggerClassName.Data(),runNumber)); | |
1afce1ce | 1005 | continue; |
58b19963 | 1006 | } |
1007 | ||
e538121a | 1008 | Float_t pacCorrection(1.0); |
1009 | ||
c665b011 | 1010 | while ( ( trigger = static_cast<TObjString*>(nextTrigger()) ) ) |
1011 | { | |
c665b011 | 1012 | TString muTriggerClassName(trigger->String()); |
1013 | Int_t n(0); | |
c665b011 | 1014 | |
1015 | if ( !trClasses.FindObject(muTriggerClassName.Data() ) ) | |
1016 | { | |
1017 | continue; | |
1018 | } | |
1019 | ||
1020 | if ( muTriggerClassName.Contains("CMUL8") ) ++n; | |
1021 | if ( muTriggerClassName.Contains("CMUL7") ) ++n; | |
1022 | ||
1023 | if ( n>1 ) | |
1024 | { | |
1025 | AliError(Form("More than 1 relevant trigger class found for run %09d ! Check that !",runNumber)); | |
1026 | trClasses.Print(); | |
1027 | continue; | |
1028 | } | |
1029 | ||
c665b011 | 1030 | AliAnalysisTriggerScalerItem* muonA = GetTriggerScaler(runNumber,"L0A",muTriggerClassName.Data()); |
1031 | AliAnalysisTriggerScalerItem* muonB = GetTriggerScaler(runNumber,"L0B",muTriggerClassName.Data()); | |
1032 | ||
58b19963 | 1033 | if (!muonA || !muonB) continue; |
c665b011 | 1034 | |
1035 | atLeastOneTriggerFound = kTRUE; | |
1036 | ||
1037 | Float_t ratio(0); | |
1038 | ||
1039 | if ( muonB->ValueCorrectedForDownscale() > 0 ) | |
1040 | { | |
1041 | ratio = muonA->ValueCorrectedForDownscale()/muonB->ValueCorrectedForDownscale(); | |
1042 | } | |
1043 | ||
1044 | ratio *= lumiB->ValueCorrectedForDownscale()/lumiSigma; | |
1045 | ||
1046 | if ( muTriggerClassName.BeginsWith("CMUL")) | |
1047 | { | |
1048 | intLumi += ratio; | |
2f331ac9 | 1049 | } |
c665b011 | 1050 | |
e538121a | 1051 | if ( muTriggerClassName.Contains("CMSH") ) |
1052 | { | |
1053 | pacCorrection = GetPauseAndConfigCorrection(runNumber,muTriggerClassName.Data()); | |
1054 | } | |
1055 | ||
c665b011 | 1056 | lumiPerTrigger[muTriggerClassName.Data()] += ratio; |
1057 | durationPerTrigger[muTriggerClassName.Data()] += duration; | |
1058 | lumiPerFillPerTrigger[currentFillNumber][muTriggerClassName.Data()] += ratio; | |
e538121a | 1059 | |
c665b011 | 1060 | } |
1061 | ||
e538121a | 1062 | lumiPerTrigger[lumiTriggerClassName.Data()] += lumiB->ValueCorrectedForDownscale()/lumiSigma; |
1063 | durationPerTrigger[lumiTriggerClassName.Data()] += duration; | |
1064 | lumiPerFillPerTrigger[currentFillNumber][lumiTriggerClassName.Data()] += lumiB->ValueCorrectedForDownscale()/lumiSigma; | |
1065 | ||
1066 | TString lumiPACCorrected(Form("%s(-PAC)",lumiTriggerClassName.Data())); | |
1067 | ||
1068 | lumiPerTrigger[lumiPACCorrected.Data()] += pacCorrection*lumiB->ValueCorrectedForDownscale()/lumiSigma; | |
1069 | durationPerTrigger[lumiPACCorrected.Data()] += duration; | |
1070 | lumiPerFillPerTrigger[currentFillNumber][lumiPACCorrected.Data()] += pacCorrection*lumiB->ValueCorrectedForDownscale()/lumiSigma; | |
1071 | ||
c665b011 | 1072 | if (!atLeastOneTriggerFound && sTriggerList.Contains("CMUL") ) |
1073 | { | |
1074 | AliError(Form("Found no relevant trigger for run %09d",runNumber)); | |
2f331ac9 | 1075 | } |
c665b011 | 1076 | } |
1077 | ||
e538121a | 1078 | AliInfo(Form("Integrated lumi %7.4f %s^-1",intLumi,csUnit)); |
c665b011 | 1079 | |
1080 | std::map<std::string,float>::const_iterator it; | |
1081 | ||
1082 | for ( it = lumiPerTrigger.begin(); it != lumiPerTrigger.end(); ++it ) | |
1083 | { | |
e538121a | 1084 | AliInfo(Form("Trigger %30s Lumi %10.4f %s^-1 duration %10ld s",it->first.c_str(),it->second,csUnit,durationPerTrigger[it->first])); |
c665b011 | 1085 | } |
2f331ac9 | 1086 | |
c665b011 | 1087 | if (out) |
1088 | { | |
1089 | std::map<int, std::map<std::string, float> >::const_iterator fit; | |
2f331ac9 | 1090 | |
c665b011 | 1091 | lumiPerTrigger.clear(); |
2f331ac9 | 1092 | |
c665b011 | 1093 | for ( fit = lumiPerFillPerTrigger.begin(); fit != lumiPerFillPerTrigger.end(); ++fit ) |
2f331ac9 | 1094 | { |
c665b011 | 1095 | int fill = fit->first; |
1096 | std::map<std::string,float>::const_iterator tit; | |
1097 | (*out) << fill << sep; | |
1098 | ||
1099 | for ( tit = fit->second.begin(); tit != fit->second.end(); ++tit ) | |
1100 | { | |
1101 | (*out) << Form("%e",tit->second) << sep; | |
1102 | } | |
1103 | ||
1104 | (*out) << sep; // comment (empty) | |
1105 | ||
1106 | for ( tit = fit->second.begin(); tit != fit->second.end(); ++tit ) | |
1107 | { | |
1108 | lumiPerTrigger[tit->first] += tit->second; | |
1109 | ||
1110 | (*out) << Form("%e",lumiPerTrigger[tit->first]) << sep; | |
1111 | } | |
1112 | (*out) << sep << "0" << sep << "0" << sep << "0" << sep << "0" << sep << std::endl; // LHC per fill, LHC integrated, lumi tot muon , efficiency | |
2f331ac9 | 1113 | } |
c665b011 | 1114 | } |
09d5920f | 1115 | // |
1116 | delete triggerArray; | |
2f331ac9 | 1117 | } |
1118 | ||
58b19963 | 1119 | //______________________________________________________________________________ |
1120 | TGraph* AliAnalysisTriggerScalers::MakeGraph(const std::vector<int>& vx, | |
1121 | const std::vector<int>& vex, | |
1122 | const std::vector<double>& vy, | |
1123 | const std::vector<double>& vey) | |
1124 | { | |
1125 | /// Build a graph from a set of stl vectors | |
1126 | ||
1127 | if ( ! ( vx.size() == vex.size() && vx.size() == vy.size() && vx.size() == vey.size() ) ) | |
1128 | { | |
1129 | std::cerr << "incompatible sizes" << std::endl; | |
1130 | return 0x0; | |
1131 | } | |
1132 | ||
1133 | double* x = new double[vx.size()]; | |
1134 | double* ex = new double[vx.size()]; | |
1135 | double* y = new double[vx.size()]; | |
1136 | double* ey = new double[vx.size()]; | |
1137 | ||
1138 | for ( size_t i = 0; i < vx.size(); ++i ) | |
1139 | { | |
1140 | x[i] = vx[i]; | |
1141 | ex[i] = vex[i]; | |
1142 | y[i] = vy[i]; | |
1143 | ey[i] = vey[i]; | |
1144 | } | |
1145 | ||
1146 | TGraph* g = new TGraphErrors(vx.size(),x,y,ex,ey); | |
1147 | ||
1148 | TimeAxis(g); | |
1149 | ||
1150 | delete[] x; | |
1151 | delete[] y; | |
1152 | delete[] ex; | |
1153 | delete[] ey; | |
1154 | ||
1155 | return g; | |
1156 | } | |
1157 | ||
1158 | //______________________________________________________________________________ | |
1159 | Int_t AliAnalysisTriggerScalers::NumberOfInteractingBunches(const AliLHCData& lhc) const | |
1160 | { | |
1161 | /// Extract the number of colliding bunches from the LHC data | |
1162 | ||
1163 | Int_t numberOfInteractingBunches(0); | |
1164 | Int_t numberOfInteractingBunchesMeasured(0); | |
1165 | Int_t nIBM2(0); | |
1166 | ||
1167 | int beam1(0); | |
1168 | int beam2(1); | |
1169 | ||
1170 | AliLHCDipValI* val = lhc.GetBunchConfigDeclared(beam1,0); | |
1171 | ||
1172 | for ( Int_t i = 0; i < val->GetSizeTotal(); ++i ) | |
1173 | { | |
1174 | if ( val->GetValue(i) < 0 ) ++numberOfInteractingBunches; | |
1175 | } | |
1176 | ||
1177 | AliLHCDipValI* valm = lhc.GetBunchConfigMeasured(beam1,0); | |
1178 | ||
1179 | for ( Int_t i = 0; i < valm->GetSizeTotal(); ++i ) | |
1180 | { | |
1181 | if ( valm->GetValue(i) < 0 ) ++numberOfInteractingBunchesMeasured; | |
1182 | } | |
1183 | ||
1184 | valm = lhc.GetBunchConfigMeasured(beam2,0); | |
1185 | ||
1186 | for ( Int_t i = 0; i < valm->GetSizeTotal(); ++i ) | |
1187 | { | |
1188 | if ( valm->GetValue(i) <= 0 ) ++nIBM2; | |
1189 | } | |
1190 | ||
1191 | if ( numberOfInteractingBunches != numberOfInteractingBunchesMeasured || | |
1192 | numberOfInteractingBunches != nIBM2 ) | |
1193 | { | |
1194 | AliWarning(Form("Got some different number of interacting bunches here ! NumberOfInteractingBunches=%3d NumberOfInteractingBunchesMeasured=%3d NIBM2=%3d", | |
1195 | numberOfInteractingBunches,numberOfInteractingBunchesMeasured,nIBM2)); | |
1196 | } | |
1197 | ||
1198 | return numberOfInteractingBunches; | |
1199 | } | |
1200 | ||
1201 | ||
1202 | //______________________________________________________________________________ | |
1203 | TGraph* AliAnalysisTriggerScalers::PlotTrigger(const char* triggerClassName, | |
1204 | const char* what) | |
1205 | { | |
1206 | // Plot one of the scalers (L0A,L0B,L0AOVERB,etc...) of a given triggerClass | |
1207 | // Get one value per run. | |
1208 | ||
1209 | std::vector<Float_t> x; | |
1210 | std::vector<Float_t> y; | |
1211 | ||
1212 | double integral(0); | |
1213 | double mean(0); | |
1214 | ||
1215 | for ( std::vector<int>::size_type i = 0; i < fRunList.size(); ++i ) | |
1216 | { | |
1217 | Int_t runNumber = fRunList[i]; | |
1218 | ||
1219 | AliAnalysisTriggerScalerItem* s = GetTriggerScaler(runNumber,what,triggerClassName); | |
1220 | ||
1221 | if (!s) continue; | |
1222 | ||
1223 | x.push_back(runNumber); | |
1224 | ||
1225 | Double_t value = s->ValueCorrectedForDownscale(); | |
1226 | ||
1227 | if ( TString(what).Contains("RATE") ) | |
1228 | { | |
1229 | value = s->Rate(); | |
1230 | } | |
1231 | ||
1232 | integral += value; | |
1233 | mean += value; | |
1234 | ||
1235 | y.push_back(value); | |
1236 | } | |
1237 | ||
1238 | if ( fRunList.size() ) { | |
1239 | mean /= fRunList.size(); | |
1240 | } | |
1241 | ||
1242 | AliInfo(Form("Integral %e mean %e",integral,mean)); | |
1243 | ||
1244 | return new TGraph(x.size(),&x[0],&y[0]); | |
1245 | } | |
1246 | ||
2f331ac9 | 1247 | //______________________________________________________________________________ |
1248 | TGraph* AliAnalysisTriggerScalers::PlotTriggerEvolution(const char* triggerClassName, | |
1249 | const char* what, | |
1250 | bool draw, | |
e538121a | 1251 | double* mean, |
1252 | bool removeZeros) | |
2f331ac9 | 1253 | { |
1254 | /// Make a graph of "what" for a given trigger class. | |
1255 | /// | |
1256 | /// What can be : | |
1257 | /// | |
1258 | /// - L0B (level 0 before any veto applied) | |
1259 | /// - L0A (level 0 after all vetoes) | |
1260 | /// - L0AOVERB (L0A/L0B) | |
1261 | /// - mu ( = -TMath::Log( 1 - P(0) ) where P(0) is the proba to have zero collisions in a bunch crossing) | |
1262 | /// - pileupfactor = mu/(1-exp(-mu)) : the factor to apply to correct the cint1b count rate | |
1263 | /// - vsnb = L0B/(NumberOfInteractingBunches*11245) | |
1afce1ce | 1264 | /// - NBCX = NumberOfInteractingBunches |
2f331ac9 | 1265 | |
c665b011 | 1266 | TString swhat(what); |
1267 | swhat.ToUpper(); | |
58b19963 | 1268 | |
c665b011 | 1269 | if ( swhat.Contains(";")) |
1270 | { | |
1271 | swhat.ReplaceAll(";",","); | |
1272 | AliWarningClass("; is not a valid separator, replaced it with ,"); | |
1273 | } | |
1274 | ||
1275 | int color(1); | |
1276 | int marker(20); | |
58b19963 | 1277 | |
c665b011 | 1278 | TObjArray* a = swhat.Tokenize(","); |
1279 | if (a->GetEntries()>1) | |
1280 | { | |
1281 | TObjArray graphs; | |
1282 | TIter next(a); | |
1283 | TObjString* str(0x0); | |
1284 | Double_t ymin(TMath::Limits<Double_t>::Max()); | |
1285 | Double_t ymax(0); | |
1286 | Double_t xmin(TMath::Limits<Double_t>::Max()); | |
1287 | Double_t xmax(0); | |
1288 | TGraph* g(0x0); | |
1289 | ||
1290 | while ( ( str = static_cast<TObjString*>(next())) ) | |
1291 | { | |
e538121a | 1292 | g = PlotTriggerEvolution(triggerClassName,str->String().Data(),false,0x0,removeZeros); |
c665b011 | 1293 | graphs.Add(g); |
1294 | for ( Int_t i = 0; i < g->GetN(); ++i ) | |
1295 | { | |
1296 | ymin = TMath::Min(ymin,g->GetY()[i]); | |
1297 | ymax = TMath::Max(ymax,g->GetY()[i]); | |
1298 | } | |
1299 | xmin = TMath::Min(xmin,g->GetX()[0]); | |
1300 | xmax = TMath::Max(xmax,g->GetX()[g->GetN()-1]); | |
1301 | } | |
1302 | ||
1303 | gStyle->SetOptTitle(0); | |
1304 | ||
1305 | AliInfoClass(Form("x %e ; %e y %e ; %e",xmin,xmax,ymin,ymax)); | |
1306 | TH2* h = new TH2F("h",triggerClassName,100,xmin,xmax,100,ymin,ymax); | |
1307 | h->SetStats(kFALSE); | |
1308 | h->GetXaxis()->SetTimeDisplay(1); | |
1309 | h->GetXaxis()->SetTimeFormat("%d/%m %H:%M"); | |
1310 | h->GetXaxis()->SetTimeOffset(0,"gmt"); | |
1311 | h->GetXaxis()->SetNdivisions(505); | |
1312 | h->Draw(); | |
58b19963 | 1313 | |
c665b011 | 1314 | TIter nextGraph(&graphs); |
1315 | ||
1316 | while ( ( g = static_cast<TGraph*>(nextGraph())) ) | |
1317 | { | |
1318 | AliInfoClass(g->GetTitle()); | |
1319 | g->Draw("lp"); | |
1320 | g->SetLineColor(color); | |
1321 | g->SetMarkerColor(color); | |
1322 | g->SetMarkerStyle(marker); | |
1323 | ++color; | |
1324 | ++marker; | |
1325 | } | |
09d5920f | 1326 | delete a; |
c665b011 | 1327 | return 0x0; |
1328 | } | |
09d5920f | 1329 | delete a; |
58b19963 | 1330 | |
2f331ac9 | 1331 | std::vector<int> vx; |
1332 | std::vector<int> vex; | |
1333 | std::vector<double> vy; | |
1334 | std::vector<double> vey; | |
1335 | ||
2f331ac9 | 1336 | |
1337 | if (mean) *mean=0; | |
1338 | double nvalues(0); | |
1339 | ||
2f331ac9 | 1340 | for ( std::vector<int>::size_type iRun = 0; iRun < fRunList.size(); ++iRun ) |
1341 | { | |
1342 | Int_t runNumber = fRunList[iRun]; | |
1343 | ||
58b19963 | 1344 | AliTriggerConfiguration* tc(0x0); |
1345 | AliTriggerRunScalers* trs(0x0); | |
1346 | AliLHCData* lhc(0x0); | |
2f331ac9 | 1347 | |
58b19963 | 1348 | GetCTPObjects(runNumber,tc,trs,lhc); |
2f331ac9 | 1349 | |
58b19963 | 1350 | Int_t numberOfInteractingBunches = NumberOfInteractingBunches(*lhc); |
2f331ac9 | 1351 | |
1352 | const TObjArray* scalers = trs->GetScalersRecords(); | |
1353 | ||
1354 | const TObjArray& trClasses = tc->GetClasses(); | |
1355 | TIter next(&trClasses); | |
1356 | AliTriggerClass* triggerClass; | |
1357 | ||
1358 | while ( ( triggerClass = static_cast<AliTriggerClass*>(next()) ) ) | |
1359 | { | |
1360 | UChar_t index = GetIndex(triggerClass->GetMask()); | |
1361 | ||
1362 | if ( !TString(triggerClass->GetName()).Contains(triggerClassName) ) continue; | |
1363 | ||
1364 | TIter nextScaler(scalers); | |
1365 | AliTriggerScalersRecord* record; | |
1366 | UInt_t reft(0); | |
1367 | UInt_t refl0b(0); | |
1368 | UInt_t refl1b(0); | |
1369 | UInt_t refl2b(0); | |
1370 | UInt_t refl0a(0); | |
1371 | UInt_t refl1a(0); | |
1372 | UInt_t refl2a(0); | |
1373 | Bool_t first(kTRUE); | |
1374 | ||
1375 | while ( ( record = static_cast<AliTriggerScalersRecord*>(nextScaler()) ) ) | |
1376 | { | |
1377 | const AliTriggerScalers* scaler = record->GetTriggerScalersForClass(index); | |
1378 | ||
e538121a | 1379 | |
2f331ac9 | 1380 | const AliTimeStamp* ats = record->GetTimeStamp(); |
1381 | ||
1382 | UInt_t seconds = ats->GetSeconds();// - TTimeStamp::GetZoneOffset(); | |
1383 | ||
1384 | TTimeStamp ts(seconds,ats->GetMicroSecs()); | |
1385 | ||
1386 | UInt_t l0b = scaler->GetLOCB() - refl0b; | |
1387 | UInt_t l0a = scaler->GetLOCA() - refl0a; | |
1388 | UInt_t l1b = scaler->GetL1CB() - refl1b; | |
1389 | UInt_t l1a = scaler->GetL1CA() - refl1a; | |
1390 | UInt_t l2b = scaler->GetL2CB() - refl2b; | |
1391 | UInt_t l2a = scaler->GetL2CA() - refl2a; | |
1392 | UInt_t timelapse = seconds - reft; | |
58b19963 | 1393 | |
1afce1ce | 1394 | if ( removeZeros && ( l0b <= 2 || ( l0a <= 2 && l0a != 0 ) || timelapse <= 9 ) ) |
1395 | { | |
1396 | AliInfo(Form("Skipping point for %s l0b %d l0a %d timelapse %d ts %s", | |
1397 | triggerClassName,l0b,l0a,timelapse,ts.AsString())); | |
1398 | continue; | |
1399 | } | |
2f331ac9 | 1400 | |
1401 | reft = seconds; | |
1402 | refl0b = scaler->GetLOCB(); | |
1403 | refl0a = scaler->GetLOCA(); | |
1404 | refl1b = scaler->GetL1CB(); | |
1405 | refl1a = scaler->GetL1CA(); | |
1406 | refl2b = scaler->GetL2CB(); | |
1407 | refl2a = scaler->GetL2CA(); | |
1408 | ||
1409 | if ( first ) | |
1410 | { | |
1411 | first = kFALSE; | |
1412 | continue; | |
1413 | } | |
1414 | ||
1415 | double value(1.0); | |
e538121a | 1416 | double error(0.0); |
2f331ac9 | 1417 | |
1418 | if (swhat.Contains("L0AOVERB") ) | |
1419 | { | |
1420 | value = l0a*1.0/l0b; | |
b2f6b613 | 1421 | if ( l0a > 0 ) |
1422 | { | |
1423 | error = value*TMath::Sqrt(1.0/l0b+1.0/l0a); | |
1424 | } | |
1425 | else | |
1426 | { | |
1427 | error = 0.0; | |
1428 | } | |
2f331ac9 | 1429 | } |
1430 | else if ( swhat.Contains("L0B") ) | |
1431 | { | |
1432 | value = l0b; | |
1433 | } | |
1434 | else if (swhat.Contains("L0A") ) | |
1435 | { | |
1436 | value = l0a; | |
1437 | } | |
1438 | else if ( swhat.Contains("L1B") ) | |
1439 | { | |
1440 | value = l1b; | |
1441 | } | |
1442 | else if (swhat.Contains("L1A") ) | |
1443 | { | |
1444 | value = l1a; | |
1445 | } | |
1446 | else if ( swhat.Contains("L2B") ) | |
1447 | { | |
1448 | value = l2b; | |
1449 | } | |
1450 | else if (swhat.Contains("L2A") ) | |
1451 | { | |
1452 | value = l2a; | |
1453 | } | |
1454 | else if ( swhat.Contains("MU") ) | |
1455 | { | |
e538121a | 1456 | value = Mu(l0b/timelapse,numberOfInteractingBunches); |
58b19963 | 1457 | error = 0.0; // FIXME |
2f331ac9 | 1458 | } |
1459 | else if ( swhat.Contains("PILEUPFACTOR") ) | |
1460 | { | |
e538121a | 1461 | Double_t mu = Mu(l0b/timelapse,numberOfInteractingBunches); |
2f331ac9 | 1462 | value = mu/(1-TMath::Exp(-mu)); |
58b19963 | 1463 | error = -1.0; // FIXME |
2f331ac9 | 1464 | } |
1465 | else if ( swhat.Contains("VSNB") ) | |
1466 | { | |
e538121a | 1467 | value = l0b/(11245.0*numberOfInteractingBunches); |
58b19963 | 1468 | error = -1.0; // FIXME |
2f331ac9 | 1469 | } |
1afce1ce | 1470 | else if ( swhat.Contains("NBCX")) |
1471 | { | |
1472 | value = numberOfInteractingBunches; | |
1473 | error = 1.0; // FIXME | |
1474 | } | |
2f331ac9 | 1475 | else |
1476 | { | |
1477 | value = timelapse; | |
1478 | AliInfo(Form("Unknown what %s",what)); | |
1479 | } | |
1480 | ||
1481 | if ( ! swhat.Contains("OVER") && ! swhat.Contains("RATIO") && | |
c665b011 | 1482 | ! swhat.Contains("MU") && ! swhat.Contains("PILEUPFACTOR") && |
1afce1ce | 1483 | ! swhat.Contains("RAW") & ! swhat.Contains("NBCX") ) |
2f331ac9 | 1484 | { |
1485 | value /= timelapse; | |
1486 | } | |
1487 | ||
1488 | if ( !TMath::Finite(value) ) continue; | |
1489 | ||
58b19963 | 1490 | if ( !swhat.Contains("L0AOVERB") && error > 0 ) |
e538121a | 1491 | { |
1492 | error = value >0 ? 1.0/TMath::Sqrt(value) : 0.0; | |
1493 | } | |
58b19963 | 1494 | |
e538121a | 1495 | if (removeZeros && TMath::Abs(value) < 1E-6 ) |
1496 | { | |
58b19963 | 1497 | continue; |
e538121a | 1498 | } |
2f331ac9 | 1499 | if (mean) |
1500 | { | |
1501 | (*mean) += value; | |
e538121a | 1502 | nvalues += 1.0; |
2f331ac9 | 1503 | } |
1504 | ||
1505 | vx.push_back(seconds); | |
81dfe194 | 1506 | vex.push_back(1); |
2f331ac9 | 1507 | |
1508 | vy.push_back(value); | |
1509 | ||
e538121a | 1510 | vey.push_back(error); |
2f331ac9 | 1511 | |
1512 | } | |
e538121a | 1513 | |
2f331ac9 | 1514 | } |
1515 | ||
2f331ac9 | 1516 | } |
58b19963 | 1517 | |
e538121a | 1518 | if (mean && nvalues) |
1519 | { | |
1520 | (*mean) /= nvalues; | |
1521 | } | |
1522 | ||
c665b011 | 1523 | if ( vx.empty() ) return 0; |
2f331ac9 | 1524 | |
1525 | TGraph* g = MakeGraph(vx,vex,vy,vey); | |
1526 | TString title(Form("TriggerEvolution%s-%s",triggerClassName,swhat.Data())); | |
1527 | ||
1528 | g->SetName(title.Data()); | |
1529 | g->SetTitle(title.Data()); | |
1530 | ||
1531 | g->GetYaxis()->SetTitle(title.Data()); | |
1532 | ||
1533 | if (draw) | |
1534 | { | |
e538121a | 1535 | TCanvas* c = NewCanvas(g->GetName()); |
c665b011 | 1536 | g->SetLineColor(color); |
1537 | g->SetMarkerColor(color); | |
1538 | g->SetMarkerStyle(marker); | |
1539 | g->Draw("ALP"); | |
e538121a | 1540 | c->SaveAs(Form("%s.png",title.Data())); |
2f331ac9 | 1541 | } |
1542 | ||
1543 | ||
1544 | return g; | |
1545 | } | |
1546 | ||
2f331ac9 | 1547 | //______________________________________________________________________________ |
1548 | TGraph* AliAnalysisTriggerScalers::PlotTriggerRatio(const char* triggerClassName1, | |
1549 | const char* what1, | |
1550 | const char* triggerClassName2, | |
1551 | const char* what2) | |
1552 | { | |
e538121a | 1553 | // Plot the ratio of two scalers. |
1554 | // Get one value per run. | |
1555 | ||
2f331ac9 | 1556 | std::vector<Float_t> x; |
1557 | std::vector<Float_t> y; | |
1558 | ||
1559 | for ( std::vector<int>::size_type i = 0; i < fRunList.size(); ++i ) | |
1560 | { | |
1561 | Int_t runNumber = fRunList[i]; | |
1562 | ||
1563 | AliAnalysisTriggerScalerItem* s1 = GetTriggerScaler(runNumber,what1,triggerClassName1); | |
1564 | AliAnalysisTriggerScalerItem* s2 = GetTriggerScaler(runNumber,what2,triggerClassName2); | |
1565 | ||
1566 | if (!s1 || !s2) continue; | |
1567 | ||
1568 | x.push_back(runNumber); | |
1569 | ||
1570 | Float_t ratio(0); | |
1571 | ||
1572 | if ( s2->ValueCorrectedForDownscale() > 0 ) | |
1573 | { | |
1574 | ratio = s1->ValueCorrectedForDownscale()/s2->ValueCorrectedForDownscale(); | |
1575 | } | |
1576 | ||
1577 | y.push_back(ratio); | |
1578 | ||
58b19963 | 1579 | AliDebug(1,Form("RUN %09d %20s (%s) %12llu (%5d) %20s (%s) %12llu (%5d) R %7.2f", |
2f331ac9 | 1580 | runNumber, |
1581 | triggerClassName1,what1, | |
1582 | s1->Value(),s1->DownscalingFactor(), | |
1583 | triggerClassName2,what2, | |
1584 | s2->Value(),s2->DownscalingFactor(), | |
1585 | ratio)); | |
2f331ac9 | 1586 | } |
1587 | ||
1588 | return new TGraph(x.size(),&x[0],&y[0]); | |
1589 | } | |
1590 | ||
58b19963 | 1591 | //______________________________________________________________________________ |
1592 | TGraph* AliAnalysisTriggerScalers::PlotTriggerRatioEvolution(const char* triggerClassName1, | |
1593 | const char* what1, | |
1594 | const char* triggerClassName2, | |
1595 | const char* what2) | |
1596 | { | |
1597 | /// Plots the evolution of one trigger ratio | |
1598 | ||
1afce1ce | 1599 | Bool_t draw(kFALSE); |
1600 | Bool_t removeZeros(kFALSE); | |
1601 | ||
1602 | TGraph* g1 = PlotTriggerEvolution(triggerClassName1,what1,draw,0x0,removeZeros); | |
1603 | TGraph* g2 = PlotTriggerEvolution(triggerClassName2,what2,draw,0x0,removeZeros); | |
58b19963 | 1604 | |
1605 | if (!g1 || !g2) return 0x0; | |
1606 | ||
1607 | if ( g1->GetN() != g2->GetN() ) | |
1608 | { | |
1609 | AliError("Oups. Did not get the same number of points for the 2 graphs ?!"); | |
1610 | return 0x0; | |
1611 | } | |
1612 | ||
1613 | Double_t x1,x2; | |
1614 | Double_t y1,y2; | |
1615 | Double_t x1err,x2err; | |
1616 | Double_t y1err,y2err; | |
1617 | ||
1618 | TGraphErrors* g = new TGraphErrors(g1->GetN()); | |
1619 | Int_t j(0); | |
1620 | ||
1621 | for ( Int_t i = 0; i < g1->GetN(); ++i ) | |
1622 | { | |
1623 | g1->GetPoint(i,x1,y1); | |
1624 | g2->GetPoint(i,x2,y2); | |
1625 | ||
1626 | x1err = g1->GetErrorX(i); | |
1627 | x2err = g2->GetErrorX(i); | |
1628 | ||
1629 | y1err = g1->GetErrorY(i); | |
1630 | y2err = g2->GetErrorY(i); | |
1631 | ||
1632 | if (x1!=x2) | |
1633 | { | |
1634 | AliError(Form("Points at %d don't have the same x ! ",i)); | |
1635 | continue; | |
1636 | } | |
1637 | ||
1638 | Double_t y(0.0); | |
1639 | ||
1640 | if ( TMath::Abs(y2) > 1E-12 ) | |
1641 | { | |
1642 | y = y1/y2; | |
1643 | } | |
1644 | ||
1645 | Double_t yerr(0.0); | |
1646 | ||
1647 | if ( TMath::Abs(x1) > 1E-12) | |
1648 | { | |
1649 | yerr += TMath::Sqrt(x1err*x1err/(x1*x1)); | |
1650 | } | |
1651 | ||
1652 | if ( TMath::Abs(x2) > 1E-12) | |
1653 | { | |
1654 | yerr += TMath::Sqrt(x2err*x2err/(x2*x2)); | |
1655 | } | |
1656 | ||
1657 | yerr *= y; | |
1658 | ||
1659 | g->SetPoint(j,x1,y); | |
1660 | g->SetPointError(j,x1err,yerr); | |
1661 | ||
1662 | ++j; | |
1663 | } | |
1664 | ||
1665 | delete g1; | |
1666 | delete g2; | |
1667 | ||
1668 | TimeAxis(g); | |
1669 | ||
1670 | return g; | |
1671 | } | |
1672 | ||
2f331ac9 | 1673 | //______________________________________________________________________________ |
c665b011 | 1674 | void AliAnalysisTriggerScalers::Print(Option_t* /* opt */) const |
1675 | { | |
1676 | /// print our runlist | |
1677 | AliAnalysisTriggerScalers::PrintIntegers(fRunList,','); | |
1678 | } | |
1679 | ||
1680 | //______________________________________________________________________________ | |
1681 | void AliAnalysisTriggerScalers::PrintIntegers(const std::vector<int>& integers, | |
2f331ac9 | 1682 | const char sep, |
1683 | std::ostream& out) | |
1684 | { | |
1685 | /// print a list of integers | |
1686 | for ( std::vector<int>::size_type i = 0; i < integers.size(); ++i ) | |
1687 | { | |
1688 | out << integers[i] << sep; | |
1689 | } | |
1690 | out << std::endl; | |
1691 | } | |
1692 | ||
1693 | //______________________________________________________________________________ | |
1694 | void AliAnalysisTriggerScalers::ReadIntegers(const char* filename, | |
1695 | std::vector<int>& integers, | |
1696 | Bool_t resetVector) | |
1697 | { | |
1698 | /// Read integers from filename, where integers are either | |
1699 | /// separated by "," or by return carriage | |
1700 | std::ifstream in(gSystem->ExpandPathName(filename)); | |
1701 | int i; | |
1702 | ||
1703 | std::set<int> runset; | |
1704 | ||
1705 | if (!resetVector) | |
1706 | { | |
1707 | for ( std::vector<int>::size_type j = 0; j < integers.size(); ++ j ) | |
1708 | { | |
1709 | runset.insert(integers[j]); | |
1710 | } | |
1711 | } | |
1712 | ||
1713 | char line[10000]; | |
1714 | ||
1715 | in.getline(line,10000,'\n'); | |
1716 | ||
1717 | TString sline(line); | |
1718 | ||
1719 | if (sline.Contains(",")) | |
1720 | { | |
1721 | TObjArray* a = sline.Tokenize(","); | |
1722 | TIter next(a); | |
1723 | TObjString* s; | |
1724 | while ( ( s = static_cast<TObjString*>(next()) ) ) | |
1725 | { | |
1726 | runset.insert(s->String().Atoi()); | |
1727 | } | |
1728 | delete a; | |
1729 | } | |
1730 | else | |
1731 | { | |
1732 | runset.insert(sline.Atoi()); | |
1733 | ||
1734 | while ( in >> i ) | |
1735 | { | |
1736 | runset.insert(i); | |
1737 | } | |
1738 | } | |
1739 | ||
1740 | integers.clear(); | |
1741 | ||
1742 | for ( std::set<int>::const_iterator it = runset.begin(); it != runset.end(); ++it ) | |
1743 | { | |
1744 | integers.push_back((*it)); | |
1745 | } | |
1746 | ||
1747 | std::sort(integers.begin(),integers.end()); | |
1748 | } | |
1749 | ||
1750 | ||
1751 | //______________________________________________________________________________ | |
1752 | void AliAnalysisTriggerScalers::SetRunList(Int_t runNumber) | |
1753 | { | |
1754 | // Make the runlist be a single run | |
1755 | fRunList.clear(); | |
1756 | fRunList.push_back(runNumber); | |
1757 | } | |
1758 | ||
e538121a | 1759 | //______________________________________________________________________________ |
1760 | void AliAnalysisTriggerScalers::SetRunList(const std::vector<int>& runs) | |
1761 | { | |
1762 | // Make the runlist be a single run | |
1763 | fRunList = runs; | |
1764 | } | |
1765 | ||
1766 | //______________________________________________________________________________ | |
1767 | void AliAnalysisTriggerScalers::SetRunList(const std::set<int>& runs) | |
1768 | { | |
1769 | // Make the runlist be a single run | |
1770 | fRunList.clear(); | |
1771 | for ( std::set<int>::const_iterator it = runs.begin(); it != runs.end(); ++it ) | |
1772 | { | |
1773 | fRunList.push_back(*it); | |
1774 | } | |
1775 | } | |
1776 | ||
2f331ac9 | 1777 | //______________________________________________________________________________ |
1778 | void AliAnalysisTriggerScalers::SetRunList(const char* runlist) | |
1779 | { | |
1780 | // Read the runlist from an ASCII file or a comma separated list | |
1781 | // or a space separated list | |
1782 | ||
1783 | fRunList.clear(); | |
1784 | ||
1785 | if ( TString(runlist).Contains(",") || TString(runlist).Contains(" ") ) | |
1786 | { | |
1787 | TObjArray* runs = 0x0; | |
1788 | if ( TString(runlist).Contains(",") ) | |
1789 | { | |
1790 | runs = TString(runlist).Tokenize(","); | |
1791 | } | |
1792 | else | |
1793 | { | |
1794 | runs = TString(runlist).Tokenize(" "); | |
1795 | } | |
1796 | TIter next(runs); | |
1797 | TObjString* s; | |
1798 | std::set<int> runset; | |
1799 | ||
1800 | while ( ( s = static_cast<TObjString*>(next()) ) ) | |
1801 | { | |
1802 | runset.insert(s->String().Atoi()); | |
1803 | } | |
1804 | ||
1805 | for ( std::set<int>::const_iterator it = runset.begin(); it != runset.end(); ++it ) | |
1806 | { | |
1807 | fRunList.push_back((*it)); | |
1808 | } | |
1809 | ||
1810 | std::sort(fRunList.begin(),fRunList.end()); | |
1811 | ||
1812 | delete runs; | |
1813 | } | |
1814 | else | |
1815 | { | |
1816 | ReadIntegers(runlist,fRunList); | |
1817 | } | |
1818 | } | |
1819 | ||
1820 | //______________________________________________________________________________ | |
1821 | //______________________________________________________________________________ | |
1822 | //______________________________________________________________________________ | |
1823 | //______________________________________________________________________________ | |
1824 | //______________________________________________________________________________ | |
1825 | //______________________________________________________________________________ | |
1826 | //______________________________________________________________________________ | |
1827 | ||
1828 | ClassImp(AliAnalysisTriggerScalerItem) | |
1829 | ||
1830 | //______________________________________________________________________________ | |
1831 | const char* | |
1832 | AliAnalysisTriggerScalerItem::BCMaskName() const | |
e538121a | 1833 | { |
1834 | // return bc mask name | |
2f331ac9 | 1835 | if ( BCMask() ) return BCMask()->GetName(); else return ""; |
1836 | } | |
1837 | ||
1838 | //______________________________________________________________________________ | |
1839 | Int_t AliAnalysisTriggerScalerItem::Compare(const TObject* obj) const | |
1840 | { | |
e538121a | 1841 | /// compare two scaler items (by means of their run number only) |
2f331ac9 | 1842 | const AliAnalysisTriggerScalerItem* s = static_cast<const AliAnalysisTriggerScalerItem*>(obj); |
1843 | ||
1844 | if ( s->RunNumber() < RunNumber() ) | |
1845 | { | |
1846 | return -1; | |
1847 | } | |
1848 | else if ( s->RunNumber() > RunNumber() ) | |
1849 | { | |
1850 | return 1; | |
1851 | } | |
1852 | return 0; | |
1853 | } | |
1854 | ||
1855 | //______________________________________________________________________________ | |
1856 | void AliAnalysisTriggerScalerItem::Print(Option_t* opt) const | |
1857 | { | |
e538121a | 1858 | /// Printout |
2f331ac9 | 1859 | TString sopt(opt); |
1860 | ||
1861 | if ( RunNumber() > 0 ) | |
1862 | { | |
1863 | sopt.ToUpper(); | |
1864 | ||
1865 | if ( sopt.Contains("FULL") ) | |
1866 | { | |
1867 | } | |
1868 | else | |
1869 | { | |
1870 | std::cout << Form("RUN %6d CLASS %24s (%5s %4d BCs) SCALER %s %12llu DS %6d DURATION %ld", | |
1871 | RunNumber(),TriggerClassName(), | |
1872 | BCMaskName(), | |
1873 | BCMask() ? BCMask()->GetNUnmaskedBCs() : 0, | |
1874 | Level(), | |
1875 | Value(),DownscalingFactor(),Duration()) << std::endl; | |
1876 | } | |
1877 | } | |
1878 | else | |
1879 | { | |
1880 | std::cout << Form("CLASS %24s SCALER %20llu NRUNS %d", | |
1881 | TriggerClassName(),Value(),NofRuns()) << std::endl; | |
1882 | } | |
1883 | } |