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