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