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