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