Fixes in the HV-sector to manu mapping
[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"
21#include "AliLog.h"
22#include "AliMUON1DArray.h"
23#include "AliMUON1DMap.h"
24#include "AliMUON2DMap.h"
0145e89a 25#include "AliMUONCalibParamND.h"
8741815f 26#include "AliMUONSparseHisto.h"
0145e89a 27#include "AliMUONVStore.h"
28#include "AliMpBusPatch.h"
8741815f 29#include "AliMpConstants.h"
0145e89a 30#include "AliMpDDLStore.h"
0145e89a 31#include "AliMpDEIterator.h"
8741815f 32#include "AliMpDEManager.h"
0145e89a 33#include "AliMpDetElement.h"
34#include "AliMpHVNamer.h"
8741815f 35#include "AliMpManuIterator.h"
0145e89a 36#include <Riostream.h>
37#include <TMath.h>
38#include <TObjArray.h>
39#include <TObjString.h>
40#include <TString.h>
41#include <TVector2.h>
42#include <float.h>
43
44/// \class AliMUONTrackerData
45///
46/// Implementation of AliMUONVTrackerData class
47///
48/// \author Laurent Aphecetche, Subatech
49
50///\cond CLASSIMP
51ClassImp(AliMUONTrackerData)
52///\endcond
53
54const Int_t AliMUONTrackerData::fgkExtraDimension = 2;
55const Int_t AliMUONTrackerData::fgkVirtualExtraDimension = 1;
56
57//_____________________________________________________________________________
58AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
59 Int_t dimension,
49419555 60 Bool_t issingleevent)
0145e89a 61: AliMUONVTrackerData(name,title),
49419555 62fIsSingleEvent(issingleevent),
0145e89a 63fChannelValues(0x0),
64fManuValues(0x0),
65fBusPatchValues(0x0),
66fDEValues(0x0),
67fChamberValues(0x0),
68fPCBValues(0x0),
49419555 69fDimension(External2Internal(dimension)+fgkExtraDimension),
0145e89a 70fNevents(0x0),
71fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
8741815f 72fExternalDimensionNames(new TObjArray(dimension)),
0145e89a 73fExternalDimension(dimension),
8741815f 74fHistogramming(new Int_t[fExternalDimension]),
10eb3d17 75fChannelHistos(0x0),
76fXmin(0.0),
77fXmax(0.0)
0145e89a 78{
79 /// ctor
10eb3d17 80 memset(fHistogramming,0,sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
8741815f 81 fExternalDimensionNames->SetOwner(kTRUE);
0145e89a 82 fDimensionNames->SetOwner(kTRUE);
83 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
84 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
85 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
86 Clear();
87}
88
89//_____________________________________________________________________________
90AliMUONTrackerData::~AliMUONTrackerData()
91{
92 /// dtor
93 delete fChannelValues;
94 delete fManuValues;
95 delete fBusPatchValues;
96 delete fDEValues;
97 delete fChamberValues;
98 delete fPCBValues;
99 delete fDimensionNames;
8741815f 100 delete fExternalDimensionNames;
101 delete[] fHistogramming;
102 delete fChannelHistos;
0145e89a 103}
104
105//_____________________________________________________________________________
106Bool_t
49419555 107AliMUONTrackerData::Add(const AliMUONVStore& store)
0145e89a 108{
8741815f 109 /// Add the given external store to our internal store
0145e89a 110
8741815f 111 AliCodeTimerAuto(GetName());
112
49419555 113 if ( IsSingleEvent() && fNevents == 1 )
114 {
115 AliError(Form("%s is supposed to be single event only",GetName()));
116 return kFALSE;
117 }
118
119 ++fNevents;
120
8741815f 121 NumberOfEventsChanged();
0145e89a 122
8741815f 123 if (!fChannelValues)
124 {
49419555 125 Int_t numberOfBusPatches(0);
126 Int_t numberOfDEs(0);
127
128 // get number of bus patches and number of detection element
129 // to initialize fBusPatchValues and fDEValues below
130
630711ed 131 TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
132 while ( next() ) ++numberOfBusPatches;
49419555 133 AliMpDEIterator deIt;
134 deIt.First();
135 while (!deIt.IsDone())
136 {
137 ++numberOfDEs;
138 deIt.Next();
139 }
140
7b6684fe 141 fChannelValues = new AliMUON2DMap(kTRUE);
142 fManuValues = new AliMUON2DMap(kTRUE);
143 fPCBValues = new AliMUON2DMap(kFALSE);
49419555 144 fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
145 fDEValues = new AliMUON1DMap(numberOfDEs);
8741815f 146 fChamberValues = new AliMUON1DArray;
147 }
0145e89a 148
149 TIter next(store.CreateIterator());
150 AliMUONVCalibParam* external;
151
49419555 152 Int_t nk(2);
153
154 if ( IsSingleEvent() ) nk = 1;
155
0145e89a 156 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
157 {
8741815f 158 if ( external->Dimension() != ExternalDimension() )
159 {
160 AliError(Form("Incompatible dimensions %d vs %d",
161 external->Dimension(),ExternalDimension()));
162 return kFALSE;
163 }
0145e89a 164
8741815f 165
166 AliMUONVCalibParam* chamber, *de, *busPatch, *pcb, *manu, *channel;
167 AliMpDetElement* mpde;
0145e89a 168
8741815f 169 Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
0145e89a 170
7b6684fe 171 if ( manuId < 0 ) continue;
172
8741815f 173 Int_t detElemId = mpde->GetId();
174
175 Double_t value[] = { 0.0, 0.0 };
176
177 Int_t nch = mpde->NofChannelsInManu(manuId);
0145e89a 178
179 for ( Int_t i = 0; i < external->Size(); ++i )
180 {
8741815f 181 Bool_t existingChannel = ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
182 : mpde->IsConnectedChannel(manuId,i));
183 // note we only use IsConnectedChannel method when really needed, as
184 // it costs (some) CPU time...
0145e89a 185
8741815f 186 if ( existingChannel )
0145e89a 187 {
8741815f 188 Bool_t validChannel(kFALSE);
0145e89a 189
8741815f 190 for ( Int_t j = 0; j < external->Dimension(); ++j )
191 {
192 Double_t vext = external->IsDoublePrecision() ?
193 external->ValueAsDoubleFast(i,j) :
194 external->ValueAsFloatFast(i,j);
195
196 if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
197
198 validChannel = kTRUE;
199
200 Int_t ix = External2Internal(j);
201
202 value[0] = vext;
203 value[1] = vext*vext;
204
205 if ( IsHistogrammed(j) )
206 {
207 FillChannel(detElemId,manuId,i,j,vext);
208 }
209
49419555 210 for ( Int_t k = 0; k < nk; ++k )
8741815f 211 {
212 channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)+value[k]);
213
214 manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)+value[k]);
215
216 busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)+value[k]);
217
218 de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)+value[k]);
219
220 chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)+value[k]);
221
222 if ( pcb )
223 {
224 pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)+value[k]);
225 }
226 }
227 }
0145e89a 228
8741815f 229 if ( validChannel )
230 {
231 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
232 channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
233 manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
234 manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
235 busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
236 busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
237 de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
238 de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
239 chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
240 chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
241 if ( pcb )
242 {
243 pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
244 pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
245 }
246 }
0145e89a 247 }
248 }
249 }
250
0145e89a 251 return kTRUE;
252}
253
254//_____________________________________________________________________________
255Double_t
256AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
257{
258 /// Return the value of a given buspatch for a given dimension
259 /// or 0 if not existing
260 AliMUONVCalibParam* param = BusPatchParam(busPatchId);
261 return param ? Value(*param,0,dim) : 0.0;
262}
263
264//_____________________________________________________________________________
265AliMUONVCalibParam*
8741815f 266AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
0145e89a 267{
268 /// Return (if it exist), the VCalibParam for a given busPatch
8741815f 269
270 AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
271 (fBusPatchValues->FindObject(busPatchId)) : 0x0;
272
273 if (!busPatch && create && fBusPatchValues)
274 {
275 busPatch = CreateBusPatchParam(busPatchId);
276 fBusPatchValues->Add(busPatch);
277 }
278
279 return busPatch;
280}
281
282//_____________________________________________________________________________
283AliMUONVCalibParam*
284AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
285{
286 /// Create storage for one bus patch
287
288 AliCodeTimerAuto("");
289
290 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
291
292 if (!bp)
293 {
294 AliError(Form("Got an invalid buspatchId = %d",busPatchId));
295 return 0x0;
296 }
297
298 AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
299
300 // set the number of channels in that buspatch
301
302 Int_t nchannels(0);
303
304 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
305
306 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
307
308 for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
309 {
310 Int_t manuId = bp->GetManuId(i);
311 nchannels += de->NofChannelsInManu(manuId);
312 }
313
314 busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
315
316 return busPatch;
0145e89a 317}
318
319//_____________________________________________________________________________
320Double_t
321AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
322{
323 /// Return the value fo a given chamber for a given dimension,
324 /// or zero if not existing
325 AliMUONVCalibParam* param = ChamberParam(chamberId);
326 return param ? Value(*param,0,dim) : 0.0;
327}
328
329//_____________________________________________________________________________
330AliMUONVCalibParam*
8741815f 331AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
0145e89a 332{
333 /// Return (if it exist) the VCalibParam for a given chamber
8741815f 334
335 AliMUONVCalibParam* chamber = fChamberValues ? static_cast<AliMUONVCalibParam*>
0145e89a 336 (fChamberValues->FindObject(chamberId)) : 0x0;
8741815f 337
338 if (!chamber && create && fChamberValues)
339 {
340 chamber = CreateChamberParam(chamberId);
341 fChamberValues->Add(chamber);
342 }
343
344 return chamber;
345}
346
347//_____________________________________________________________________________
348AliMUONVCalibParam*
349AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
350{
351 /// Create storage for one chamber
352
353 AliCodeTimerAuto("");
354
355 AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
356
357 // set the number of channels in that chamber
358
359 Int_t nchannels(0);
360
361 AliMpDEIterator it;
362
363 it.First(chamberId);
364
365 while ( !it.IsDone() )
366 {
367 AliMpDetElement* det = it.CurrentDE();
368
369 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
370 {
371 Int_t busPatchId = det->GetBusPatchId(i);
372 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
373 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
374 {
375 Int_t manuId = bp->GetManuId(j);
376 nchannels += det->NofChannelsInManu(manuId);
377 }
378 }
379
380 it.Next();
381 }
382
383 chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
384
385 return chamber;
0145e89a 386}
387
388//_____________________________________________________________________________
389Double_t
390AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId,
391 Int_t manuChannel, Int_t dim) const
392{
393 /// Return the value for a given channel for a given dimension
394
395 AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
396
397 return param ? Value(*param,manuChannel,dim) : 0.0;
398}
399
400//_____________________________________________________________________________
401AliMUONVCalibParam*
8741815f 402AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
403 AliMUONVCalibParam* external) const
0145e89a 404{
405 /// Return (if it exist) the VCalibParam for a given manu
8741815f 406
407 AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
408 (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
409
410 if (!param && external && fChannelValues)
411 {
7b6684fe 412 param = CreateDouble(*external,detElemId,manuId);
8741815f 413 fChannelValues->Add(param);
414 }
415
416 return param;
0145e89a 417}
418
0145e89a 419//_____________________________________________________________________________
420void
421AliMUONTrackerData::Clear(Option_t*)
422{
423 /// Clear all the values
424 if ( fChannelValues ) fChannelValues->Clear();
425 if ( fManuValues ) fManuValues->Clear();
426 if ( fBusPatchValues) fBusPatchValues->Clear();
427 if ( fPCBValues ) fPCBValues->Clear();
428 if ( fDEValues) fDEValues->Clear();
8741815f 429 if ( fChamberValues ) fChamberValues->Clear();
430 if ( fChannelHistos ) fChannelHistos->Clear();
0145e89a 431 fNevents = 0;
432 NumberOfEventsChanged();
433}
434
435//_____________________________________________________________________________
436Double_t
437AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId,
438 Int_t manuChannel) const
439{
440 /// Return the number of times a given channel had data
0145e89a 441
8741815f 442 return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
0145e89a 443}
444
445//_____________________________________________________________________________
446AliMUONVCalibParam*
7b6684fe 447AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param,
448 Int_t detElemId, Int_t manuId) const
0145e89a 449{
450 /// Create a double version of VCalibParam, for internal use
8741815f 451
452 AliCodeTimerAuto("");
453
454 AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
455 param.Size(),
7b6684fe 456 detElemId,
457 manuId,
8741815f 458 0.0);
0145e89a 459
7b6684fe 460 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
461
0145e89a 462 for ( Int_t i = 0; i < c->Size(); ++i )
463 {
7b6684fe 464 Double_t value(0.0);
465
466 if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
467
468 c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
0145e89a 469 }
470
471 return c;
472}
473
474//_____________________________________________________________________________
475Double_t
476AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
477{
478 /// Return the value for a given detection element for a given dimension
479 AliMUONVCalibParam* param = DetectionElementParam(detElemId);
480 return param ? Value(*param,0,dim) : 0.0;
481
482}
483
484//_____________________________________________________________________________
485AliMUONVCalibParam*
8741815f 486AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
0145e89a 487{
488 /// Return (if it exist) the VCalibParam for a given detection element
8741815f 489
490 AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
491 (fDEValues->FindObject(detElemId)) : 0x0 ;
492
493 if (!de && create && fDEValues)
494 {
495 de = CreateDetectionElementParam(detElemId);
496 fDEValues->Add(de);
497 }
498
499 return de;
500
501}
502
503//_____________________________________________________________________________
504AliMUONVCalibParam*
505AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
506{
507 /// Create storage for one detection element
508
509 AliCodeTimerAuto("");
510
511 AliMUONVCalibParam* de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
512
513 AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
514 Int_t nchannels(0);
515
516 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
517 {
518 Int_t busPatchId = det->GetBusPatchId(i);
519 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
520 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
521 {
522 Int_t manuId = bp->GetManuId(j);
523 nchannels += det->NofChannelsInManu(manuId);
524 }
525 }
526
527 de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
528
529 return de;
0145e89a 530}
531
532//_____________________________________________________________________________
533TString
534AliMUONTrackerData::DimensionName(Int_t dim) const
535{
536 /// Get the name of a given dimension
537 TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
538 if ( value )
539 {
540 return value->String();
541 }
542 else
543 {
544 return TString("Invalid");
545 }
546}
547
548//_____________________________________________________________________________
49419555 549Int_t
550AliMUONTrackerData::External2Internal(Int_t index) const
551{
552 /// From external to internal dimension
553 return IsSingleEvent() ? index : index*2;
554}
555
556//_____________________________________________________________________________
8741815f 557TString
558AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
0145e89a 559{
8741815f 560 /// Get the name of a given external dimension
561
562 TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
563 if ( value )
564 {
565 return value->String();
566 }
567 else
568 {
569 return TString("Invalid");
570 }
0145e89a 571}
572
573//_____________________________________________________________________________
8741815f 574void
575AliMUONTrackerData::FillChannel(Int_t detElemId, Int_t manuId, Int_t manuChannel,
576 Int_t dim, Double_t value)
0145e89a 577{
8741815f 578 /// Fill histogram of a given channel
579
10eb3d17 580 AliMUONSparseHisto* h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
8741815f 581
582 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
0145e89a 583}
584
585//_____________________________________________________________________________
10eb3d17 586AliMUONSparseHisto*
587AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
588 Int_t manuChannel, Int_t dim) const
8741815f 589{
10eb3d17 590 /// Get histogram of a given channel
8741815f 591
10eb3d17 592 if (!fChannelHistos) return 0x0;
8741815f 593
10eb3d17 594 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fChannelHistos->FindObject(detElemId,manuId));
595 if (!m) return 0x0;
8741815f 596
10eb3d17 597 UInt_t uid = ( manuChannel << 16 ) | dim;
8741815f 598
10eb3d17 599 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
8741815f 600
601 return h;
602}
0145e89a 603
8741815f 604//_____________________________________________________________________________
605AliMUONSparseHisto*
10eb3d17 606AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
607 Int_t manuChannel, Int_t dim)
8741815f 608{
10eb3d17 609 /// Get histogram of a given channel. Create it if necessary
8741815f 610
611 if (!fChannelHistos) fChannelHistos = new AliMUON2DMap(kTRUE);
612
10eb3d17 613 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fChannelHistos->FindObject(detElemId,manuId));
614 if (!m)
8741815f 615 {
10eb3d17 616 m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
617 m->SetUniqueID( ( manuId << 16 ) | detElemId );
618 fChannelHistos->Add(m);
8741815f 619 }
620
10eb3d17 621 UInt_t uid = ( manuChannel << 16 ) | dim;
8741815f 622
10eb3d17 623 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
8741815f 624 if (!h)
625 {
10eb3d17 626 h = new AliMUONSparseHisto(fXmin,fXmax);
627
628 h->SetUniqueID(uid);
629
630 m->Add(h);
8741815f 631 }
0145e89a 632
8741815f 633 return h;
634}
0145e89a 635
8741815f 636//_____________________________________________________________________________
637Int_t
638AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
639 AliMUONVCalibParam*& chamber,
640 AliMUONVCalibParam*& de,
641 AliMUONVCalibParam*& busPatch,
642 AliMUONVCalibParam*& pcb,
643 AliMUONVCalibParam*& manu,
644 AliMUONVCalibParam*& channel,
645 AliMpDetElement*& mpde)
646{
647 /// Get containers at all levels
648
649 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
650
7b6684fe 651 Int_t detElemId;
652 Int_t manuId;
8741815f 653
7b6684fe 654 if ( external->ID1() <= 0 )
655 {
656 // we get a manu serial number
657 Int_t serial = external->ID0();
658 AliMpIntPair pair = ddlStore->GetDetElemIdManu(serial);
659 detElemId = pair.GetFirst();
660 manuId = pair.GetSecond();
661 if ( !detElemId )
662 {
663 AliError(Form("DE %d manuId %d from serial %d is not correct !",
664 detElemId,manuId,serial));
665 return -1;
666 }
667 }
668 else
669 {
670 // we get a (de,manu) pair
671 detElemId = external->ID0();
672 manuId = external->ID1();
673 }
674
8741815f 675 mpde = ddlStore->GetDetElement(detElemId);
7b6684fe 676
677 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
678
8741815f 679 Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
680
681 Int_t pcbIndex = -1;
682
683 AliMp::StationType stationType = mpde->GetStationType();
684
685 if ( stationType == AliMp::kStation345 )
686 {
687 AliMpHVNamer namer;
688 pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
689 }
690
691 channel = ChannelParam(detElemId,manuId,external);
692
693 manu = ManuParam(detElemId,manuId,kTRUE);
694
695 busPatch = BusPatchParam(busPatchId,kTRUE);
696
697 de = DetectionElementParam(detElemId,kTRUE);
698
699 chamber = ChamberParam(chamberId,kTRUE);
700
701 pcb = 0x0;
702
703 if ( pcbIndex >= 0 )
704 {
705 pcb = PCBParam(detElemId,pcbIndex,kTRUE);
0145e89a 706 }
8741815f 707
708 return manuId;
709}
0145e89a 710
8741815f 711//_____________________________________________________________________________
712Bool_t
713AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
714{
715 /// Whether we have data for a given buspatch
716 return ( BusPatchParam(busPatchId) != 0 );
717}
718
719//_____________________________________________________________________________
720Bool_t
721AliMUONTrackerData::HasChamber(Int_t chamberId) const
722{
723 /// Whether we have data for a given chamber
724 return ( ChamberParam(chamberId) != 0 );
725}
726
727//_____________________________________________________________________________
728Bool_t
729AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
730{
731 /// Whether we have data for a given detection element
732 return ( DetectionElementParam(detElemId) != 0 );
733}
734
735//_____________________________________________________________________________
736Bool_t
737AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
738{
739 /// Whether we have data for a given manu
740 return ( ManuParam(detElemId,manuId) != 0 );
741}
742
743//_____________________________________________________________________________
744Bool_t
745AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
746{
747 /// Whether we have data for a given pcb
748 return ( PCBParam(detElemId,pcbIndex) != 0 );
0145e89a 749}
750
751//_____________________________________________________________________________
752Double_t
753AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
754{
9016a84e 755 /// Return the value for a given manu and a given dimension
756
0145e89a 757 AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
758 return param ? Value(*param,0,dim) : 0.0;
759}
760
761//_____________________________________________________________________________
762AliMUONVCalibParam*
8741815f 763AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
0145e89a 764{
9016a84e 765 /// Get the VCalibParam for a given manu
8741815f 766
767 AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
768 (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
769
770 if (!manu && create && fManuValues)
771 {
772 manu = CreateManuParam(detElemId,manuId);
773 fManuValues->Add(manu);
774 }
775
776 return manu;
777}
778
779//_____________________________________________________________________________
780AliMUONVCalibParam*
781AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
782{
783 /// Create storage for one manu
784
785 AliCodeTimerAuto("");
786
787 AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
788
789 // set the number of channels in that manu
790
791 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
792
793 manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
794
795 return manu;
0145e89a 796}
797
798//_____________________________________________________________________________
7b6684fe 799Long64_t
4a3224ff 800AliMUONTrackerData::Merge(TCollection*)
7b6684fe 801{
802 /// Merge all tracker data objects from li into a single one.
803
804 AliError("Not implemented yet");
805
806 return 0;
807}
808
809//_____________________________________________________________________________
0145e89a 810Int_t
811AliMUONTrackerData::NumberOfDimensions() const
812{
813 /// Number of dimensions we're dealing with
814
815 return fDimension + fgkVirtualExtraDimension;
816}
817
818//_____________________________________________________________________________
819Double_t
820AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
821{
822 /// Return the value of a given pcb for a given dimension
823
824 AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
825
826 return param ? Value(*param,pcbIndex,dim) : 0.0;
827}
828
829//_____________________________________________________________________________
830AliMUONVCalibParam*
8741815f 831AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
0145e89a 832{
833 /// Return (if it exist) the VCalibParam for a given pcb
8741815f 834
835 AliMUONVCalibParam* pcb = fPCBValues ? static_cast<AliMUONVCalibParam*>
836 (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
837
838 if (create && fPCBValues && !pcb)
839 {
840 pcb = CreatePCBParam(detElemId,pcbIndex);
841 fPCBValues->Add(pcb);
842 }
843
844 return pcb;
845}
846
847//_____________________________________________________________________________
848AliMUONVCalibParam*
849AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
850{
851 /// Create storage for one PCB (station345 only)
852
853 AliCodeTimerAuto("");
854
855 AliMpHVNamer namer;
856
857 AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
858 namer.NumberOfPCBs(detElemId),
859 detElemId,
860 pcbIndex,
861 0.0);
862 return pcb;
0145e89a 863}
864
865//_____________________________________________________________________________
866void
867AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
868{
869 /// Printout
870
871 TNamed::Print(opt);
872
49419555 873 if ( !fIsSingleEvent )
0145e89a 874 {
875 cout << " Nevents=" << fNevents << endl;
876 }
8741815f 877
878 for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i )
879 {
880 TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
881 cout << Form("External Dimension %2d Name %s %s",i,
882 ( name ? name->String().Data() : "null"),
883 ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
884 }
0145e89a 885
886 for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i )
887 {
888 TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
8741815f 889 cout << Form("Internal Dimension %2d Name %s",i,
0145e89a 890 ( name ? name->String().Data() : "null")) << endl;
891 }
8741815f 892
0145e89a 893 TString sopt(opt);
894 sopt.ToUpper();
895
896 if ( sopt.Contains("CHANNEL") && fChannelValues )
897 {
898 fChannelValues->Print(wildcard,opt);
899 }
900
901 if ( sopt.Contains("MANU") && fManuValues )
902 {
903 fManuValues->Print(wildcard,opt);
904 }
905
906 if ( sopt.Contains("BUSPATCH") && fBusPatchValues )
907 {
908 fBusPatchValues->Print(wildcard,opt);
909 }
910
911 if ( sopt.Contains("DE") && fDEValues )
912 {
913 fDEValues->Print(wildcard,opt);
914 }
915
916 if ( sopt.Contains("CHAMBER") && fChamberValues )
917 {
918 fChamberValues->Print(wildcard,opt);
919 }
920
921}
922
923//_____________________________________________________________________________
924void
925AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
926{
927 /// Set the name of a given dimension
928
929 if ( index >= fExternalDimension )
930 {
931 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
932 return;
933 }
934
935 Int_t ix = External2Internal(index);
936
49419555 937 if ( !IsSingleEvent() )
0145e89a 938 {
49419555 939 const char* prefix[] = { "mean", "sigma" };
940
941 for ( Int_t i = 0; i < 2; ++i )
942 {
943 Int_t j = ix+i;
0145e89a 944
49419555 945 SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
946 }
947 }
948 else
949 {
950 SetInternalDimensionName(index,name);
0145e89a 951 }
8741815f 952
953 SetExternalDimensionName(index,name);
954}
955
956//_____________________________________________________________________________
957void
10eb3d17 958AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
8741815f 959{
960 /// decide to make histos for a given dimension
961 if ( index >= ExternalDimension() )
962 {
963 AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
964 return;
965 }
966
967 fHistogramming[index] = value;
10eb3d17 968 fXmin = xmin;
969 fXmax = xmax;
0145e89a 970}
971
972//_____________________________________________________________________________
973void
974AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
975{
976 /// Set the name of a given internal dimension
977 if ( index >= fDimension )
978 {
979 AliError(Form("Index out of bounds : %d / %d",index,fDimension));
980 return;
981 }
982
983 TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
984
985 if ( ovalue )
986 {
987 fDimensionNames->Remove(ovalue);
988 delete ovalue;
989 }
990 fDimensionNames->AddAt(new TObjString(value),index);
991}
992
993//_____________________________________________________________________________
8741815f 994void
995AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
996{
997 /// Set the name of a given external dimension
998 if ( index >= fExternalDimension )
999 {
1000 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
1001 return;
1002 }
1003
1004 TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
1005
1006 if ( ovalue )
1007 {
1008 fExternalDimensionNames->Remove(ovalue);
1009 delete ovalue;
1010 }
1011 fExternalDimensionNames->AddAt(new TObjString(value),index);
1012}
1013
1014//_____________________________________________________________________________
0145e89a 1015Double_t
1016AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i, Int_t dim) const
1017{
1018 /// Compute the value for a given dim, using the internal information we have
1019 /// Basically we're converting sum of weights and sum of squares of weights
1020 /// into means and sigmas, and number of events into occupancy number.
1021
1022 Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
1023
1024 if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
1025
1026 Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
1027
1028 if ( dim >= fDimension )
1029 {
1030 return occ;
1031 }
1032
1033 if ( dim == IndexOfOccupancyDimension() ) return occ/n/NumberOfEvents();
1034
1035 Double_t value = param.ValueAsDouble(i,dim);
1036
1037 if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
1038
49419555 1039 if ( TMath::Even(dim) || IsSingleEvent() )
0145e89a 1040 {
1041 return value/occ;
1042 }
1043 else
1044 {
bf0d3528 1045 Double_t nn = occ;
0145e89a 1046
bf0d3528 1047 if ( nn > 1.0 )
49419555 1048 {
bf0d3528 1049 Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
b0565451 1050
bf0d3528 1051 return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
49419555 1052 }
1053 else
1054 {
1055 return 0.0;
1056 }
0145e89a 1057 }
1058
1059 AliError("Why am I here ?");
1060 return 0.0;
1061}
1062