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