Error message removed when data is posted by other than the owner.
[u/mrichter/AliRoot.git] / MUON / AliMUONTrackerData.cxx
CommitLineData
0145e89a 1/**************************************************************************
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
7* Permission to use, copy, modify and distribute this software and its *
8* documentation strictly for non-commercial purposes is hereby granted *
9* without fee, provided that the above copyright notice appears in all *
10* copies and that both the copyright notice and this permission notice *
11* appear in the supporting documentation. The authors make no claims *
12* about the suitability of this software for any purpose. It is *
13* provided "as is" without express or implied warranty. *
14**************************************************************************/
15
16// $Id$
17
18#include "AliMUONTrackerData.h"
19
8741815f 20#include "AliCodeTimer.h"
e83120bd 21#include "AliDAQ.h"
8741815f 22#include "AliLog.h"
23#include "AliMUON1DArray.h"
24#include "AliMUON1DMap.h"
25#include "AliMUON2DMap.h"
0145e89a 26#include "AliMUONCalibParamND.h"
8741815f 27#include "AliMUONSparseHisto.h"
0145e89a 28#include "AliMUONVStore.h"
29#include "AliMpBusPatch.h"
8741815f 30#include "AliMpConstants.h"
ab167304 31#include "AliMpCDB.h"
0145e89a 32#include "AliMpDDLStore.h"
ab167304 33#include "AliMpManuStore.h"
0145e89a 34#include "AliMpDEIterator.h"
8741815f 35#include "AliMpDEManager.h"
0145e89a 36#include "AliMpDetElement.h"
49e110ec 37#include "AliMpDCSNamer.h"
8741815f 38#include "AliMpManuIterator.h"
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)
0145e89a 117{
8741815f 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)
1ffbeb9d 333{
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 }
49419555 345 }
e83120bd 346
347 if (!fNofDDLs)
348 {
349 fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK");
350 fNofEventsPerDDL = new Int_t[fNofDDLs];
351 for ( Int_t i = 0; i < fNofDDLs; ++i )
352 {
353 fNofEventsPerDDL[i] = 0;
354 }
355 }
356
357 if (nevents)
358 {
359 if (nevents->GetSize() != fNofDDLs )
360 {
361 AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d",
362 nevents->GetSize(),fNofDDLs));
363 return kFALSE;
364 }
365
366 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
367 {
368 fNofEventsPerDDL[i] += nevents->At(i);
369 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
370 }
371 }
372 else
373 {
374 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
375 {
376 ++fNofEventsPerDDL[i];
377 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
378 }
379 }
49419555 380
e13620cd 381 if (!fChamberValues)
8741815f 382 {
49419555 383 Int_t numberOfBusPatches(0);
384 Int_t numberOfDEs(0);
385
386 // get number of bus patches and number of detection element
387 // to initialize fBusPatchValues and fDEValues below
388
630711ed 389 TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
390 while ( next() ) ++numberOfBusPatches;
49419555 391 AliMpDEIterator deIt;
392 deIt.First();
393 while (!deIt.IsDone())
394 {
395 ++numberOfDEs;
396 deIt.Next();
397 }
398
e13620cd 399 if ( fIsChannelLevelEnabled )
400 {
401 fChannelValues = new AliMUON2DMap(kTRUE);
402 }
0edb62c4 403 if ( fIsManuLevelEnabled )
404 {
405 fManuValues = new AliMUON2DMap(kTRUE);
406 }
7b6684fe 407 fPCBValues = new AliMUON2DMap(kFALSE);
49419555 408 fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
409 fDEValues = new AliMUON1DMap(numberOfDEs);
8741815f 410 fChamberValues = new AliMUON1DArray;
411 }
0145e89a 412
413 TIter next(store.CreateIterator());
414 AliMUONVCalibParam* external;
415
49419555 416 Int_t nk(2);
417
418 if ( IsSingleEvent() ) nk = 1;
419
0145e89a 420 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
421 {
8741815f 422 if ( external->Dimension() != ExternalDimension() )
423 {
424 AliError(Form("Incompatible dimensions %d vs %d",
425 external->Dimension(),ExternalDimension()));
426 return kFALSE;
427 }
0145e89a 428
8741815f 429
430 AliMUONVCalibParam* chamber, *de, *busPatch, *pcb, *manu, *channel;
431 AliMpDetElement* mpde;
0145e89a 432
8741815f 433 Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
0145e89a 434
7b6684fe 435 if ( manuId < 0 ) continue;
436
8741815f 437 Int_t detElemId = mpde->GetId();
438
439 Double_t value[] = { 0.0, 0.0 };
440
441 Int_t nch = mpde->NofChannelsInManu(manuId);
0145e89a 442
443 for ( Int_t i = 0; i < external->Size(); ++i )
444 {
8741815f 445 Bool_t existingChannel = ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
446 : mpde->IsConnectedChannel(manuId,i));
447 // note we only use IsConnectedChannel method when really needed, as
448 // it costs (some) CPU time...
0145e89a 449
8741815f 450 if ( existingChannel )
0145e89a 451 {
8741815f 452 Bool_t validChannel(kFALSE);
0145e89a 453
8741815f 454 for ( Int_t j = 0; j < external->Dimension(); ++j )
455 {
456 Double_t vext = external->IsDoublePrecision() ?
457 external->ValueAsDoubleFast(i,j) :
458 external->ValueAsFloatFast(i,j);
459
460 if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
461
462 validChannel = kTRUE;
463
464 Int_t ix = External2Internal(j);
465
466 value[0] = vext;
467 value[1] = vext*vext;
468
469 if ( IsHistogrammed(j) )
470 {
0edb62c4 471 FillHisto(detElemId,manuId,i,j,vext);
8741815f 472 }
473
49419555 474 for ( Int_t k = 0; k < nk; ++k )
8741815f 475 {
e13620cd 476 Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
1ffbeb9d 477
e13620cd 478 if ( channel )
479 {
480 channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
481 }
482
0edb62c4 483 if (manu)
484 {
485 manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);
486 }
1ffbeb9d 487
488 busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
489
490 de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
491
492 chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
8741815f 493
8741815f 494 if ( pcb )
495 {
1ffbeb9d 496 pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
8741815f 497 }
498 }
499 }
0145e89a 500
1ffbeb9d 501 if ( validChannel && !replace )
8741815f 502 {
e13620cd 503 if ( channel )
504 {
505 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
506 channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
507 }
508
0edb62c4 509 if (manu)
510 {
511 manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
512 manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
513 }
514
8741815f 515 busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
516 busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
517 de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
518 de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
519 chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
520 chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
521 if ( pcb )
522 {
523 pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
524 pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
525 }
526 }
0145e89a 527 }
528 }
529 }
530
f6358d9e 531 NumberOfEventsChanged();
532
0145e89a 533 return kTRUE;
534}
535
536//_____________________________________________________________________________
537Double_t
538AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
539{
540 /// Return the value of a given buspatch for a given dimension
541 /// or 0 if not existing
542 AliMUONVCalibParam* param = BusPatchParam(busPatchId);
e83120bd 543 return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0;
0145e89a 544}
545
546//_____________________________________________________________________________
547AliMUONVCalibParam*
8741815f 548AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
0145e89a 549{
550 /// Return (if it exist), the VCalibParam for a given busPatch
8741815f 551
552 AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
553 (fBusPatchValues->FindObject(busPatchId)) : 0x0;
554
555 if (!busPatch && create && fBusPatchValues)
556 {
557 busPatch = CreateBusPatchParam(busPatchId);
558 fBusPatchValues->Add(busPatch);
559 }
560
561 return busPatch;
562}
563
564//_____________________________________________________________________________
565AliMUONVCalibParam*
566AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
567{
568 /// Create storage for one bus patch
569
570 AliCodeTimerAuto("");
571
572 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
573
574 if (!bp)
575 {
576 AliError(Form("Got an invalid buspatchId = %d",busPatchId));
577 return 0x0;
578 }
579
580 AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
581
582 // set the number of channels in that buspatch
583
584 Int_t nchannels(0);
585
586 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
587
588 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
589
590 for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
591 {
592 Int_t manuId = bp->GetManuId(i);
593 nchannels += de->NofChannelsInManu(manuId);
594 }
595
596 busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
597
598 return busPatch;
0145e89a 599}
600
601//_____________________________________________________________________________
602Double_t
603AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
604{
605 /// Return the value fo a given chamber for a given dimension,
606 /// or zero if not existing
e83120bd 607
608 // FIXME: is the Value() correct wrt to number of events in the case of
609 // chamber ? Or should we do something custom at the chamber level
610 // (as it spans several ddls) ?
611
0145e89a 612 AliMUONVCalibParam* param = ChamberParam(chamberId);
e83120bd 613 return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0;
0145e89a 614}
615
616//_____________________________________________________________________________
617AliMUONVCalibParam*
8741815f 618AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
0145e89a 619{
620 /// Return (if it exist) the VCalibParam for a given chamber
8741815f 621
622 AliMUONVCalibParam* chamber = fChamberValues ? static_cast<AliMUONVCalibParam*>
0145e89a 623 (fChamberValues->FindObject(chamberId)) : 0x0;
8741815f 624
625 if (!chamber && create && fChamberValues)
626 {
627 chamber = CreateChamberParam(chamberId);
628 fChamberValues->Add(chamber);
629 }
630
631 return chamber;
632}
633
634//_____________________________________________________________________________
635AliMUONVCalibParam*
636AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
637{
638 /// Create storage for one chamber
639
640 AliCodeTimerAuto("");
641
642 AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
643
644 // set the number of channels in that chamber
645
646 Int_t nchannels(0);
647
648 AliMpDEIterator it;
649
650 it.First(chamberId);
651
652 while ( !it.IsDone() )
653 {
654 AliMpDetElement* det = it.CurrentDE();
655
656 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
657 {
658 Int_t busPatchId = det->GetBusPatchId(i);
659 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
660 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
661 {
662 Int_t manuId = bp->GetManuId(j);
663 nchannels += det->NofChannelsInManu(manuId);
664 }
665 }
666
667 it.Next();
668 }
669
670 chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
671
672 return chamber;
0145e89a 673}
674
675//_____________________________________________________________________________
676Double_t
677AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId,
678 Int_t manuChannel, Int_t dim) const
679{
680 /// Return the value for a given channel for a given dimension
681
682 AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
683
e83120bd 684 return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
0145e89a 685}
686
687//_____________________________________________________________________________
688AliMUONVCalibParam*
8741815f 689AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
690 AliMUONVCalibParam* external) const
0145e89a 691{
692 /// Return (if it exist) the VCalibParam for a given manu
8741815f 693
694 AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
695 (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
696
697 if (!param && external && fChannelValues)
698 {
7b6684fe 699 param = CreateDouble(*external,detElemId,manuId);
8741815f 700 fChannelValues->Add(param);
701 }
702
703 return param;
0145e89a 704}
705
0145e89a 706//_____________________________________________________________________________
707void
708AliMUONTrackerData::Clear(Option_t*)
709{
710 /// Clear all the values
711 if ( fChannelValues ) fChannelValues->Clear();
712 if ( fManuValues ) fManuValues->Clear();
713 if ( fBusPatchValues) fBusPatchValues->Clear();
714 if ( fPCBValues ) fPCBValues->Clear();
715 if ( fDEValues) fDEValues->Clear();
8741815f 716 if ( fChamberValues ) fChamberValues->Clear();
0edb62c4 717 if ( fHistos ) fHistos->Clear();
e83120bd 718 for ( Int_t i = 0; i < fNofDDLs; ++i )
719 {
720 fNofEventsPerDDL[i] = 0;
721 }
0145e89a 722 NumberOfEventsChanged();
723}
724
725//_____________________________________________________________________________
726Double_t
727AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId,
728 Int_t manuChannel) const
729{
730 /// Return the number of times a given channel had data
0145e89a 731
8741815f 732 return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
0145e89a 733}
734
735//_____________________________________________________________________________
736AliMUONVCalibParam*
7b6684fe 737AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param,
738 Int_t detElemId, Int_t manuId) const
0145e89a 739{
740 /// Create a double version of VCalibParam, for internal use
8741815f 741
742 AliCodeTimerAuto("");
743
744 AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
745 param.Size(),
7b6684fe 746 detElemId,
747 manuId,
8741815f 748 0.0);
0145e89a 749
7b6684fe 750 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
751
0145e89a 752 for ( Int_t i = 0; i < c->Size(); ++i )
753 {
7b6684fe 754 Double_t value(0.0);
755
756 if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
757
758 c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
0145e89a 759 }
760
761 return c;
762}
763
764//_____________________________________________________________________________
765Double_t
766AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
767{
768 /// Return the value for a given detection element for a given dimension
769 AliMUONVCalibParam* param = DetectionElementParam(detElemId);
e83120bd 770 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
0145e89a 771
772}
773
774//_____________________________________________________________________________
775AliMUONVCalibParam*
8741815f 776AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
0145e89a 777{
778 /// Return (if it exist) the VCalibParam for a given detection element
8741815f 779
780 AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
781 (fDEValues->FindObject(detElemId)) : 0x0 ;
782
783 if (!de && create && fDEValues)
784 {
785 de = CreateDetectionElementParam(detElemId);
786 fDEValues->Add(de);
787 }
788
789 return de;
790
791}
792
793//_____________________________________________________________________________
794AliMUONVCalibParam*
795AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
796{
797 /// Create storage for one detection element
798
799 AliCodeTimerAuto("");
800
801 AliMUONVCalibParam* de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
802
803 AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
804 Int_t nchannels(0);
805
806 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
807 {
808 Int_t busPatchId = det->GetBusPatchId(i);
809 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
810 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
811 {
812 Int_t manuId = bp->GetManuId(j);
813 nchannels += det->NofChannelsInManu(manuId);
814 }
815 }
816
817 de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
818
819 return de;
0145e89a 820}
821
822//_____________________________________________________________________________
e83120bd 823Int_t
824AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const
825{
826 /// Get the "local" ddlid (0..19) of a given buspatch
827 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid);
828 if (bp)
829 {
830 return bp->GetDdlId();
831 }
832 return -1;
833}
834
835//_____________________________________________________________________________
836Int_t
837AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const
838{
839 /// Get the "local" ddlid (0..19) of a given detection element
840 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid);
841 if (de)
842 {
843 return de->GetDdlId();
844 }
845 return -1;
846}
847
848//_____________________________________________________________________________
849Int_t
850AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const
851{
852 /// Get the "local" ddlid (0..19) of a given chamber
853 /// This has no real meaning (as there are several ddls per chamber),
854 /// so we take the ddlid where we got the max number of events
855
856 AliMpDEIterator it;
857
858 it.First(chamberid);
859 Int_t n(0);
860 Int_t d(-1);
861
862 while (!it.IsDone())
863 {
864 Int_t detElemId = it.CurrentDEId();
865 Int_t ddlId = DdlIdFromDetElemId(detElemId);
866 if ( NumberOfEvents(ddlId) > n )
867 {
868 n = NumberOfEvents(ddlId);
869 d = ddlId;
870 }
871 it.Next();
872 }
873
874 return d;
875}
876
877//_____________________________________________________________________________
0145e89a 878TString
879AliMUONTrackerData::DimensionName(Int_t dim) const
880{
881 /// Get the name of a given dimension
882 TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
883 if ( value )
884 {
885 return value->String();
886 }
887 else
888 {
889 return TString("Invalid");
890 }
891}
892
893//_____________________________________________________________________________
e13620cd 894void
895AliMUONTrackerData::DisableChannelLevel()
896{
897 /// Disable the storing of data at channel level
898
899 delete fChannelValues;
900 fChannelValues = 0x0;
901 fIsChannelLevelEnabled = kFALSE;
902}
903
904//_____________________________________________________________________________
0edb62c4 905void
906AliMUONTrackerData::DisableManuLevel()
907{
908 /// Disable the storing of data at manu level (and below)
909
910 DisableChannelLevel();
911 delete fManuValues;
912 fManuValues = 0x0;
913 fIsManuLevelEnabled = kFALSE;
914}
915
916//_____________________________________________________________________________
49419555 917Int_t
918AliMUONTrackerData::External2Internal(Int_t index) const
919{
920 /// From external to internal dimension
921 return IsSingleEvent() ? index : index*2;
922}
923
924//_____________________________________________________________________________
8741815f 925TString
926AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
0145e89a 927{
8741815f 928 /// Get the name of a given external dimension
929
930 TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
931 if ( value )
932 {
933 return value->String();
934 }
935 else
936 {
937 return TString("Invalid");
938 }
0145e89a 939}
940
941//_____________________________________________________________________________
8741815f 942void
0edb62c4 943AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel,
944 Int_t dim, Double_t value)
0145e89a 945{
8741815f 946 /// Fill histogram of a given channel
947
0edb62c4 948 AliMUONSparseHisto* h(0x0);
949
e13620cd 950 if ( fIsChannelLevelEnabled )
951 {
0edb62c4 952 h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
953 }
954 else if ( fIsManuLevelEnabled )
955 {
956 h = GetManuSparseHisto(detElemId,manuId,dim);
957 }
958
959 AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h));
960
961 if (h)
962 {
e13620cd 963 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
964 }
0145e89a 965}
966
967//_____________________________________________________________________________
10eb3d17 968AliMUONSparseHisto*
0edb62c4 969AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId,
970 Int_t dim) const
971{
972 /// Get histogram of a given manu
973
974 if (!fHistos) return 0x0;
975
976 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
977 if (!m) return 0x0;
978
979 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
980
981 return h;
982}
983
984//_____________________________________________________________________________
985AliMUONSparseHisto*
986AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim)
987{
988 /// Get histogram of a given manu. Create it if necessary
989
990 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
991
992 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
993 if (!m)
994 {
995 m = new AliMUON1DArray(NumberOfDimensions());
996 m->SetUniqueID( ( manuId << 16 ) | detElemId );
997 fHistos->Add(m);
998 }
999
1000 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1001 if (!h)
1002 {
1003 h = new AliMUONSparseHisto(fXmin,fXmax);
1004
1005 h->SetUniqueID(dim);
1006
1007 m->Add(h);
1008 }
1009
1010 return h;
1011}
1012
1013//_____________________________________________________________________________
1014AliMUONSparseHisto*
10eb3d17 1015AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1016 Int_t manuChannel, Int_t dim) const
8741815f 1017{
10eb3d17 1018 /// Get histogram of a given channel
8741815f 1019
0edb62c4 1020 if (!fHistos) return 0x0;
8741815f 1021
0edb62c4 1022 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
10eb3d17 1023 if (!m) return 0x0;
8741815f 1024
10eb3d17 1025 UInt_t uid = ( manuChannel << 16 ) | dim;
8741815f 1026
10eb3d17 1027 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
8741815f 1028
1029 return h;
1030}
0145e89a 1031
8741815f 1032//_____________________________________________________________________________
1033AliMUONSparseHisto*
10eb3d17 1034AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1035 Int_t manuChannel, Int_t dim)
8741815f 1036{
10eb3d17 1037 /// Get histogram of a given channel. Create it if necessary
8741815f 1038
0edb62c4 1039 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
8741815f 1040
0edb62c4 1041 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
10eb3d17 1042 if (!m)
8741815f 1043 {
10eb3d17 1044 m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
1045 m->SetUniqueID( ( manuId << 16 ) | detElemId );
0edb62c4 1046 fHistos->Add(m);
8741815f 1047 }
1048
10eb3d17 1049 UInt_t uid = ( manuChannel << 16 ) | dim;
8741815f 1050
10eb3d17 1051 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
8741815f 1052 if (!h)
1053 {
10eb3d17 1054 h = new AliMUONSparseHisto(fXmin,fXmax);
1055
1056 h->SetUniqueID(uid);
1057
1058 m->Add(h);
8741815f 1059 }
0145e89a 1060
8741815f 1061 return h;
1062}
0145e89a 1063
8741815f 1064//_____________________________________________________________________________
e83120bd 1065void
1066AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param,
1067 Int_t& detElemId, Int_t& manuId) const
1068{
1069 /// Tries to get (detElemId,manuId) of param
1070
ab167304 1071 // Load mapping manu store
1072 if ( ! AliMpCDB::LoadManuStore() ) {
1073 AliError("Could not access manu store from OCDB !");
1074 return;
1075 }
1076
e83120bd 1077 if ( param.ID1() <= 0 )
1078 {
1079 // we (probably) get a manu serial number
1080 Int_t serial = param.ID0();
ab167304 1081 AliMpIntPair pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial);
e83120bd 1082 detElemId = pair.GetFirst();
1083 manuId = pair.GetSecond();
1084 if ( !detElemId )
1085 {
1086 AliError(Form("DE %d manuId %d from serial %d is not correct !",
1087 detElemId,manuId,serial));
1088 }
1089 }
1090 else
1091 {
1092 // we get a (de,manu) pair
1093 detElemId = param.ID0();
1094 manuId = param.ID1();
1095 }
1096}
1097
1098
1099//_____________________________________________________________________________
8741815f 1100Int_t
1101AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
1102 AliMUONVCalibParam*& chamber,
1103 AliMUONVCalibParam*& de,
1104 AliMUONVCalibParam*& busPatch,
1105 AliMUONVCalibParam*& pcb,
1106 AliMUONVCalibParam*& manu,
1107 AliMUONVCalibParam*& channel,
1108 AliMpDetElement*& mpde)
1109{
1110 /// Get containers at all levels
1111
1112 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1113
7b6684fe 1114 Int_t detElemId;
1115 Int_t manuId;
8741815f 1116
e83120bd 1117 GetDEManu(*external,detElemId,manuId);
1118
8741815f 1119 mpde = ddlStore->GetDetElement(detElemId);
7b6684fe 1120
f6358d9e 1121 if (!mpde) // can happen if reading e.g. capacitances store where we have data for non-connected manus
1122 {
1123 return -1;
1124 }
1125
7b6684fe 1126 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1127
8741815f 1128 Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1129
1130 Int_t pcbIndex = -1;
1131
1132 AliMp::StationType stationType = mpde->GetStationType();
1133
1134 if ( stationType == AliMp::kStation345 )
1135 {
49e110ec 1136 AliMpDCSNamer namer("TRACKER");
8741815f 1137 pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
1138 }
1139
1140 channel = ChannelParam(detElemId,manuId,external);
1141
1142 manu = ManuParam(detElemId,manuId,kTRUE);
1143
1144 busPatch = BusPatchParam(busPatchId,kTRUE);
1145
1146 de = DetectionElementParam(detElemId,kTRUE);
1147
1148 chamber = ChamberParam(chamberId,kTRUE);
1149
1150 pcb = 0x0;
1151
1152 if ( pcbIndex >= 0 )
1153 {
1154 pcb = PCBParam(detElemId,pcbIndex,kTRUE);
0145e89a 1155 }
8741815f 1156
1157 return manuId;
1158}
0145e89a 1159
8741815f 1160//_____________________________________________________________________________
1161Bool_t
1162AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
1163{
1164 /// Whether we have data for a given buspatch
1165 return ( BusPatchParam(busPatchId) != 0 );
1166}
1167
1168//_____________________________________________________________________________
1169Bool_t
1170AliMUONTrackerData::HasChamber(Int_t chamberId) const
1171{
1172 /// Whether we have data for a given chamber
1173 return ( ChamberParam(chamberId) != 0 );
1174}
1175
1176//_____________________________________________________________________________
1177Bool_t
1178AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
1179{
1180 /// Whether we have data for a given detection element
1181 return ( DetectionElementParam(detElemId) != 0 );
1182}
1183
1184//_____________________________________________________________________________
1185Bool_t
1186AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
1187{
1188 /// Whether we have data for a given manu
1189 return ( ManuParam(detElemId,manuId) != 0 );
1190}
1191
1192//_____________________________________________________________________________
1193Bool_t
1194AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
1195{
1196 /// Whether we have data for a given pcb
1197 return ( PCBParam(detElemId,pcbIndex) != 0 );
0145e89a 1198}
1199
1200//_____________________________________________________________________________
1201Double_t
1202AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
1203{
9016a84e 1204 /// Return the value for a given manu and a given dimension
1205
0145e89a 1206 AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
e83120bd 1207 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
0145e89a 1208}
1209
1210//_____________________________________________________________________________
1211AliMUONVCalibParam*
8741815f 1212AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
0145e89a 1213{
9016a84e 1214 /// Get the VCalibParam for a given manu
8741815f 1215
1216 AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
1217 (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
1218
1219 if (!manu && create && fManuValues)
1220 {
1221 manu = CreateManuParam(detElemId,manuId);
1222 fManuValues->Add(manu);
1223 }
1224
1225 return manu;
1226}
1227
1228//_____________________________________________________________________________
1229AliMUONVCalibParam*
1230AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
1231{
1232 /// Create storage for one manu
1233
1234 AliCodeTimerAuto("");
1235
1236 AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
1237
1238 // set the number of channels in that manu
1239
1240 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1241
1242 manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
1243
1244 return manu;
0145e89a 1245}
1246
1247//_____________________________________________________________________________
7b6684fe 1248Long64_t
e83120bd 1249AliMUONTrackerData::Merge(TCollection* list)
7b6684fe 1250{
e83120bd 1251 /// Merge this with a list of AliMUONVTrackerData
1252
1253 if (!list) return 0;
7b6684fe 1254
e83120bd 1255 if ( list->IsEmpty() ) return NumberOfEvents(-1);
1256
1257 TIter next(list);
1258 const TObject* o(0x0);
1259
1260 while ( ( o = next() ) )
1261 {
1262 const AliMUONTrackerData* data = dynamic_cast<const AliMUONTrackerData*>(o);
1263 if (!o)
1264 {
1265 AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it",
1266 o->GetName()));
1267 }
1268 else
1269 {
1270 Bool_t ok = Add(*data);
1271 if (!ok)
1272 {
1273 AliError("Got incompatible objects");
1274 }
1275 }
1276 }
7b6684fe 1277
e83120bd 1278 return NumberOfEvents(-1);
7b6684fe 1279}
1280
1281//_____________________________________________________________________________
0145e89a 1282Int_t
1283AliMUONTrackerData::NumberOfDimensions() const
1284{
1285 /// Number of dimensions we're dealing with
1286
1287 return fDimension + fgkVirtualExtraDimension;
1288}
1289
1290//_____________________________________________________________________________
e83120bd 1291Int_t
1292AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const
1293{
1294 /// Get the number of events we've seen for a given DDL, or the max
1295 /// in case ddlNumber<0
1296
1297 Int_t n(0);
1298
1299 if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs )
1300 {
1301 n = fNofEventsPerDDL[ddlNumber];
1302 }
1303 else
1304 {
1305 // get the max number of events
1306 return fNevents;
1307 }
1308
1309 return n;
1310}
1311
1312//_____________________________________________________________________________
0145e89a 1313Double_t
1314AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
1315{
1316 /// Return the value of a given pcb for a given dimension
1317
1318 AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
1319
e83120bd 1320 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
0145e89a 1321}
1322
1323//_____________________________________________________________________________
1324AliMUONVCalibParam*
8741815f 1325AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
0145e89a 1326{
1327 /// Return (if it exist) the VCalibParam for a given pcb
8741815f 1328
1329 AliMUONVCalibParam* pcb = fPCBValues ? static_cast<AliMUONVCalibParam*>
1330 (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
1331
1332 if (create && fPCBValues && !pcb)
1333 {
1334 pcb = CreatePCBParam(detElemId,pcbIndex);
1335 fPCBValues->Add(pcb);
1336 }
1337
1338 return pcb;
1339}
1340
1341//_____________________________________________________________________________
1342AliMUONVCalibParam*
1343AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
1344{
1345 /// Create storage for one PCB (station345 only)
1346
1347 AliCodeTimerAuto("");
1348
49e110ec 1349 AliMpDCSNamer namer("TRACKER");
8741815f 1350
1351 AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
1352 namer.NumberOfPCBs(detElemId),
1353 detElemId,
1354 pcbIndex,
1355 0.0);
1356 return pcb;
0145e89a 1357}
1358
1359//_____________________________________________________________________________
1360void
1361AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
1362{
1363 /// Printout
1364
1365 TNamed::Print(opt);
1366
49419555 1367 if ( !fIsSingleEvent )
0145e89a 1368 {
e83120bd 1369 for ( Int_t i = 0; i < fNofDDLs; ++i )
1370 {
1371 cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl;
1372 }
0145e89a 1373 }
8741815f 1374
0edb62c4 1375 if ( !fIsChannelLevelEnabled )
1376 {
1377 cout << "Is not storing data at the channel level" << endl;
1378 }
1379
1380 if ( !fIsManuLevelEnabled )
e13620cd 1381 {
0edb62c4 1382 cout << "Is not storing data at the manu level" << endl;
e13620cd 1383 }
0edb62c4 1384
8741815f 1385 for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i )
1386 {
1387 TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
1388 cout << Form("External Dimension %2d Name %s %s",i,
1389 ( name ? name->String().Data() : "null"),
1390 ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
1391 }
0145e89a 1392
1393 for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i )
1394 {
1395 TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
8741815f 1396 cout << Form("Internal Dimension %2d Name %s",i,
0145e89a 1397 ( name ? name->String().Data() : "null")) << endl;
1398 }
8741815f 1399
0145e89a 1400 TString sopt(opt);
1401 sopt.ToUpper();
1402
0edb62c4 1403 if ( sopt.Contains("CHANNEL") )
0145e89a 1404 {
0edb62c4 1405 if ( fIsChannelLevelEnabled )
1406 {
1407 if ( fChannelValues ) fChannelValues->Print(wildcard,opt);
1408 }
1409 else
1410 {
1411 AliWarning("You requested channel values, but they were not stored !");
1412 }
0145e89a 1413 }
1414
0edb62c4 1415 if ( sopt.Contains("MANU") )
0145e89a 1416 {
0edb62c4 1417 if ( fIsManuLevelEnabled )
1418 {
1419 if ( fManuValues ) fManuValues->Print(wildcard,opt);
1420 }
1421 else
1422 {
1423 AliWarning("You requested manu values, but they were not stored !");
1424 }
0145e89a 1425 }
1426
1427 if ( sopt.Contains("BUSPATCH") && fBusPatchValues )
1428 {
1429 fBusPatchValues->Print(wildcard,opt);
1430 }
1431
1432 if ( sopt.Contains("DE") && fDEValues )
1433 {
1434 fDEValues->Print(wildcard,opt);
1435 }
1436
1437 if ( sopt.Contains("CHAMBER") && fChamberValues )
1438 {
1439 fChamberValues->Print(wildcard,opt);
1440 }
1441
1442}
1443
1444//_____________________________________________________________________________
1445void
1446AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
1447{
1448 /// Set the name of a given dimension
1449
1450 if ( index >= fExternalDimension )
1451 {
1452 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
1453 return;
1454 }
1455
1456 Int_t ix = External2Internal(index);
1457
49419555 1458 if ( !IsSingleEvent() )
0145e89a 1459 {
49419555 1460 const char* prefix[] = { "mean", "sigma" };
1461
1462 for ( Int_t i = 0; i < 2; ++i )
1463 {
1464 Int_t j = ix+i;
0145e89a 1465
49419555 1466 SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
1467 }
1468 }
1469 else
1470 {
1471 SetInternalDimensionName(index,name);
0145e89a 1472 }
8741815f 1473
1474 SetExternalDimensionName(index,name);
1475}
1476
1477//_____________________________________________________________________________
1478void
10eb3d17 1479AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
8741815f 1480{
1481 /// decide to make histos for a given dimension
1482 if ( index >= ExternalDimension() )
1483 {
1484 AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
1485 return;
1486 }
1487
1488 fHistogramming[index] = value;
10eb3d17 1489 fXmin = xmin;
1490 fXmax = xmax;
0145e89a 1491}
1492
1493//_____________________________________________________________________________
1494void
1495AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
1496{
1497 /// Set the name of a given internal dimension
1498 if ( index >= fDimension )
1499 {
1500 AliError(Form("Index out of bounds : %d / %d",index,fDimension));
1501 return;
1502 }
1503
1504 TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
1505
1506 if ( ovalue )
1507 {
1508 fDimensionNames->Remove(ovalue);
1509 delete ovalue;
1510 }
1511 fDimensionNames->AddAt(new TObjString(value),index);
1512}
1513
1514//_____________________________________________________________________________
8741815f 1515void
1516AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
1517{
1518 /// Set the name of a given external dimension
1519 if ( index >= fExternalDimension )
1520 {
1521 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
1522 return;
1523 }
1524
1525 TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
1526
1527 if ( ovalue )
1528 {
1529 fExternalDimensionNames->Remove(ovalue);
1530 delete ovalue;
1531 }
1532 fExternalDimensionNames->AddAt(new TObjString(value),index);
1533}
1534
1535//_____________________________________________________________________________
0145e89a 1536Double_t
e83120bd 1537AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i,
1538 Int_t dim, Int_t ddlId) const
0145e89a 1539{
1540 /// Compute the value for a given dim, using the internal information we have
1541 /// Basically we're converting sum of weights and sum of squares of weights
1542 /// into means and sigmas, and number of events into occupancy number.
1543
1544 Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
1545
1546 if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
1547
1548 Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
1549
1550 if ( dim >= fDimension )
1551 {
1552 return occ;
1553 }
1554
e83120bd 1555 if ( dim == IndexOfOccupancyDimension() )
1556 {
1557 if ( ddlId < 0 ) AliError("Got a negative ddl id !");
1558 return occ/n/NumberOfEvents(ddlId);
1559 }
0145e89a 1560
1561 Double_t value = param.ValueAsDouble(i,dim);
1562
1563 if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
1564
49419555 1565 if ( TMath::Even(dim) || IsSingleEvent() )
0145e89a 1566 {
1c4173b3 1567 Double_t x = value/occ;
1568
1569 return ( TMath::Finite(x) ? x : 0.0 ) ;
0145e89a 1570 }
1571 else
1572 {
bf0d3528 1573 Double_t nn = occ;
0145e89a 1574
bf0d3528 1575 if ( nn > 1.0 )
49419555 1576 {
bf0d3528 1577 Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
b0565451 1578
bf0d3528 1579 return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
49419555 1580 }
1581 else
1582 {
1583 return 0.0;
1584 }
0145e89a 1585 }
1586
1587 AliError("Why am I here ?");
1588 return 0.0;
1589}
1590
e83120bd 1591//_____________________________________________________________________________
1592void
1593AliMUONTrackerData::Streamer(TBuffer &R__b)
1594{
1595 /// Customized streamer
1596
1597 if (R__b.IsReading()) {
1598 AliMUONTrackerData::Class()->ReadBuffer(R__b, this);
1599 if ( !fNofDDLs )
1600 {
1601 // backward compatible mode : we set number of events
1602 // per DDL to the total number of events (the only information
1603 // we had before version 7 of that class)
1604 delete[] fNofEventsPerDDL;
1605 fNofDDLs=20;
1606 fNofEventsPerDDL = new Int_t[fNofDDLs];
1607 for ( Int_t i = 0; i < fNofDDLs; ++i )
1608 {
1609 fNofEventsPerDDL[i] = fNevents;
1610 }
1611 }
1612 }
1613 else {
1614 AliMUONTrackerData::Class()->WriteBuffer(R__b, this);
1615 }
1616}
1617
1618