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