Line data Source code
1 : #include "AliMUONBusPatchEvolution.h"
2 :
3 : /// \class AliMUONBusPatchEvolution
4 : ///
5 : /// This utility class can be used to perform two operations on the output of the MCHBPEVO DA
6 : /// (which is, on purpose, limited to the strict minimum) : extract alarm information
7 : /// from it, and augment it with derived information.
8 : ///
9 : /// The GetListOfFaultyBusPatches() can be used to get the list of bus patches with an occupancy above
10 : /// a given threshold.
11 : ///
12 : /// The Augment() method goes from the list of histograms (in the form of an AliMergeableCollection)
13 : /// describing the time evolution of the bus patches hit count, this class
14 : /// adds histograms to get the bus patches occupancy (=hit count / nevents / npads).
15 : /// Then the occupancy is also computed at different levels of the detector : detection
16 : /// element, DDL, chamber, station, in order to allow a global view of issues (if any)
17 : ///
18 : /// \author Laurent Aphecetche, Subatech
19 :
20 : ///\cond CLASSIMP
21 18 : ClassImp(AliMUONBusPatchEvolution)
22 : ///\endcond
23 :
24 : #include "AliCDBManager.h"
25 : #include "AliDAQ.h"
26 : #include "AliLog.h"
27 : #include "AliMergeableCollection.h"
28 : #include "AliMpBusPatch.h"
29 : #include "AliMpCDB.h"
30 : #include "AliMpDCSNamer.h"
31 : #include "AliMpDDL.h"
32 : #include "AliMpDDLStore.h"
33 : #include "AliMpDEIterator.h"
34 : #include "AliMpDEManager.h"
35 : #include "AliMpDetElement.h"
36 : #include "TH1F.h"
37 : #include "TList.h"
38 : #include "TMath.h"
39 : #include "TObjArray.h"
40 : #include "TObjString.h"
41 : #include "TString.h"
42 : #include <cassert>
43 : #include <set>
44 : #include <iostream>
45 :
46 : //_________________________________________________________________________________________________
47 : AliMUONBusPatchEvolution::AliMUONBusPatchEvolution(AliMergeableCollection& hc)
48 0 : : TObject(), fBPEVO(hc),fNofPads()
49 0 : {
50 0 : ComputeNumberOfPads();
51 0 : }
52 :
53 : //_________________________________________________________________________________________________
54 : AliMUONBusPatchEvolution::AliMUONBusPatchEvolution(AliMergeableCollection& hc,
55 : const std::map<int,int>& nofPadsPerBusPatch)
56 0 : : TObject(), fBPEVO(hc), fNofPads(nofPadsPerBusPatch)
57 0 : {
58 :
59 0 : }
60 :
61 : //_________________________________________________________________________________________________
62 : void AliMUONBusPatchEvolution::Augment()
63 : {
64 : /// From the list of histograms (in the form of an AliMergeableCollection)
65 : /// describing the time evolution of the bus patches hit count, this class
66 : /// adds histograms to get the bus patches occupancy (=hit count / nevents / npads).
67 : /// Then the occupancy is also computed at different levels of the detector : detection
68 : /// element, DDL, chamber, station, in order to allow a global view of issues (if any)
69 : ///
70 :
71 0 : if (FillNumberOfPads())
72 : {
73 0 : std::vector<int> timeResolutions;
74 :
75 0 : GetTimeResolutions(timeResolutions);
76 :
77 0 : AliInfo(Form("Number of time resolutions found : %lu",timeResolutions.size()));
78 :
79 0 : ShrinkTimeAxis();
80 :
81 0 : for ( std::vector<int>::size_type i = 0; i < timeResolutions.size(); ++i )
82 : {
83 0 : AliInfo(Form("TimeResolution: %ds",timeResolutions[i]));
84 0 : const int tr = timeResolutions[i];
85 0 : GroupByDE(tr);
86 0 : GroupByDDL(tr);
87 0 : GroupByChamber(tr);
88 0 : GroupByStation(tr);
89 : }
90 0 : Normalize();
91 0 : }
92 0 : }
93 :
94 : //_________________________________________________________________________________________________
95 : void AliMUONBusPatchEvolution::ComputeNumberOfPads()
96 : {
97 : /// Compute the number of pads in each bus patch
98 : /// from the mapping
99 :
100 0 : if (!fNofPads.empty()) return;
101 :
102 0 : AliCDBManager* cdbm = AliCDBManager::Instance();
103 :
104 0 : if (!cdbm->IsDefaultStorageSet())
105 : {
106 0 : Long_t id, size, flags, modtime;
107 0 : TDatime now;
108 :
109 0 : TString testPath;
110 :
111 0 : testPath.Form("/cvmfs/alice-ocdb.cern.ch/calibration/data/%d/OCDB",now.GetYear());
112 :
113 0 : if ( !gSystem->GetPathInfo(testPath.Data(),&id,&size,&flags,&modtime) )
114 : {
115 0 : if ( flags & 0x1 )
116 : {
117 0 : cdbm->SetDefaultStorage(Form("local://%s",testPath.Data()));
118 : }
119 : }
120 : else
121 : {
122 0 : cdbm->SetDefaultStorage("raw://");
123 : }
124 0 : }
125 :
126 0 : cdbm->SetRun(0);
127 :
128 0 : AliMpCDB::LoadAll();
129 :
130 0 : TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
131 : AliMpBusPatch* bp;
132 :
133 : Int_t total(0);
134 :
135 0 : while ((bp = static_cast<AliMpBusPatch*>(next())))
136 : {
137 : Int_t npads(0);
138 :
139 0 : Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(bp->GetId());
140 :
141 0 : AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(
142 : detElemId);
143 :
144 0 : for (Int_t i = 0; i < bp->GetNofManus(); ++i)
145 : {
146 0 : Int_t manuId = bp->GetManuId(i);
147 :
148 0 : npads += de->NofChannelsInManu(manuId);
149 : }
150 :
151 0 : fNofPads[bp->GetId()] = npads;
152 :
153 0 : total += npads;
154 : }
155 :
156 0 : assert(total==1064008);
157 0 : }
158 :
159 : //_________________________________________________________________________________________________
160 : TH1* AliMUONBusPatchEvolution::ExpandTimeAxis(const TH1& h, Int_t expansionTime, Int_t timeResolution)
161 : {
162 : /// Extend (by increasing the number of bins) the time range of h by nbins
163 : /// if expansion < 0 expansion is from before the start of x-axis, otherwise from the end.
164 :
165 0 : if (timeResolution<0)
166 : {
167 0 : timeResolution=GetTimeResolution(h);
168 0 : }
169 :
170 0 : if ( timeResolution<=0) return 0x0;
171 :
172 0 : const TAxis* timeAxis = h.GetXaxis();
173 :
174 0 : Int_t extraBins = TMath::Nint(TMath::Abs(expansionTime)/timeResolution);
175 :
176 0 : Int_t nbins = timeAxis->GetNbins() + extraBins;
177 0 : Double_t xmin = timeAxis->GetXmin();
178 0 : Double_t xmax = timeAxis->GetXmax();
179 :
180 0 : if ( expansionTime < 0 )
181 : {
182 0 : xmin += expansionTime;
183 0 : }
184 : else
185 : {
186 0 : xmax += expansionTime;
187 : }
188 :
189 0 : TH1* hnew = new TH1F(h.GetName(),h.GetTitle(),nbins,xmin,xmax);
190 0 : hnew->SetDirectory(0);
191 0 : hnew->GetXaxis()->SetTimeDisplay(1);
192 0 : hnew->GetXaxis()->SetTimeFormat(timeAxis->GetTimeFormat());
193 :
194 0 : for ( Int_t i = 1; i <= timeAxis->GetNbins(); ++i )
195 : {
196 0 : hnew->SetBinContent(i+extraBins,h.GetBinContent(i));
197 0 : hnew->SetBinError(i+extraBins,h.GetBinError(i));
198 : }
199 :
200 0 : if ( expansionTime < 0 )
201 : {
202 : /// Must update the time offset
203 0 : TTimeStamp origin;
204 0 : GetTimeOffset(h,origin);
205 0 : UInt_t ot = origin.GetSec();
206 0 : ot += expansionTime;
207 0 : origin.SetSec(ot);
208 0 : hnew->GetXaxis()->SetTimeOffset(origin.GetSec(),"gmt");
209 0 : GetTimeOffset(*hnew,origin);
210 0 : }
211 :
212 : return hnew;
213 0 : }
214 :
215 : //_________________________________________________________________________________________________
216 : Bool_t AliMUONBusPatchEvolution::FillNumberOfPads()
217 : {
218 : /// Fill histograms with the number of pads per element
219 : /// (BP, DE, DDL, chamber, station)
220 :
221 0 : assert(fNofPads.size()==888);
222 :
223 0 : if ( fBPEVO.Histo("/BUSPATCH/NPADS/BP0001"))
224 : {
225 : // work already done
226 0 : AliWarning("Already done. Not re-doing it...");
227 0 : return kFALSE;
228 : }
229 :
230 : Int_t total(0);
231 :
232 0 : AliMpDCSNamer dcs("TRACKER");
233 :
234 0 : std::map<int,int>::const_iterator it;
235 :
236 0 : for ( it = fNofPads.begin(); it != fNofPads.end(); ++it )
237 : {
238 0 : int busPatchId = it->first;
239 0 : int npads = it->second;
240 :
241 0 : TH1* h = new TH1F(Form("BP%04d", busPatchId), "number of pads", 1, 0,1);
242 :
243 0 : Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
244 :
245 0 : AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(
246 : detElemId);
247 :
248 0 : h->Fill(0.0, 1.0 * npads);
249 :
250 0 : TH1* hde = fBPEVO.Histo(Form("/DE/NPADS/DE%04d", detElemId));
251 0 : if (!hde) {
252 0 : hde = new TH1F(Form("DE%04d", detElemId), "number of pads", 1, 0,
253 : 1);
254 0 : fBPEVO.Adopt("/DE/NPADS/", hde);
255 : }
256 0 : hde->Fill(0.0, 1.0 * npads);
257 :
258 0 : Int_t ddlId = de->GetDdlId() + AliDAQ::DdlIDOffset("MUONTRK");
259 :
260 0 : TH1* hddl = fBPEVO.Histo(Form("/DDL/NPADS/DDL%d", ddlId));
261 0 : if (!hddl) {
262 0 : hddl = new TH1F(Form("DDL%d", ddlId), "number of pads", 1, 0, 1);
263 0 : fBPEVO.Adopt("/DDL/NPADS/", hddl);
264 : }
265 0 : hddl->Fill(0.0, 1.0 * npads);
266 :
267 0 : Int_t chamberId = 1 + AliMpDEManager::GetChamberId(detElemId);
268 0 : Int_t stationId = 1 + AliMpDEManager::GetChamberId(detElemId) / 2;
269 :
270 : TH1* hchamberSide(0x0);
271 : TH1* hstationSide(0x0);
272 :
273 0 : if (dcs.DCSAliasName(detElemId).Contains("Left")) {
274 0 : hchamberSide = fBPEVO.Histo(
275 0 : Form("/CHAMBER/NPADS/CHAMBER%dLEFT", chamberId));
276 0 : if (!hchamberSide) {
277 0 : hchamberSide = new TH1F(Form("CHAMBER%dLEFT", chamberId),
278 : "number of pads", 1, 0, 1);
279 0 : fBPEVO.Adopt("/CHAMBER/NPADS/", hchamberSide);
280 : }
281 0 : hstationSide = fBPEVO.Histo(
282 0 : Form("/STATION/NPADS/STATION%dLEFT", stationId));
283 0 : if (!hstationSide) {
284 0 : hstationSide = new TH1F(Form("STATION%dLEFT", stationId),
285 : "number of pads", 1, 0, 1);
286 0 : fBPEVO.Adopt("/STATION/NPADS/", hstationSide);
287 : }
288 : } else {
289 0 : if (dcs.DCSAliasName(detElemId).Contains("Right")) {
290 0 : hchamberSide = fBPEVO.Histo(
291 0 : Form("/CHAMBER/NPADS/CHAMBER%dRIGHT", chamberId));
292 0 : if (!hchamberSide) {
293 0 : hchamberSide = new TH1F(Form("CHAMBER%dRIGHT", chamberId),
294 : "number of pads", 1, 0, 1);
295 0 : fBPEVO.Adopt("/CHAMBER/NPADS/", hchamberSide);
296 : }
297 0 : hstationSide = fBPEVO.Histo(
298 0 : Form("/STATION/NPADS/STATION%dRIGHT", stationId));
299 0 : if (!hstationSide) {
300 0 : hstationSide = new TH1F(Form("STATION%dRIGHT", stationId),
301 : "number of pads", 1, 0, 1);
302 0 : fBPEVO.Adopt("/STATION/NPADS/", hstationSide);
303 : }
304 : }
305 : }
306 :
307 0 : hchamberSide->Fill(0.0, 1.0 * npads);
308 0 : hstationSide->Fill(0.0, 1.0 * npads);
309 :
310 0 : TH1* hchamber = fBPEVO.Histo(Form("/CHAMBER/NPADS/CHAMBER%d", chamberId));
311 0 : if (!hchamber) {
312 0 : hchamber = new TH1F(Form("CHAMBER%d", chamberId), "number of pads",
313 : 1, 0, 1);
314 0 : fBPEVO.Adopt("/CHAMBER/NPADS/", hchamber);
315 : }
316 0 : hchamber->Fill(0.0, 1.0 * npads);
317 :
318 0 : TH1* hstation = fBPEVO.Histo(Form("/STATION/NPADS/STATION%d", stationId));
319 0 : if (!hstation) {
320 0 : hstation = new TH1F(Form("STATION%d", stationId), "number of pads",
321 : 1, 0, 1);
322 0 : fBPEVO.Adopt("/STATION/NPADS/", hstation);
323 : }
324 0 : hstation->Fill(0.0, 1.0 * npads);
325 :
326 0 : total += npads;
327 :
328 0 : fBPEVO.Adopt("/BUSPATCH/NPADS/", h);
329 : }
330 :
331 : return kTRUE;
332 0 : }
333 :
334 :
335 : //_________________________________________________________________________________________________
336 : Bool_t AliMUONBusPatchEvolution::GetTimeOffset(const TH1& h, TTimeStamp& origin)
337 : {
338 : /// Assuming histogram h has a time axis, fills origin with its time offset and returns
339 : /// kTRUE. Otherwise returns kFALSE
340 : /// Assumes that the time offset is indicated in GMT
341 :
342 0 : const TAxis* x = h.GetXaxis();
343 :
344 0 : if ( x->GetTimeDisplay() )
345 : {
346 0 : TString tf = x->GetTimeFormat();
347 0 : Int_t ix = tf.Index('F');
348 0 : Int_t year,month,day;
349 0 : Int_t hour,minute,second;
350 0 : sscanf(tf(ix+1,tf.Length()-ix-1).Data(),"%4d-%02d-%02d %02d:%02d:%02d",&year,&month,&day,
351 : &hour,&minute,&second);
352 0 : origin.Set(year,month,day,hour,minute,second,0,kTRUE,0);
353 : return kTRUE;
354 0 : }
355 : else
356 : {
357 0 : return kFALSE;
358 : }
359 0 : }
360 :
361 : //_________________________________________________________________________________________________
362 : int AliMUONBusPatchEvolution::GetTimeResolution(const TH1& h)
363 : {
364 : // we assume the title ends with "xxx s bins"
365 : // and we try to find xxx ...
366 :
367 0 : TString title = h.GetTitle();
368 :
369 : int timeResolution(-1);
370 :
371 0 : TObjArray* a = title.Tokenize(" ");
372 0 : TString last = static_cast<TObjString*>(a->Last())->String();
373 0 : TString m = static_cast<TObjString*>(a->At(a->GetLast() - 1))->String();
374 :
375 0 : if (last != "bins" || m != "s") {
376 : std::cerr
377 0 : << "Histogram title does not match the expected pattern (... xxx s bins) : "
378 0 : << std::endl << h.GetTitle() << std::endl;
379 : } else {
380 : timeResolution =
381 0 : static_cast<TObjString*>(a->At(a->GetLast() - 2))->String().Atoi();
382 : }
383 0 : delete a;
384 :
385 : return timeResolution;
386 0 : }
387 :
388 :
389 : //_________________________________________________________________________________________________
390 : void AliMUONBusPatchEvolution::GetTimeResolutions(std::vector<int>& timeResolutions)
391 : {
392 0 : TIter next(fBPEVO.CreateIterator());
393 :
394 : TH1F* h(0x0);
395 :
396 0 : while ((h = static_cast<TH1F*>(next()))) {
397 0 : if ( TString(h->GetName()).BeginsWith("Nevents") )
398 : {
399 0 : int tr = GetTimeResolution(*h);
400 0 : if (tr > 0 )
401 : {
402 0 : timeResolutions.push_back(tr);
403 : }
404 0 : }
405 : }
406 :
407 0 : }
408 :
409 : //______________________________________________________________________________
410 : Bool_t AliMUONBusPatchEvolution::GetFaultyBusPatches(int timeResolution,
411 : int requiredEvents,
412 : float occupancyThreshold,
413 : std::map<int,double>& faultyBusPatchOccupancies)
414 : {
415 : /// Loop over all bus patches and compute their occupancy in the last nevents
416 : /// Return kFALSE if the number of required events was not reached
417 : ///
418 :
419 : // find how many bins should be considered, by finding in the Nevents histogram
420 : // how many of the latest bins are required to get an integral >= requiredEvents
421 0 : TH1* hnevents = fBPEVO.Histo(Form("Nevents%ds",timeResolution));
422 :
423 : int lastbin(0);
424 :
425 0 : for ( int i = hnevents->GetXaxis()->GetNbins()-1 ; i > 0 && lastbin == 0; --i )
426 : {
427 0 : if ( hnevents->GetBinContent(i) > 1 ) lastbin = i;
428 : }
429 :
430 : float nevents(0);
431 :
432 : int firstbin = lastbin;
433 :
434 0 : for ( firstbin = lastbin; firstbin > 0; --firstbin )
435 : {
436 0 : nevents += hnevents->GetBinContent(firstbin);
437 0 : if ( nevents > requiredEvents ) break;
438 : }
439 :
440 0 : if ( nevents < requiredEvents)
441 : {
442 0 : return kFALSE;
443 : }
444 :
445 0 : double dnevents = hnevents->Integral(firstbin,lastbin);
446 :
447 0 : for ( std::map<int,int>::const_iterator it = fNofPads.begin(); it != fNofPads.end(); ++it )
448 : {
449 0 : const int& buspatchId = it->first;
450 0 : const int& npads = it->second;
451 :
452 0 : TString bpName = Form("BP%04d",buspatchId);
453 :
454 0 : TH1* hbp = fBPEVO.Histo(Form("/BUSPATCH/HITS/%ds/%s",timeResolution,bpName.Data()));
455 :
456 0 : double occ = hbp->Integral(firstbin,lastbin) / dnevents / npads;
457 :
458 0 : if (occ > occupancyThreshold)
459 : {
460 0 : faultyBusPatchOccupancies[buspatchId] = occ;
461 0 : }
462 0 : }
463 :
464 : return kTRUE;
465 0 : }
466 :
467 : //_________________________________________________________________________________________________
468 : void AliMUONBusPatchEvolution::GroupByStation(int timeResolution)
469 : {
470 : /// From the histograms at chamber level, make the corresponding ones at station level
471 :
472 : int station(1);
473 :
474 0 : for (Int_t ich = 1; ich < 10; ich += 2) {
475 0 : TH1* h = fBPEVO.Histo(
476 0 : Form("/CHAMBER/HITS/%ds/CHAMBER%d", timeResolution, ich));
477 0 : TH1* h1 = fBPEVO.Histo(
478 0 : Form("/CHAMBER/HITS/%ds/CHAMBER%d", timeResolution, ich + 1));
479 :
480 0 : TH1* hstation = static_cast<TH1*>(h->Clone(Form("STATION%d", station)));
481 :
482 0 : hstation->Add(h1);
483 0 : fBPEVO.Adopt(Form("/STATION/HITS/%ds", timeResolution), hstation);
484 :
485 0 : h = fBPEVO.Histo(
486 0 : Form("/CHAMBER/HITS/%ds/CHAMBER%dLEFT", timeResolution, ich));
487 0 : h1 = fBPEVO.Histo(
488 0 : Form("/CHAMBER/HITS/%ds/CHAMBER%dLEFT", timeResolution,
489 : ich + 1));
490 :
491 0 : hstation = static_cast<TH1*>(h->Clone(Form("STATION%dLEFT", station)));
492 :
493 0 : hstation->Add(h1);
494 0 : fBPEVO.Adopt(Form("/STATION/HITS/%ds", timeResolution), hstation);
495 :
496 0 : h = fBPEVO.Histo(
497 0 : Form("/CHAMBER/HITS/%ds/CHAMBER%dRIGHT", timeResolution, ich));
498 0 : h1 = fBPEVO.Histo(
499 0 : Form("/CHAMBER/HITS/%ds/CHAMBER%dRIGHT", timeResolution,
500 : ich + 1));
501 :
502 0 : hstation = static_cast<TH1*>(h->Clone(Form("STATION%dRIGHT", station)));
503 :
504 0 : hstation->Add(h1);
505 0 : fBPEVO.Adopt(Form("/STATION/HITS/%ds", timeResolution), hstation);
506 :
507 0 : ++station;
508 : }
509 0 : }
510 :
511 : //_________________________________________________________________________________________________
512 : void AliMUONBusPatchEvolution::GroupByChamber(int timeResolution)
513 : {
514 : /// From the histograms at DE level, make the corresponding ones at chamber level
515 : /// with left and right separated as well.
516 :
517 0 : for (Int_t ich = 1; ich <= 10; ++ich) {
518 0 : AliMpDEIterator it;
519 :
520 0 : it.First(ich - 1);
521 :
522 : TH1* hchamberLeft(0x0);
523 : TH1* hchamberRight(0x0);
524 0 : TList listLeft;
525 0 : TList listRight;
526 0 : listLeft.SetOwner(kFALSE);
527 0 : listRight.SetOwner(kFALSE);
528 :
529 0 : AliMpDCSNamer dcs("TRACKER");
530 :
531 0 : while (!it.IsDone()) {
532 0 : Int_t detElemId = it.CurrentDEId();
533 :
534 0 : AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(
535 : detElemId);
536 :
537 0 : TH1* h = fBPEVO.Histo(
538 0 : Form("/DE/HITS/%ds/DE%04d", timeResolution, detElemId));
539 :
540 0 : if (dcs.DCSAliasName(detElemId).Contains("Left")) {
541 0 : if (!hchamberLeft) {
542 0 : hchamberLeft = static_cast<TH1*>(h->Clone(
543 0 : Form("CHAMBER%dLEFT", ich)));
544 0 : } else {
545 0 : listLeft.Add(h);
546 : }
547 : } else {
548 0 : if (!hchamberRight) {
549 0 : hchamberRight = static_cast<TH1*>(h->Clone(
550 0 : Form("CHAMBER%dRIGHT", ich)));
551 0 : } else {
552 0 : listRight.Add(h);
553 : }
554 : }
555 :
556 0 : it.Next();
557 : }
558 :
559 0 : hchamberLeft->Merge(&listLeft);
560 0 : hchamberRight->Merge(&listRight);
561 :
562 0 : hchamberLeft->SetLineColor(4);
563 0 : hchamberRight->SetLineColor(2);
564 :
565 0 : fBPEVO.Adopt(Form("/CHAMBER/HITS/%ds", timeResolution), hchamberLeft);
566 0 : fBPEVO.Adopt(Form("/CHAMBER/HITS/%ds", timeResolution), hchamberRight);
567 0 : TH1* hchamber = static_cast<TH1*>(hchamberLeft->Clone(
568 0 : Form("CHAMBER%d", ich)));
569 0 : hchamber->Add(hchamberRight);
570 0 : hchamber->SetLineColor(1);
571 0 : fBPEVO.Adopt(Form("/CHAMBER/HITS/%ds", timeResolution), hchamber);
572 0 : }
573 0 : }
574 :
575 : //_________________________________________________________________________________________________
576 : void AliMUONBusPatchEvolution::GroupByDDL(int timeResolution)
577 : {
578 : /// From the histograms at DE level, make the corresponding ones at DDL level
579 :
580 0 : Int_t nddls = AliDAQ::NumberOfDdls("MUONTRK");
581 0 : Int_t offset = AliDAQ::DdlIDOffset("MUONTRK");
582 :
583 0 : for (Int_t i = 0; i < nddls; ++i) {
584 0 : Int_t ddlId = offset + i;
585 :
586 0 : AliMpDDL* ddl = AliMpDDLStore::Instance()->GetDDL(i);
587 :
588 : TH1* hddl(0x0);
589 0 : TList list;
590 0 : list.SetOwner(kFALSE);
591 :
592 0 : for (Int_t ide = 0; ide < ddl->GetNofDEs(); ++ide) {
593 0 : Int_t detElemId = ddl->GetDEId(ide);
594 :
595 0 : TH1* h = fBPEVO.Histo(
596 0 : Form("/DE/HITS/%ds/DE%04d", timeResolution, detElemId));
597 :
598 0 : if (!hddl) {
599 0 : hddl = static_cast<TH1*>(h->Clone(Form("DDL%d", ddlId)));
600 0 : } else {
601 0 : list.Add(h);
602 : }
603 : }
604 :
605 0 : hddl->Merge(&list);
606 0 : fBPEVO.Adopt(Form("/DDL/HITS/%ds", timeResolution), hddl);
607 0 : }
608 0 : }
609 :
610 : //_________________________________________________________________________________________________
611 : void AliMUONBusPatchEvolution::GroupByDE(int timeResolution)
612 : {
613 : /// From the histograms at Bus Patch level (which is the original DA output)
614 : /// make the corresponding histograms at DE level
615 :
616 0 : AliMpDEIterator it;
617 :
618 0 : it.First();
619 :
620 0 : while (!it.IsDone()) {
621 0 : Int_t detElemId = it.CurrentDEId();
622 :
623 0 : AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(
624 : detElemId);
625 :
626 0 : TList list;
627 0 : list.SetOwner(kFALSE);
628 : TH1* hde(0x0);
629 :
630 0 : if (de->GetStationType() != AliMp::kStationTrigger) {
631 0 : for (Int_t i = 0; i < de->GetNofBusPatches(); ++i) {
632 0 : Int_t busPatchId = de->GetBusPatchId(i);
633 :
634 0 : TH1* h = fBPEVO.Histo(
635 0 : Form("/BUSPATCH/HITS/%ds/BP%04d", timeResolution,
636 : busPatchId));
637 :
638 0 : h->SetLineColor(1);
639 :
640 0 : if (!hde) {
641 0 : hde = static_cast<TH1*>(h->Clone());
642 0 : hde->SetName(Form("DE%04d", detElemId));
643 : } else {
644 0 : list.Add(h);
645 : }
646 : }
647 :
648 0 : hde->Merge(&list);
649 0 : fBPEVO.Adopt(Form("/DE/HITS/%ds", timeResolution), hde);
650 : }
651 :
652 0 : it.Next();
653 0 : }
654 :
655 0 : }
656 :
657 :
658 : //_________________________________________________________________________________________________
659 : void AliMUONBusPatchEvolution::Normalize()
660 : {
661 0 : TObjArray* a = fBPEVO.SortAllIdentifiers();
662 0 : TIter nextId(a);
663 : TObjString* sid;
664 :
665 0 : while ((sid = static_cast<TObjString*>(nextId()))) {
666 :
667 0 : if (!sid->String().Contains("HITS"))
668 : continue;
669 :
670 0 : TObjArray* parts = sid->String().Tokenize("/");
671 0 : TString npadsId("/");
672 :
673 0 : npadsId += static_cast<TObjString*>(parts->At(0))->String();
674 0 : npadsId += "/NPADS";
675 :
676 0 : TString sduration = static_cast<TObjString*>(parts->Last())->String();
677 :
678 0 : delete parts;
679 :
680 0 : Int_t duration = sduration.Atoi();
681 :
682 0 : TList* list = fBPEVO.CreateListOfObjectNames(sid->String().Data());
683 0 : TIter nextObject(list);
684 : TObjString* sobject;
685 0 : while ((sobject = static_cast<TObjString*>(nextObject())))
686 : {
687 0 : TString hname;
688 :
689 0 : hname.Form("%s%s", sid->String().Data(), sobject->String().Data());
690 :
691 0 : TH1* hnhits = fBPEVO.Histo(hname.Data());
692 :
693 0 : TString padname;
694 :
695 0 : padname.Form("%s/%s", npadsId.Data(), sobject->String().Data());
696 :
697 0 : TH1* hnpads = fBPEVO.Histo(padname.Data());
698 :
699 0 : Double_t npads = hnpads->GetBinContent(1);
700 :
701 0 : TH1* hocchz = static_cast<TH1*>(hnhits->Clone());
702 :
703 0 : hocchz->SetDirectory(0);
704 :
705 0 : hocchz->SetTitle("Occupancy (Hz)");
706 :
707 0 : hocchz->Scale(1.0 / npads / duration);
708 :
709 0 : TString occ = sid->String();
710 :
711 0 : occ.ReplaceAll("HITS", "OCCHZ");
712 :
713 0 : fBPEVO.Adopt(occ.Data(), hocchz);
714 :
715 0 : TH1* hocc = static_cast<TH1*>(hnhits->Clone());
716 :
717 0 : hocc->SetDirectory(0);
718 :
719 0 : hocc->SetTitle("Occupancy");
720 :
721 0 : occ.ReplaceAll("HZ", "");
722 :
723 0 : TH1* hnevents = fBPEVO.Histo(Form("Nevents%s", sduration.Data()));
724 :
725 0 : hocc->GetXaxis()->SetTimeDisplay(0); // to avoid bin inflation in Divide...
726 :
727 0 : hocc->Divide(hnhits,hnevents,1.0/npads,1.0);
728 :
729 0 : hocc->GetXaxis()->SetTimeDisplay(1);
730 :
731 0 : fBPEVO.Adopt(occ.Data(), hocc);
732 0 : }
733 :
734 0 : delete list;
735 0 : }
736 :
737 0 : delete a;
738 0 : }
739 :
740 :
741 : //_____________________________________________________________________________
742 : void
743 : AliMUONBusPatchEvolution::ShrinkTimeAxis()
744 : {
745 : /// remove unused bins (after the last used bin) in all histograms that
746 : /// have a time axis. Note that we _assume_ that at this
747 : /// point the collection indeed contains only histograms that have time bins
748 :
749 0 : TIter next(fBPEVO.CreateIterator());
750 :
751 0 : TH1F* h(0x0);
752 :
753 0 : std::map<int, int> lastbins;
754 0 : std::map<int, int> firstbins;
755 0 : std::map<int, int> nbins;
756 0 : std::map<int, std::vector<TH1F*> > histos;
757 :
758 0 : std::set<int> timeResolutions;
759 :
760 : // get the upper bin per time resolution (only one in order to stick to a common bin
761 : // definition for all histograms
762 :
763 0 : while ((h = static_cast<TH1F*>(next()))) {
764 :
765 0 : if (!h->GetXaxis()->GetTimeDisplay())
766 : continue;
767 :
768 0 : int timeResolution = GetTimeResolution(*h);
769 :
770 0 : if (timeResolution <= 0)
771 0 : continue;
772 :
773 0 : timeResolutions.insert(timeResolution);
774 :
775 0 : if (h->GetEntries()) {
776 0 : lastbins[timeResolution] = TMath::Max(lastbins[timeResolution],
777 0 : h->FindLastBinAbove(0.0));
778 :
779 0 : if (firstbins.count(timeResolution)) {
780 0 : firstbins[timeResolution] = TMath::Min(
781 0 : firstbins[timeResolution], h->FindFirstBinAbove(0.0));
782 0 : } else {
783 0 : firstbins[timeResolution] = h->FindFirstBinAbove(0.0);
784 : }
785 : }
786 :
787 0 : int nb = h->GetNbinsX();
788 :
789 0 : if (nbins.count(timeResolution)) {
790 0 : assert(nbins[timeResolution] = nb);
791 : } else {
792 0 : nbins[timeResolution] = nb;
793 : }
794 :
795 0 : histos[timeResolution].push_back(h);
796 0 : }
797 :
798 0 : std::set<int, int>::const_iterator it;
799 :
800 0 : TH1::AddDirectory (kFALSE);
801 :
802 0 : for (it = timeResolutions.begin(); it != timeResolutions.end(); ++it) {
803 :
804 0 : int timeRes = *it;
805 0 : int firstbin = firstbins[timeRes];
806 0 : int lastbin = lastbins[timeRes];
807 0 : int nb = nbins[timeRes];
808 0 : const std::vector<TH1F*>& v = histos[timeRes];
809 :
810 0 : std::map<int, std::vector<TH1F*> >::const_iterator hit;
811 0 : for (std::vector<TH1F*>::size_type iv = 0; iv < v.size(); ++iv) {
812 0 : TH1F* hold = static_cast<TH1F*>(v[iv]);
813 :
814 0 : TH1F* hnew = new TH1F(hold->GetName(), hold->GetTitle(),
815 0 : lastbin - firstbin + 1, hold->GetBinLowEdge(firstbin),
816 0 : hold->GetBinLowEdge(lastbin) + hold->GetBinWidth(lastbin));
817 :
818 0 : Double_t nentries = hold->GetEntries();
819 :
820 0 : for (int i = firstbin; i <= lastbin; ++i) {
821 0 : hnew->SetBinContent(i - firstbin + 1, hold->GetBinContent(i));
822 : }
823 :
824 0 : TString timeFormat = hold->GetXaxis()->GetTimeFormat();
825 :
826 0 : hnew->Copy(*hold);
827 :
828 0 : hold->SetEntries(nentries);
829 :
830 0 : hold->GetXaxis()->SetTimeFormat(timeFormat.Data());
831 0 : hold->GetXaxis()->SetTimeDisplay(1);
832 :
833 0 : delete hnew;
834 0 : }
835 0 : }
836 0 : }
837 :
838 :
|