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