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