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