]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONTrackerData.cxx
- Update to read the "new" data format for the TailCancelation Filter Analysis
[u/mrichter/AliRoot.git] / MUON / AliMUONTrackerData.cxx
CommitLineData
0145e89a 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
18#include "AliMUONTrackerData.h"
19
8741815f 20#include "AliCodeTimer.h"
e83120bd 21#include "AliDAQ.h"
8741815f 22#include "AliLog.h"
23#include "AliMUON1DArray.h"
24#include "AliMUON1DMap.h"
25#include "AliMUON2DMap.h"
0145e89a 26#include "AliMUONCalibParamND.h"
8741815f 27#include "AliMUONSparseHisto.h"
0145e89a 28#include "AliMUONVStore.h"
29#include "AliMpBusPatch.h"
8741815f 30#include "AliMpConstants.h"
ab167304 31#include "AliMpCDB.h"
0145e89a 32#include "AliMpDDLStore.h"
ab167304 33#include "AliMpManuStore.h"
0145e89a 34#include "AliMpDEIterator.h"
8741815f 35#include "AliMpDEManager.h"
0145e89a 36#include "AliMpDetElement.h"
49e110ec 37#include "AliMpDCSNamer.h"
8741815f 38#include "AliMpManuIterator.h"
168e9c4d 39#include "AliMpEncodePair.h"
a499c7d9 40#include "AliMpSegmentation.h"
0145e89a 41#include <Riostream.h>
e83120bd 42#include <TClass.h>
0145e89a 43#include <TMath.h>
44#include <TObjArray.h>
45#include <TObjString.h>
46#include <TString.h>
7eafe398 47#include <TTimeStamp.h>
0145e89a 48#include <TVector2.h>
7eafe398 49#include <cassert>
0145e89a 50#include <float.h>
51
52/// \class AliMUONTrackerData
53///
54/// Implementation of AliMUONVTrackerData class
55///
56/// \author Laurent Aphecetche, Subatech
57
58///\cond CLASSIMP
59ClassImp(AliMUONTrackerData)
60///\endcond
61
62const Int_t AliMUONTrackerData::fgkExtraDimension = 2;
63const Int_t AliMUONTrackerData::fgkVirtualExtraDimension = 1;
64
65//_____________________________________________________________________________
66AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
67 Int_t dimension,
49419555 68 Bool_t issingleevent)
0145e89a 69: AliMUONVTrackerData(name,title),
49419555 70fIsSingleEvent(issingleevent),
0145e89a 71fChannelValues(0x0),
72fManuValues(0x0),
73fBusPatchValues(0x0),
74fDEValues(0x0),
75fChamberValues(0x0),
76fPCBValues(0x0),
49419555 77fDimension(External2Internal(dimension)+fgkExtraDimension),
e83120bd 78fNevents(0),
0145e89a 79fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
8741815f 80fExternalDimensionNames(new TObjArray(dimension)),
0145e89a 81fExternalDimension(dimension),
8741815f 82fHistogramming(new Int_t[fExternalDimension]),
0edb62c4 83fHistos(0x0),
10eb3d17 84fXmin(0.0),
e13620cd 85fXmax(0.0),
0edb62c4 86fIsChannelLevelEnabled(kTRUE),
e83120bd 87fIsManuLevelEnabled(kTRUE),
06bc44ee 88fIsBustPatchLevelEnabled(kTRUE),
89fIsPCBLevelEnabled(kTRUE),
e83120bd 90fNofDDLs(0),
91fNofEventsPerDDL(0x0)
0145e89a 92{
93 /// ctor
a4dcc3f8 94 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
8741815f 95 fExternalDimensionNames->SetOwner(kTRUE);
0145e89a 96 fDimensionNames->SetOwner(kTRUE);
97 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
98 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
99 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
100 Clear();
101}
102
7eafe398 103//_____________________________________________________________________________
104AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
105 const AliMUONVStore& manuValues)
106: AliMUONVTrackerData(name,title),
107fIsSingleEvent(kFALSE),
108fChannelValues(0x0),
109fManuValues(0x0),
110fBusPatchValues(0x0),
111fDEValues(0x0),
112fChamberValues(0x0),
113fPCBValues(0x0),
114fDimension(0),
115fNevents(0),
116fDimensionNames(0x0),
117fExternalDimensionNames(0x0),
118fExternalDimension(0),
119fHistogramming(0x0),
120fHistos(0x0),
121fXmin(0.0),
122fXmax(0.0),
123fIsChannelLevelEnabled(kFALSE),
124fIsManuLevelEnabled(kTRUE),
06bc44ee 125fIsBustPatchLevelEnabled(kTRUE),
126fIsPCBLevelEnabled(kTRUE),
7eafe398 127fNofDDLs(0),
128fNofEventsPerDDL(0x0)
129{
130 /// ctor with pre-computed values at the manu level
131 /// In this case, we force fIsChannelLevelEnabled = kFALSE
132 /// ctor
133
134 if (manuValues.GetSize()==0)
135 {
136 AliFatal("Cannot create a tracker data from nothing in that case !");
137 }
138
139 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
140 {
141 AliError("Cannot work without (full) mapping");
142 return;
143 }
144
145 TIter next(manuValues.CreateIterator());
146 AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
147
148 Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
149
150 fDimension = External2Internal(dimension)+fgkExtraDimension;
151
152 fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
153 fExternalDimensionNames = new TObjArray(dimension);
154 fExternalDimension = dimension;
155 fHistogramming = new Int_t[fExternalDimension];
a4dcc3f8 156 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
7eafe398 157
158 fExternalDimensionNames->SetOwner(kTRUE);
159 fDimensionNames->SetOwner(kTRUE);
160 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
161 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
162 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
163 Clear();
164 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
165 AssertStores();
166
167 next.Reset();
168 AliMUONVCalibParam* external;
169
170 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
171 {
172 Int_t detElemId, manuId;
173
174 GetDEManu(*external,detElemId,manuId);
175
176 AliMUONVCalibParam* chamber(0x0);
177 AliMUONVCalibParam* de(0x0);
178 AliMUONVCalibParam* busPatch(0x0);
179 AliMUONVCalibParam* pcb(0x0);
180 AliMUONVCalibParam* manu(0x0);
181 AliMUONVCalibParam* channel(0x0);
182 AliMpDetElement* mpde(0x0);
183
184 AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,manuId,0);
185 // as external, but without event count
186 wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
187 wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
188 wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
189 wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
190
191 Int_t mid = GetParts(wec,chamber,de,busPatch,pcb,manu,channel,mpde);
192
193 if ( manuId != mid )
194 {
195 AliError(Form("Something is wrong for DE %5d : manuId = %d vs mid = %d",detElemId,manuId,mid));
196 continue;
197 }
198
199 if ( manuId < 0 )
200 {
201 AliError("Got a < 0 manuId. Should not happen here !");
202 continue;
203 }
204
205 assert(channel==0x0);
206
207 Int_t n1 = manu->ValueAsInt(0,IndexOfNumberDimension());
208 Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
209 if ( n1 != n2 )
210 {
211 AliError(Form("Incoherent number of manu channels for DE %5d MANU %5d : %d vs %d",
212 detElemId,manuId,n1,n2));
213 }
214
215 Int_t nevt = external->ValueAsInt(0,4);
216
217 Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
218
219 Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus(busPatchId);
220
221 if ( nevents[ddl] == 0 )
222 {
223 nevents[ddl] = nevt;
224 }
225 else
226 {
227 if ( nevents.At(ddl) != nevt )
228 {
229 AliError(Form("Nevt mismatch for DE %5d MANU %5d DDL %d : %d vs %d",
230 detElemId,manuId,ddl,nevents.At(ddl),nevt));
231 continue;
232 }
233 }
234
235 for ( Int_t i = 0; i < wec->Dimension()-1; ++i )
236 {
237 manu->SetValueAsDouble(0,i,manu->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
238
239 busPatch->SetValueAsDouble(0,i,busPatch->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
240
241 de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
242
243 chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
244 }
245 delete wec;
246 }
247
248 UpdateNumberOfEvents(&nevents);
249
250}
251
06bc44ee 252//_____________________________________________________________________________
253AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
254 const AliMUONVStore& deValues, Int_t val)
255: AliMUONVTrackerData(name,title),
256fIsSingleEvent(kFALSE),
257fChannelValues(0x0),
258fManuValues(0x0),
259fBusPatchValues(0x0),
260fDEValues(0x0),
261fChamberValues(0x0),
262fPCBValues(0x0),
263fDimension(0),
264fNevents(0),
265fDimensionNames(0x0),
266fExternalDimensionNames(0x0),
267fExternalDimension(0),
268fHistogramming(0x0),
269fHistos(0x0),
270fXmin(0.0),
271fXmax(0.0),
272fIsChannelLevelEnabled(kFALSE),
273fIsManuLevelEnabled(kFALSE),
274fIsBustPatchLevelEnabled(kFALSE),
275fIsPCBLevelEnabled(kFALSE),
276fNofDDLs(0),
277fNofEventsPerDDL(0x0)
278{
279 /// ctor with values at the detection element level
280 /// In this case, we force fIsChannelLevelEnabled = fIsManuLevelEnabled = kFALSE
281 /// ctor
282
283 if (deValues.GetSize()==0)
284 {
285 AliFatal("Cannot create a tracker data from nothing in that case !");
286 }
287
288 if ( val != 1 )
289 {
290 AliFatal("Wrong parameter. For DE, must be 1");
291 }
292
293 if ( !AliMpDDLStore::Instance(kFALSE) && !AliMpManuStore::Instance(kFALSE) )
294 {
295 AliError("Cannot work without (full) mapping");
296 return;
297 }
298
299 TIter next(deValues.CreateIterator());
300 AliMUONVCalibParam* m = static_cast<AliMUONVCalibParam*>(next());
301
302 Int_t dimension = ( m->Dimension() - fgkExtraDimension - fgkVirtualExtraDimension ) / 2;
303
304 fDimension = External2Internal(dimension)+fgkExtraDimension;
305
306 fDimensionNames = new TObjArray(fDimension+fgkVirtualExtraDimension);
307 fExternalDimensionNames = new TObjArray(dimension);
308 fExternalDimension = dimension;
309 fHistogramming = new Int_t[fExternalDimension];
310 memset(fHistogramming,0,fExternalDimension*sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
311
312 fExternalDimensionNames->SetOwner(kTRUE);
313 fDimensionNames->SetOwner(kTRUE);
314 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
315 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
316 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
317 Clear();
318 TArrayI nevents(AliDAQ::NumberOfDdls("MUONTRK"));
319 AssertStores();
320
321 next.Reset();
322 AliMUONVCalibParam* external;
323
324 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
325 {
326 Int_t detElemId = external->ID0();
327
328 AliMpDetElement* mpde = AliMpDDLStore::Instance()->GetDetElement(detElemId,kFALSE);
329
330 if (!mpde)
331 {
332 AliError(Form("Got an invalid DE (%d) from external store",detElemId));
333 continue;
334 }
335
336 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
337 AliMUONVCalibParam* chamber = ChamberParam(chamberId,kTRUE);
338 AliMUONVCalibParam* de = DetectionElementParam(detElemId,kTRUE);
339
340 AliMUONVCalibParam* wec = new AliMUONCalibParamND(external->Dimension()-1,1,detElemId,0,0);
341 // as external, but without event count
342 wec->SetValueAsDouble(0,0,external->ValueAsDouble(0,0));
343 wec->SetValueAsDouble(0,1,external->ValueAsDouble(0,1));
344 wec->SetValueAsDouble(0,2,external->ValueAsDouble(0,2));
345 wec->SetValueAsDouble(0,3,external->ValueAsDouble(0,3));
346
347 Int_t n1 = de->ValueAsInt(0,IndexOfNumberDimension());
348 Int_t n2 = external->ValueAsInt(0,IndexOfNumberDimension());
349 if ( n1 != n2 )
350 {
351 AliError(Form("Incoherent number of dimensions for DE%d : %d vs %d",
352 detElemId,n1,n2));
353 continue;
354 }
355
356 Int_t nevt = external->ValueAsInt(0,4);
357
358 Int_t ddl = mpde->GetDdlId();
359
360 if ( nevents[ddl] == 0 )
361 {
362 nevents[ddl] = nevt;
363 }
364 else
365 {
366 if ( nevents.At(ddl) != nevt )
367 {
368 AliError(Form("Nevt mismatch for DE %5d DDL %d : %d vs %d",
369 detElemId,ddl,nevents.At(ddl),nevt));
370 continue;
371 }
372 }
373
374 for ( Int_t i = 0; i < wec->Dimension()-1; ++i )
375 {
376 de->SetValueAsDouble(0,i,de->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
377
378 chamber->SetValueAsDouble(0,i,chamber->ValueAsDouble(0,i) + wec->ValueAsDouble(0,i));
379 }
380 delete wec;
381 }
382
383 UpdateNumberOfEvents(&nevents);
384
385}
7eafe398 386
0145e89a 387//_____________________________________________________________________________
388AliMUONTrackerData::~AliMUONTrackerData()
389{
390 /// dtor
391 delete fChannelValues;
392 delete fManuValues;
393 delete fBusPatchValues;
394 delete fDEValues;
395 delete fChamberValues;
396 delete fPCBValues;
397 delete fDimensionNames;
8741815f 398 delete fExternalDimensionNames;
399 delete[] fHistogramming;
0edb62c4 400 delete fHistos;
e83120bd 401 delete[] fNofEventsPerDDL;
0145e89a 402}
403
404//_____________________________________________________________________________
405Bool_t
e83120bd 406AliMUONTrackerData::Add(const AliMUONVStore& store, TArrayI* nevents)
1ffbeb9d 407{
408 /// Add the given external store to our internal store
e83120bd 409 return InternalAdd(store,nevents,kFALSE);
410}
411
412//_____________________________________________________________________________
413Bool_t
414AliMUONTrackerData::Add(const AliMUONTrackerData& data)
415{
416 /// Add data to *this
417 // We do this by looping on all VCalibParam stored in the various containers,
418 // and simply adding the values there.
419 // Same thing for the number of events per DDL.
420 // Same thing for sparsehistograms, if we have some.
421
422 // First cross check we have compatible objects.
423
424 if ( fIsChannelLevelEnabled != data.fIsChannelLevelEnabled )
425 {
426 AliError("Incompatible IsChannelLevelEnabled status");
427 return kFALSE;
428 }
429
430 if ( fIsManuLevelEnabled != data.fIsManuLevelEnabled )
431 {
432 AliError("Incompatible IsManuLevelEnabled status");
433 return kFALSE;
434 }
435
436 if ( fIsSingleEvent != data.fIsSingleEvent )
437 {
438 AliError("Incompatible IsSingleEvent status");
439 return kFALSE;
440 }
441
442 if ( fDimension != data.fDimension || fExternalDimension != data.fExternalDimension )
443 {
444 AliError("Incompatible dimensions");
445 return kFALSE;
446 }
447
448 if ( fNofDDLs != data.fNofDDLs )
449 {
450 AliError("Incompatible number of Ddls");
451 return kFALSE;
452 }
453
454 if ( ( !fHistogramming && data.fHistogramming ) || ( fHistogramming && !data.fHistogramming )
455 || fXmin != data.fXmin || fXmax != data.fXmax )
456 {
1130977f 457 AliError(Form("Incompatible histogramming (%p vs %p) (xmax = %e vs %e ; xmin = %e vs %e)",
e83120bd 458 fHistogramming,data.fHistogramming,fXmax,data.fXmax,fXmin,data.fXmin));
459 return kFALSE;
460 }
461
462 if ( fHistogramming )
463 {
464 for ( Int_t i = 0; i < fExternalDimension; ++i )
465 {
466 if ( fHistogramming[i] != data.fHistogramming[i] )
467 {
468 AliError(Form("Incompatible histogramming for external dimension %d",i));
469 return kFALSE;
470 }
471 }
472 }
473
474 // OK. Seems we have compatible objects, so we can proceed with the actual
475 // merging...
476
477 if ( data.fChannelValues )
478 {
479 Add2D(*(data.fChannelValues),*fChannelValues);
480 }
481
482 if ( data.fManuValues )
483 {
484 Add2D(*(data.fManuValues),*fManuValues);
485 }
486
487 if ( data.fPCBValues )
488 {
489 Add2D(*(data.fPCBValues),*fPCBValues);
490 }
491
492 if ( data.fBusPatchValues )
493 {
494 Add1D(*(data.fBusPatchValues),*fBusPatchValues);
495 }
496
497 if ( data.fDEValues )
498 {
499 Add1D(*(data.fDEValues),*fDEValues);
500 }
501
502 if ( data.fChamberValues )
503 {
504 Add1D(*(data.fChamberValues),*fChamberValues);
505 }
506
507 for ( Int_t i = 0; i < fNofDDLs; ++i )
508 {
509 fNofEventsPerDDL[i] += data.fNofEventsPerDDL[i];
510 }
511
512 if ( data.fHistos )
513 {
514 TIter nexthisto(data.fHistos->CreateIterator());
515 AliMUONVStore* store;
516 while ( ( store = static_cast<AliMUONVStore*>(nexthisto()) ) )
517 {
518 TIter ns(store->CreateIterator());
519 AliMUONSparseHisto* h;
520 while ( ( h = static_cast<AliMUONSparseHisto*>(ns()) ) )
521 {
522 AliMUONVStore* thisStore = static_cast<AliMUONVStore*>(fHistos->FindObject(store->GetUniqueID()));
523
524 if (!thisStore)
525 {
526 thisStore = store->Create();
527 thisStore->SetUniqueID(store->GetUniqueID());
528 fHistos->Add(thisStore);
529 }
530
531 AliMUONSparseHisto* mine = static_cast<AliMUONSparseHisto*>(thisStore->FindObject(h->GetUniqueID()));
532
533 if (!mine)
534 {
535 thisStore->Add(h);
536 }
537 else
538 {
539 mine->Add(*h);
540 }
541 }
542 }
543 }
544
a499c7d9 545 fNevents = TMath::Max(fNevents,data.fNevents);
546
e83120bd 547 return kTRUE;
548}
549
550//_____________________________________________________________________________
551void
552AliMUONTrackerData::Add2D(const AliMUONVStore& src, AliMUONVStore& dest) const
553{
554 /// Add one 2d store to another
555
556 TIter next(src.CreateIterator());
557 AliMUONVCalibParam* p;
558
559 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
560 {
561 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->ID0(),p->ID1()));
562
563 if (!a)
564 {
565 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
566 }
567 else
568 {
569 AddCalibParams(*p,*a);
570 }
571 }
572}
573
574//_____________________________________________________________________________
575void
576AliMUONTrackerData::Add1D(const AliMUONVStore& src, AliMUONVStore& dest) const
577{
578 /// Add one 1d store to another
579
580 TIter next(src.CreateIterator());
581 AliMUONVCalibParam* p;
582
583 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
584 {
585 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->GetUniqueID()));
586
587 if (!a)
588 {
589 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
590 }
591 else
592 {
593 AddCalibParams(*p,*a);
594 }
595 }
596}
597
598//_____________________________________________________________________________
599void
600AliMUONTrackerData::AddCalibParams(const AliMUONVCalibParam& src, AliMUONVCalibParam& dest) const
601{
602 /// Add src to dest
603 for ( Int_t i = 0; i < src.Size(); ++i )
604 {
605 for ( Int_t j = 0; j < src.Dimension(); ++j )
606 {
607 dest.SetValueAsFloat(i,j,src.ValueAsFloat(i,j));
608 }
609 }
1ffbeb9d 610}
611
612//_____________________________________________________________________________
613Bool_t
614AliMUONTrackerData::Replace(const AliMUONVStore& store)
615{
616 /// Replace our values by values from the given external store
e83120bd 617 Bool_t rv = InternalAdd(store,0x0,kTRUE);
1ffbeb9d 618 AliMUONVTrackerData::Replace(store);
619 return rv;
620}
621
622//_____________________________________________________________________________
623Bool_t
7eafe398 624AliMUONTrackerData::UpdateNumberOfEvents(TArrayI* nevents)
0145e89a 625{
7eafe398 626 /// Update the number of events
0145e89a 627
e83120bd 628 if (!fNofDDLs)
629 {
630 fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK");
631 fNofEventsPerDDL = new Int_t[fNofDDLs];
632 for ( Int_t i = 0; i < fNofDDLs; ++i )
633 {
634 fNofEventsPerDDL[i] = 0;
635 }
636 }
7eafe398 637
e83120bd 638 if (nevents)
639 {
640 if (nevents->GetSize() != fNofDDLs )
641 {
642 AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d",
643 nevents->GetSize(),fNofDDLs));
644 return kFALSE;
645 }
646
647 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
648 {
649 fNofEventsPerDDL[i] += nevents->At(i);
650 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
651 }
652 }
653 else
654 {
655 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
656 {
657 ++fNofEventsPerDDL[i];
658 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
659 }
660 }
7eafe398 661 return kTRUE;
662}
663
664//_____________________________________________________________________________
665void
666AliMUONTrackerData::AssertStores()
667{
668 /// Insure our stores are allocated
49419555 669
e13620cd 670 if (!fChamberValues)
8741815f 671 {
49419555 672 Int_t numberOfBusPatches(0);
673 Int_t numberOfDEs(0);
674
675 // get number of bus patches and number of detection element
676 // to initialize fBusPatchValues and fDEValues below
677
630711ed 678 TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
679 while ( next() ) ++numberOfBusPatches;
49419555 680 AliMpDEIterator deIt;
681 deIt.First();
682 while (!deIt.IsDone())
683 {
684 ++numberOfDEs;
685 deIt.Next();
686 }
687
7eafe398 688 if ( fIsChannelLevelEnabled )
689 {
690 fChannelValues = new AliMUON2DMap(kTRUE);
691 }
0edb62c4 692 if ( fIsManuLevelEnabled )
693 {
694 fManuValues = new AliMUON2DMap(kTRUE);
695 }
06bc44ee 696 if ( fIsPCBLevelEnabled )
697 {
698 fPCBValues = new AliMUON2DMap(kFALSE);
699 }
700 if ( fIsBustPatchLevelEnabled )
701 {
702 fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
703 }
49419555 704 fDEValues = new AliMUON1DMap(numberOfDEs);
8741815f 705 fChamberValues = new AliMUON1DArray;
706 }
7eafe398 707}
708
709//_____________________________________________________________________________
710Bool_t
711AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, TArrayI* nevents, Bool_t replace)
712{
713 /// Add the given external store to our internal store
714
99c136e1 715 AliCodeTimerAuto(GetName(),0);
7eafe398 716
717 if ( !replace)
718 {
719 if ( IsSingleEvent() && NumberOfEvents(-1) == 1 )
720 {
721 AliError(Form("%s is supposed to be single event only",GetName()));
722 return kFALSE;
723 }
724 }
725
726 UpdateNumberOfEvents(nevents);
727
728 AssertStores();
0145e89a 729
730 TIter next(store.CreateIterator());
731 AliMUONVCalibParam* external;
732
49419555 733 Int_t nk(2);
734
735 if ( IsSingleEvent() ) nk = 1;
736
0145e89a 737 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
738 {
8741815f 739 if ( external->Dimension() != ExternalDimension() )
740 {
741 AliError(Form("Incompatible dimensions %d vs %d",
742 external->Dimension(),ExternalDimension()));
743 return kFALSE;
744 }
0145e89a 745
7eafe398 746 AliMUONVCalibParam* chamber(0x0);
747 AliMUONVCalibParam* de(0x0);
748 AliMUONVCalibParam* busPatch(0x0);
749 AliMUONVCalibParam* pcb(0x0);
750 AliMUONVCalibParam* manu(0x0);
751 AliMUONVCalibParam* channel(0x0);
752 AliMpDetElement* mpde(0x0);
0145e89a 753
8741815f 754 Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
0145e89a 755
7b6684fe 756 if ( manuId < 0 ) continue;
757
8741815f 758 Int_t detElemId = mpde->GetId();
759
760 Double_t value[] = { 0.0, 0.0 };
761
762 Int_t nch = mpde->NofChannelsInManu(manuId);
0145e89a 763
764 for ( Int_t i = 0; i < external->Size(); ++i )
765 {
8741815f 766 Bool_t existingChannel = ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
767 : mpde->IsConnectedChannel(manuId,i));
768 // note we only use IsConnectedChannel method when really needed, as
769 // it costs (some) CPU time...
0145e89a 770
8741815f 771 if ( existingChannel )
0145e89a 772 {
8741815f 773 Bool_t validChannel(kFALSE);
0145e89a 774
8741815f 775 for ( Int_t j = 0; j < external->Dimension(); ++j )
776 {
777 Double_t vext = external->IsDoublePrecision() ?
778 external->ValueAsDoubleFast(i,j) :
779 external->ValueAsFloatFast(i,j);
780
781 if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
782
783 validChannel = kTRUE;
784
785 Int_t ix = External2Internal(j);
786
787 value[0] = vext;
788 value[1] = vext*vext;
789
790 if ( IsHistogrammed(j) )
791 {
0edb62c4 792 FillHisto(detElemId,manuId,i,j,vext);
8741815f 793 }
794
49419555 795 for ( Int_t k = 0; k < nk; ++k )
8741815f 796 {
e13620cd 797 Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
1ffbeb9d 798
e13620cd 799 if ( channel )
800 {
801 channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
802 }
803
0edb62c4 804 if (manu)
805 {
806 manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);
807 }
1ffbeb9d 808
809 busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
810
811 de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
812
813 chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
8741815f 814
8741815f 815 if ( pcb )
816 {
1ffbeb9d 817 pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
8741815f 818 }
819 }
820 }
0145e89a 821
1ffbeb9d 822 if ( validChannel && !replace )
8741815f 823 {
e13620cd 824 if ( channel )
825 {
826 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
827 channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
828 }
829
0edb62c4 830 if (manu)
831 {
832 manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
833 manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
834 }
835
8741815f 836 busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
837 busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
838 de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
839 de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
840 chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
841 chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
842 if ( pcb )
843 {
844 pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
845 pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
846 }
847 }
0145e89a 848 }
849 }
850 }
851
f6358d9e 852 NumberOfEventsChanged();
853
0145e89a 854 return kTRUE;
855}
856
857//_____________________________________________________________________________
858Double_t
859AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
860{
861 /// Return the value of a given buspatch for a given dimension
862 /// or 0 if not existing
863 AliMUONVCalibParam* param = BusPatchParam(busPatchId);
e83120bd 864 return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0;
0145e89a 865}
866
867//_____________________________________________________________________________
868AliMUONVCalibParam*
8741815f 869AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
0145e89a 870{
871 /// Return (if it exist), the VCalibParam for a given busPatch
8741815f 872
873 AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
874 (fBusPatchValues->FindObject(busPatchId)) : 0x0;
875
876 if (!busPatch && create && fBusPatchValues)
877 {
878 busPatch = CreateBusPatchParam(busPatchId);
879 fBusPatchValues->Add(busPatch);
880 }
881
882 return busPatch;
883}
884
885//_____________________________________________________________________________
886AliMUONVCalibParam*
887AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
888{
889 /// Create storage for one bus patch
890
99c136e1 891 AliCodeTimerAuto("",0);
8741815f 892
893 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
894
895 if (!bp)
896 {
897 AliError(Form("Got an invalid buspatchId = %d",busPatchId));
898 return 0x0;
899 }
900
901 AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
902
903 // set the number of channels in that buspatch
904
905 Int_t nchannels(0);
906
907 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
908
909 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
910
911 for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
912 {
913 Int_t manuId = bp->GetManuId(i);
914 nchannels += de->NofChannelsInManu(manuId);
915 }
916
917 busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
918
919 return busPatch;
0145e89a 920}
921
922//_____________________________________________________________________________
923Double_t
924AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
925{
926 /// Return the value fo a given chamber for a given dimension,
927 /// or zero if not existing
e83120bd 928
929 // FIXME: is the Value() correct wrt to number of events in the case of
930 // chamber ? Or should we do something custom at the chamber level
931 // (as it spans several ddls) ?
932
0145e89a 933 AliMUONVCalibParam* param = ChamberParam(chamberId);
e83120bd 934 return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0;
0145e89a 935}
936
937//_____________________________________________________________________________
938AliMUONVCalibParam*
8741815f 939AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
0145e89a 940{
941 /// Return (if it exist) the VCalibParam for a given chamber
8741815f 942
943 AliMUONVCalibParam* chamber = fChamberValues ? static_cast<AliMUONVCalibParam*>
0145e89a 944 (fChamberValues->FindObject(chamberId)) : 0x0;
8741815f 945
946 if (!chamber && create && fChamberValues)
947 {
948 chamber = CreateChamberParam(chamberId);
949 fChamberValues->Add(chamber);
950 }
951
952 return chamber;
953}
954
955//_____________________________________________________________________________
956AliMUONVCalibParam*
957AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
958{
959 /// Create storage for one chamber
960
99c136e1 961 AliCodeTimerAuto("",0);
8741815f 962
963 AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
964
965 // set the number of channels in that chamber
966
967 Int_t nchannels(0);
968
969 AliMpDEIterator it;
970
971 it.First(chamberId);
972
973 while ( !it.IsDone() )
974 {
975 AliMpDetElement* det = it.CurrentDE();
976
977 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
978 {
979 Int_t busPatchId = det->GetBusPatchId(i);
980 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
981 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
982 {
983 Int_t manuId = bp->GetManuId(j);
984 nchannels += det->NofChannelsInManu(manuId);
985 }
986 }
987
988 it.Next();
989 }
990
991 chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
992
993 return chamber;
0145e89a 994}
995
996//_____________________________________________________________________________
997Double_t
998AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId,
999 Int_t manuChannel, Int_t dim) const
1000{
1001 /// Return the value for a given channel for a given dimension
1002
1003 AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
1004
e83120bd 1005 return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
0145e89a 1006}
1007
1008//_____________________________________________________________________________
1009AliMUONVCalibParam*
8741815f 1010AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
57e2ad1a 1011 const AliMUONVCalibParam* external) const
0145e89a 1012{
1013 /// Return (if it exist) the VCalibParam for a given manu
8741815f 1014
1015 AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
1016 (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
1017
1018 if (!param && external && fChannelValues)
1019 {
7b6684fe 1020 param = CreateDouble(*external,detElemId,manuId);
8741815f 1021 fChannelValues->Add(param);
1022 }
1023
1024 return param;
0145e89a 1025}
1026
0145e89a 1027//_____________________________________________________________________________
1028void
1029AliMUONTrackerData::Clear(Option_t*)
1030{
1031 /// Clear all the values
1032 if ( fChannelValues ) fChannelValues->Clear();
1033 if ( fManuValues ) fManuValues->Clear();
1034 if ( fBusPatchValues) fBusPatchValues->Clear();
1035 if ( fPCBValues ) fPCBValues->Clear();
1036 if ( fDEValues) fDEValues->Clear();
8741815f 1037 if ( fChamberValues ) fChamberValues->Clear();
0edb62c4 1038 if ( fHistos ) fHistos->Clear();
e83120bd 1039 for ( Int_t i = 0; i < fNofDDLs; ++i )
1040 {
1041 fNofEventsPerDDL[i] = 0;
1042 }
2076dbd3 1043 fNevents = 0;
0145e89a 1044 NumberOfEventsChanged();
1045}
1046
1047//_____________________________________________________________________________
1048Double_t
1049AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId,
1050 Int_t manuChannel) const
1051{
1052 /// Return the number of times a given channel had data
0145e89a 1053
8741815f 1054 return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
0145e89a 1055}
1056
1057//_____________________________________________________________________________
1058AliMUONVCalibParam*
7b6684fe 1059AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param,
1060 Int_t detElemId, Int_t manuId) const
0145e89a 1061{
1062 /// Create a double version of VCalibParam, for internal use
8741815f 1063
99c136e1 1064 AliCodeTimerAuto("",0);
8741815f 1065
1066 AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
1067 param.Size(),
7b6684fe 1068 detElemId,
1069 manuId,
8741815f 1070 0.0);
0145e89a 1071
7b6684fe 1072 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
1073
0145e89a 1074 for ( Int_t i = 0; i < c->Size(); ++i )
1075 {
7b6684fe 1076 Double_t value(0.0);
1077
1078 if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
1079
1080 c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
0145e89a 1081 }
1082
1083 return c;
1084}
1085
1086//_____________________________________________________________________________
1087Double_t
1088AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
1089{
1090 /// Return the value for a given detection element for a given dimension
1091 AliMUONVCalibParam* param = DetectionElementParam(detElemId);
e83120bd 1092 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
0145e89a 1093
1094}
1095
1096//_____________________________________________________________________________
1097AliMUONVCalibParam*
8741815f 1098AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
0145e89a 1099{
1100 /// Return (if it exist) the VCalibParam for a given detection element
8741815f 1101
1102 AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
1103 (fDEValues->FindObject(detElemId)) : 0x0 ;
1104
1105 if (!de && create && fDEValues)
1106 {
1107 de = CreateDetectionElementParam(detElemId);
1108 fDEValues->Add(de);
1109 }
1110
1111 return de;
1112
1113}
1114
1115//_____________________________________________________________________________
1116AliMUONVCalibParam*
1117AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
1118{
1119 /// Create storage for one detection element
1120
99c136e1 1121 AliCodeTimerAuto("",0);
8741815f 1122
1123 AliMUONVCalibParam* de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
1124
1125 AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1126 Int_t nchannels(0);
1127
1128 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
1129 {
1130 Int_t busPatchId = det->GetBusPatchId(i);
1131 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
1132 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
1133 {
1134 Int_t manuId = bp->GetManuId(j);
1135 nchannels += det->NofChannelsInManu(manuId);
1136 }
1137 }
1138
1139 de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
1140
1141 return de;
0145e89a 1142}
1143
e83120bd 1144//_____________________________________________________________________________
1145Int_t
1146AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const
1147{
1148 /// Get the "local" ddlid (0..19) of a given buspatch
1149 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid);
1150 if (bp)
1151 {
1152 return bp->GetDdlId();
1153 }
1154 return -1;
1155}
1156
1157//_____________________________________________________________________________
1158Int_t
1159AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const
1160{
1161 /// Get the "local" ddlid (0..19) of a given detection element
1162 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid);
1163 if (de)
1164 {
1165 return de->GetDdlId();
1166 }
1167 return -1;
1168}
1169
1170//_____________________________________________________________________________
1171Int_t
1172AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const
1173{
1174 /// Get the "local" ddlid (0..19) of a given chamber
1175 /// This has no real meaning (as there are several ddls per chamber),
1176 /// so we take the ddlid where we got the max number of events
1177
1178 AliMpDEIterator it;
1179
1180 it.First(chamberid);
1181 Int_t n(0);
1182 Int_t d(-1);
1183
1184 while (!it.IsDone())
1185 {
1186 Int_t detElemId = it.CurrentDEId();
1187 Int_t ddlId = DdlIdFromDetElemId(detElemId);
1188 if ( NumberOfEvents(ddlId) > n )
1189 {
1190 n = NumberOfEvents(ddlId);
1191 d = ddlId;
1192 }
1193 it.Next();
1194 }
1195
1196 return d;
1197}
1198
0145e89a 1199//_____________________________________________________________________________
1200TString
1201AliMUONTrackerData::DimensionName(Int_t dim) const
1202{
1203 /// Get the name of a given dimension
1204 TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
1205 if ( value )
1206 {
1207 return value->String();
1208 }
1209 else
1210 {
1211 return TString("Invalid");
1212 }
1213}
1214
e13620cd 1215//_____________________________________________________________________________
1216void
1217AliMUONTrackerData::DisableChannelLevel()
1218{
1219 /// Disable the storing of data at channel level
1220
1221 delete fChannelValues;
1222 fChannelValues = 0x0;
1223 fIsChannelLevelEnabled = kFALSE;
1224}
1225
0edb62c4 1226//_____________________________________________________________________________
1227void
1228AliMUONTrackerData::DisableManuLevel()
1229{
1230 /// Disable the storing of data at manu level (and below)
1231
1232 DisableChannelLevel();
1233 delete fManuValues;
1234 fManuValues = 0x0;
1235 fIsManuLevelEnabled = kFALSE;
1236}
1237
49419555 1238//_____________________________________________________________________________
1239Int_t
1240AliMUONTrackerData::External2Internal(Int_t index) const
1241{
1242 /// From external to internal dimension
1243 return IsSingleEvent() ? index : index*2;
1244}
1245
0145e89a 1246//_____________________________________________________________________________
8741815f 1247TString
1248AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
0145e89a 1249{
8741815f 1250 /// Get the name of a given external dimension
1251
1252 TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
1253 if ( value )
1254 {
1255 return value->String();
1256 }
1257 else
1258 {
1259 return TString("Invalid");
1260 }
0145e89a 1261}
1262
1263//_____________________________________________________________________________
8741815f 1264void
0edb62c4 1265AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel,
1266 Int_t dim, Double_t value)
0145e89a 1267{
8741815f 1268 /// Fill histogram of a given channel
1269
0edb62c4 1270 AliMUONSparseHisto* h(0x0);
1271
e13620cd 1272 if ( fIsChannelLevelEnabled )
1273 {
0edb62c4 1274 h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
1275 }
1276 else if ( fIsManuLevelEnabled )
1277 {
1278 h = GetManuSparseHisto(detElemId,manuId,dim);
1279 }
1280
1281 AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h));
1282
1283 if (h)
1284 {
e13620cd 1285 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
1286 }
0145e89a 1287}
1288
0edb62c4 1289//_____________________________________________________________________________
1290AliMUONSparseHisto*
1291AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId,
1292 Int_t dim) const
1293{
1294 /// Get histogram of a given manu
1295
1296 if (!fHistos) return 0x0;
1297
1298 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1299 if (!m) return 0x0;
1300
1301 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1302
1303 return h;
1304}
1305
1306//_____________________________________________________________________________
1307AliMUONSparseHisto*
1308AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim)
1309{
1310 /// Get histogram of a given manu. Create it if necessary
1311
1312 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1313
1314 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
1315 if (!m)
1316 {
1317 m = new AliMUON1DArray(NumberOfDimensions());
1318 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1319 fHistos->Add(m);
1320 }
1321
1322 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1323 if (!h)
1324 {
1325 h = new AliMUONSparseHisto(fXmin,fXmax);
1326
1327 h->SetUniqueID(dim);
1328
1329 m->Add(h);
1330 }
1331
1332 return h;
1333}
1334
0145e89a 1335//_____________________________________________________________________________
10eb3d17 1336AliMUONSparseHisto*
1337AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1338 Int_t manuChannel, Int_t dim) const
8741815f 1339{
10eb3d17 1340 /// Get histogram of a given channel
8741815f 1341
0edb62c4 1342 if (!fHistos) return 0x0;
8741815f 1343
0edb62c4 1344 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
10eb3d17 1345 if (!m) return 0x0;
8741815f 1346
10eb3d17 1347 UInt_t uid = ( manuChannel << 16 ) | dim;
8741815f 1348
10eb3d17 1349 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
8741815f 1350
1351 return h;
1352}
0145e89a 1353
8741815f 1354//_____________________________________________________________________________
1355AliMUONSparseHisto*
10eb3d17 1356AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1357 Int_t manuChannel, Int_t dim)
8741815f 1358{
10eb3d17 1359 /// Get histogram of a given channel. Create it if necessary
8741815f 1360
0edb62c4 1361 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
8741815f 1362
0edb62c4 1363 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
10eb3d17 1364 if (!m)
8741815f 1365 {
10eb3d17 1366 m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
1367 m->SetUniqueID( ( manuId << 16 ) | detElemId );
0edb62c4 1368 fHistos->Add(m);
8741815f 1369 }
1370
10eb3d17 1371 UInt_t uid = ( manuChannel << 16 ) | dim;
8741815f 1372
10eb3d17 1373 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
8741815f 1374 if (!h)
1375 {
10eb3d17 1376 h = new AliMUONSparseHisto(fXmin,fXmax);
1377
1378 h->SetUniqueID(uid);
1379
1380 m->Add(h);
8741815f 1381 }
0145e89a 1382
8741815f 1383 return h;
1384}
0145e89a 1385
e83120bd 1386//_____________________________________________________________________________
1387void
1388AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param,
1389 Int_t& detElemId, Int_t& manuId) const
1390{
1391 /// Tries to get (detElemId,manuId) of param
1392
ab167304 1393 // Load mapping manu store
1394 if ( ! AliMpCDB::LoadManuStore() ) {
1395 AliError("Could not access manu store from OCDB !");
1396 return;
1397 }
1398
e83120bd 1399 if ( param.ID1() <= 0 )
1400 {
1401 // we (probably) get a manu serial number
1402 Int_t serial = param.ID0();
168e9c4d 1403 MpPair_t pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial);
1404 detElemId = AliMp::PairFirst(pair);
1405 manuId = AliMp::PairSecond(pair);
e83120bd 1406 if ( !detElemId )
1407 {
a499c7d9 1408 AliDebug(1,Form("DE %d manuId %d from serial %d is not correct !",
1409 detElemId,manuId,serial));
e83120bd 1410 }
1411 }
1412 else
1413 {
1414 // we get a (de,manu) pair
1415 detElemId = param.ID0();
1416 manuId = param.ID1();
1417 }
1418}
1419
1420
8741815f 1421//_____________________________________________________________________________
1422Int_t
1423AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
1424 AliMUONVCalibParam*& chamber,
1425 AliMUONVCalibParam*& de,
1426 AliMUONVCalibParam*& busPatch,
1427 AliMUONVCalibParam*& pcb,
1428 AliMUONVCalibParam*& manu,
1429 AliMUONVCalibParam*& channel,
1430 AliMpDetElement*& mpde)
1431{
1432 /// Get containers at all levels
1433
7eafe398 1434 chamber = de = busPatch = pcb = manu = channel = 0x0;
1435 mpde = 0x0;
1436
8741815f 1437 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1438
7b6684fe 1439 Int_t detElemId;
1440 Int_t manuId;
8741815f 1441
e83120bd 1442 GetDEManu(*external,detElemId,manuId);
1443
a499c7d9 1444 mpde = ddlStore->GetDetElement(detElemId,kFALSE);
7b6684fe 1445
f6358d9e 1446 if (!mpde) // can happen if reading e.g. capacitances store where we have data for non-connected manus
1447 {
1448 return -1;
1449 }
1450
a499c7d9 1451 // explicitely check that de,manu is correct
1452 const AliMpVSegmentation* mpseg = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId, manuId,kFALSE);
1453
1454 if (!mpseg)
1455 {
1456 return -1;
1457 }
1458
7b6684fe 1459 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1460
8741815f 1461 Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1462
a499c7d9 1463 if ( busPatchId <= 0 )
1464 {
1465 return -1;
1466 }
1467
8741815f 1468 Int_t pcbIndex = -1;
1469
1470 AliMp::StationType stationType = mpde->GetStationType();
1471
1472 if ( stationType == AliMp::kStation345 )
1473 {
49e110ec 1474 AliMpDCSNamer namer("TRACKER");
8741815f 1475 pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
1476 }
1477
7eafe398 1478 if ( fIsChannelLevelEnabled )
1479 {
1480 channel = ChannelParam(detElemId,manuId,external);
1481 }
8741815f 1482
1483 manu = ManuParam(detElemId,manuId,kTRUE);
1484
1485 busPatch = BusPatchParam(busPatchId,kTRUE);
1486
1487 de = DetectionElementParam(detElemId,kTRUE);
1488
1489 chamber = ChamberParam(chamberId,kTRUE);
1490
1491 pcb = 0x0;
1492
1493 if ( pcbIndex >= 0 )
1494 {
1495 pcb = PCBParam(detElemId,pcbIndex,kTRUE);
0145e89a 1496 }
8741815f 1497
1498 return manuId;
1499}
0145e89a 1500
8741815f 1501//_____________________________________________________________________________
1502Bool_t
1503AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
1504{
1505 /// Whether we have data for a given buspatch
1506 return ( BusPatchParam(busPatchId) != 0 );
1507}
1508
1509//_____________________________________________________________________________
1510Bool_t
1511AliMUONTrackerData::HasChamber(Int_t chamberId) const
1512{
1513 /// Whether we have data for a given chamber
1514 return ( ChamberParam(chamberId) != 0 );
1515}
1516
1517//_____________________________________________________________________________
1518Bool_t
1519AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
1520{
1521 /// Whether we have data for a given detection element
1522 return ( DetectionElementParam(detElemId) != 0 );
1523}
1524
1525//_____________________________________________________________________________
1526Bool_t
1527AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
1528{
1529 /// Whether we have data for a given manu
1530 return ( ManuParam(detElemId,manuId) != 0 );
1531}
1532
1533//_____________________________________________________________________________
1534Bool_t
1535AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
1536{
1537 /// Whether we have data for a given pcb
1538 return ( PCBParam(detElemId,pcbIndex) != 0 );
0145e89a 1539}
1540
1541//_____________________________________________________________________________
1542Double_t
1543AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
1544{
9016a84e 1545 /// Return the value for a given manu and a given dimension
1546
0145e89a 1547 AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
e83120bd 1548 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
0145e89a 1549}
1550
1551//_____________________________________________________________________________
1552AliMUONVCalibParam*
8741815f 1553AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
0145e89a 1554{
9016a84e 1555 /// Get the VCalibParam for a given manu
8741815f 1556
1557 AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
1558 (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
1559
1560 if (!manu && create && fManuValues)
1561 {
1562 manu = CreateManuParam(detElemId,manuId);
1563 fManuValues->Add(manu);
1564 }
1565
1566 return manu;
1567}
1568
1569//_____________________________________________________________________________
1570AliMUONVCalibParam*
1571AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
1572{
1573 /// Create storage for one manu
1574
99c136e1 1575 AliCodeTimerAuto("",0);
8741815f 1576
1577 AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
1578
1579 // set the number of channels in that manu
1580
1581 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1582
1583 manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
1584
1585 return manu;
0145e89a 1586}
1587
7b6684fe 1588//_____________________________________________________________________________
1589Long64_t
e83120bd 1590AliMUONTrackerData::Merge(TCollection* list)
7b6684fe 1591{
e83120bd 1592 /// Merge this with a list of AliMUONVTrackerData
1593
1594 if (!list) return 0;
7b6684fe 1595
e83120bd 1596 if ( list->IsEmpty() ) return NumberOfEvents(-1);
1597
1598 TIter next(list);
1599 const TObject* o(0x0);
1600
1601 while ( ( o = next() ) )
1602 {
1603 const AliMUONTrackerData* data = dynamic_cast<const AliMUONTrackerData*>(o);
9b780418 1604 if (!data)
e83120bd 1605 {
1606 AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it",
1607 o->GetName()));
1608 }
1609 else
1610 {
1611 Bool_t ok = Add(*data);
1612 if (!ok)
1613 {
1614 AliError("Got incompatible objects");
1615 }
1616 }
1617 }
7b6684fe 1618
e83120bd 1619 return NumberOfEvents(-1);
7b6684fe 1620}
1621
0145e89a 1622//_____________________________________________________________________________
1623Int_t
1624AliMUONTrackerData::NumberOfDimensions() const
1625{
1626 /// Number of dimensions we're dealing with
1627
1628 return fDimension + fgkVirtualExtraDimension;
1629}
1630
e83120bd 1631//_____________________________________________________________________________
1632Int_t
1633AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const
1634{
1635 /// Get the number of events we've seen for a given DDL, or the max
1636 /// in case ddlNumber<0
1637
1638 Int_t n(0);
1639
1640 if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs )
1641 {
1642 n = fNofEventsPerDDL[ddlNumber];
1643 }
1644 else
1645 {
1646 // get the max number of events
1647 return fNevents;
1648 }
1649
1650 return n;
1651}
1652
0145e89a 1653//_____________________________________________________________________________
1654Double_t
1655AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
1656{
1657 /// Return the value of a given pcb for a given dimension
1658
1659 AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
1660
e83120bd 1661 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
0145e89a 1662}
1663
1664//_____________________________________________________________________________
1665AliMUONVCalibParam*
8741815f 1666AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
0145e89a 1667{
1668 /// Return (if it exist) the VCalibParam for a given pcb
8741815f 1669
1670 AliMUONVCalibParam* pcb = fPCBValues ? static_cast<AliMUONVCalibParam*>
1671 (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
1672
1673 if (create && fPCBValues && !pcb)
1674 {
1675 pcb = CreatePCBParam(detElemId,pcbIndex);
1676 fPCBValues->Add(pcb);
1677 }
1678
1679 return pcb;
1680}
1681
1682//_____________________________________________________________________________
1683AliMUONVCalibParam*
1684AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
1685{
1686 /// Create storage for one PCB (station345 only)
1687
99c136e1 1688 AliCodeTimerAuto("",0);
8741815f 1689
49e110ec 1690 AliMpDCSNamer namer("TRACKER");
8741815f 1691
1692 AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
1693 namer.NumberOfPCBs(detElemId),
1694 detElemId,
1695 pcbIndex,
1696 0.0);
1697 return pcb;
0145e89a 1698}
1699
1700//_____________________________________________________________________________
1701void
1702AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
1703{
1704 /// Printout
1705
1706 TNamed::Print(opt);
1707
49419555 1708 if ( !fIsSingleEvent )
0145e89a 1709 {
e83120bd 1710 for ( Int_t i = 0; i < fNofDDLs; ++i )
1711 {
1712 cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl;
1713 }
0145e89a 1714 }
8741815f 1715
0edb62c4 1716 if ( !fIsChannelLevelEnabled )
1717 {
1718 cout << "Is not storing data at the channel level" << endl;
1719 }
1720
1721 if ( !fIsManuLevelEnabled )
e13620cd 1722 {
0edb62c4 1723 cout << "Is not storing data at the manu level" << endl;
e13620cd 1724 }
0edb62c4 1725
8741815f 1726 for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i )
1727 {
1728 TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
1729 cout << Form("External Dimension %2d Name %s %s",i,
1730 ( name ? name->String().Data() : "null"),
1731 ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
1732 }
0145e89a 1733
1734 for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i )
1735 {
1736 TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
8741815f 1737 cout << Form("Internal Dimension %2d Name %s",i,
0145e89a 1738 ( name ? name->String().Data() : "null")) << endl;
1739 }
8741815f 1740
0145e89a 1741 TString sopt(opt);
1742 sopt.ToUpper();
1743
0edb62c4 1744 if ( sopt.Contains("CHANNEL") )
0145e89a 1745 {
0edb62c4 1746 if ( fIsChannelLevelEnabled )
1747 {
1748 if ( fChannelValues ) fChannelValues->Print(wildcard,opt);
1749 }
1750 else
1751 {
1752 AliWarning("You requested channel values, but they were not stored !");
1753 }
0145e89a 1754 }
1755
0edb62c4 1756 if ( sopt.Contains("MANU") )
0145e89a 1757 {
0edb62c4 1758 if ( fIsManuLevelEnabled )
1759 {
1760 if ( fManuValues ) fManuValues->Print(wildcard,opt);
1761 }
1762 else
1763 {
1764 AliWarning("You requested manu values, but they were not stored !");
1765 }
0145e89a 1766 }
1767
1768 if ( sopt.Contains("BUSPATCH") && fBusPatchValues )
1769 {
1770 fBusPatchValues->Print(wildcard,opt);
1771 }
1772
1773 if ( sopt.Contains("DE") && fDEValues )
1774 {
1775 fDEValues->Print(wildcard,opt);
1776 }
1777
1778 if ( sopt.Contains("CHAMBER") && fChamberValues )
1779 {
1780 fChamberValues->Print(wildcard,opt);
1781 }
1782
1783}
1784
1785//_____________________________________________________________________________
1786void
1787AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
1788{
1789 /// Set the name of a given dimension
1790
1791 if ( index >= fExternalDimension )
1792 {
a499c7d9 1793 AliError(Form("%s : dimension %s : Index out of bounds : %d / %d",
1794 GetName(),
1795 name,index,fExternalDimension));
0145e89a 1796 return;
1797 }
1798
1799 Int_t ix = External2Internal(index);
1800
49419555 1801 if ( !IsSingleEvent() )
0145e89a 1802 {
49419555 1803 const char* prefix[] = { "mean", "sigma" };
1804
1805 for ( Int_t i = 0; i < 2; ++i )
1806 {
1807 Int_t j = ix+i;
0145e89a 1808
49419555 1809 SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
1810 }
1811 }
1812 else
1813 {
1814 SetInternalDimensionName(index,name);
0145e89a 1815 }
8741815f 1816
1817 SetExternalDimensionName(index,name);
1818}
1819
1820//_____________________________________________________________________________
1821void
10eb3d17 1822AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
8741815f 1823{
1824 /// decide to make histos for a given dimension
1825 if ( index >= ExternalDimension() )
1826 {
1827 AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
1828 return;
1829 }
1830
305a08ac 1831 AliWarning(Form("Will %s make histogram for data %s index %d : that might ressemble a memory leak depending on the input data",
1832 value ? "":"not", GetName(),index));
8741815f 1833 fHistogramming[index] = value;
10eb3d17 1834 fXmin = xmin;
1835 fXmax = xmax;
0145e89a 1836}
1837
1838//_____________________________________________________________________________
1839void
1840AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
1841{
1842 /// Set the name of a given internal dimension
1843 if ( index >= fDimension )
1844 {
1845 AliError(Form("Index out of bounds : %d / %d",index,fDimension));
1846 return;
1847 }
1848
1849 TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
1850
1851 if ( ovalue )
1852 {
1853 fDimensionNames->Remove(ovalue);
1854 delete ovalue;
1855 }
1856 fDimensionNames->AddAt(new TObjString(value),index);
1857}
1858
8741815f 1859//_____________________________________________________________________________
1860void
1861AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
1862{
1863 /// Set the name of a given external dimension
1864 if ( index >= fExternalDimension )
1865 {
1866 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
1867 return;
1868 }
1869
1870 TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
1871
1872 if ( ovalue )
1873 {
1874 fExternalDimensionNames->Remove(ovalue);
1875 delete ovalue;
1876 }
1877 fExternalDimensionNames->AddAt(new TObjString(value),index);
1878}
1879
0145e89a 1880//_____________________________________________________________________________
1881Double_t
e83120bd 1882AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i,
1883 Int_t dim, Int_t ddlId) const
0145e89a 1884{
1885 /// Compute the value for a given dim, using the internal information we have
1886 /// Basically we're converting sum of weights and sum of squares of weights
1887 /// into means and sigmas, and number of events into occupancy number.
1888
1889 Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
1890
1891 if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
1892
1893 Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
1894
1895 if ( dim >= fDimension )
1896 {
1897 return occ;
1898 }
1899
e83120bd 1900 if ( dim == IndexOfOccupancyDimension() )
1901 {
1902 if ( ddlId < 0 ) AliError("Got a negative ddl id !");
1903 return occ/n/NumberOfEvents(ddlId);
1904 }
0145e89a 1905
1906 Double_t value = param.ValueAsDouble(i,dim);
1907
1908 if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
1909
49419555 1910 if ( TMath::Even(dim) || IsSingleEvent() )
0145e89a 1911 {
1c4173b3 1912 Double_t x = value/occ;
1913
1914 return ( TMath::Finite(x) ? x : 0.0 ) ;
0145e89a 1915 }
1916 else
1917 {
bf0d3528 1918 Double_t nn = occ;
0145e89a 1919
bf0d3528 1920 if ( nn > 1.0 )
49419555 1921 {
bf0d3528 1922 Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
b0565451 1923
bf0d3528 1924 return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
49419555 1925 }
1926 else
1927 {
1928 return 0.0;
1929 }
0145e89a 1930 }
1931
1932 AliError("Why am I here ?");
1933 return 0.0;
1934}
1935
e83120bd 1936//_____________________________________________________________________________
1937void
1938AliMUONTrackerData::Streamer(TBuffer &R__b)
1939{
1940 /// Customized streamer
1941
1942 if (R__b.IsReading()) {
1943 AliMUONTrackerData::Class()->ReadBuffer(R__b, this);
1944 if ( !fNofDDLs )
1945 {
1946 // backward compatible mode : we set number of events
1947 // per DDL to the total number of events (the only information
1948 // we had before version 7 of that class)
1949 delete[] fNofEventsPerDDL;
1950 fNofDDLs=20;
1951 fNofEventsPerDDL = new Int_t[fNofDDLs];
1952 for ( Int_t i = 0; i < fNofDDLs; ++i )
1953 {
1954 fNofEventsPerDDL[i] = fNevents;
1955 }
1956 }
1957 }
1958 else {
1959 AliMUONTrackerData::Class()->WriteBuffer(R__b, this);
1960 }
1961}
1962
7eafe398 1963//_____________________________________________________________________________
1964Bool_t
1965AliMUONTrackerData::ExportAsASCIIOccupancyFile(const char* filename, Int_t runNumber) const
1966{
1967 /// Export only the occupancy part, in a format compatible with what
1968 /// the online occupancy DA is writing
1969
1970 if ( ! AliMpDDLStore::Instance(kFALSE) )
1971 {
1972 AliError("Mapping not loaded. Cannot work");
1973 return kFALSE;
1974 }
1975
1976 if (!fManuValues)
1977 {
1978 AliError("No manu values. Cannot work");
1979 return kFALSE;
1980 }
1981
1982 ofstream out(filename);
1983
1984 if (out.bad())
1985 {
1986 AliError(Form("Cannot create file %s",filename));
1987 return kFALSE;
1988 }
1989
1990 out << "//===========================================================================" << endl;
1991 out << "// Hit counter exported from $Id$" << endl;
1992 out << "//===========================================================================" << endl;
1993 out << "//" << endl;
1994 out << "// * Run Number : " << runNumber << endl;
1995 out << "// * File Creation Date : " << TTimeStamp().AsString("l") << endl;
1996 out << "//---------------------------------------------------------------------------" << endl;
1997 out << "// BP MANU SUM_N NEVENTS" << endl;
1998 out << "//---------------------------------------------------------------------------" << endl;
1999
2000 TIter next(fManuValues->CreateIterator());
2001 AliMUONVCalibParam* manu;
2002
2003 while ( ( manu = static_cast<AliMUONVCalibParam*>(next()) ) )
2004 {
2005 Int_t detElemId = manu->ID0();
2006 Int_t manuId = manu->ID1();
2007 Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
2008 Int_t ddl = AliMpDDLStore::Instance()->GetDDLfromBus( busPatchId);
2009 if ( busPatchId < 0 || ddl < 0 )
2010 {
2011 AliError(Form("Got invalid (DE,manu,bp,ddl)=(%d,%d,%d,%d). Skipping it",detElemId,manuId,busPatchId,ddl));
2012 continue;
2013 }
2014
2015 Int_t nevents = fNofEventsPerDDL[ddl];
2016
2017 out << Form("%5d %5d %10d %10d",busPatchId,manuId,manu->ValueAsInt(0,IndexOfOccupancyDimension()),nevents) << endl;
2018 }
2019
2020 out.close();
2021 return kTRUE;
2022}
2023
e83120bd 2024