1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 #include "AliMUONTrackerData.h"
20 #include "AliMUONCalibParamND.h"
21 #include "AliMUONVStore.h"
22 #include "AliMpBusPatch.h"
23 #include "AliMpDDLStore.h"
24 #include "AliMpDEManager.h"
25 #include "AliMpDEIterator.h"
26 #include "AliMpDetElement.h"
27 #include "AliMpHVNamer.h"
28 #include "AliCodeTimer.h"
30 #include <Riostream.h>
32 #include <TObjArray.h>
33 #include <TObjString.h>
38 /// \class AliMUONTrackerData
40 /// Implementation of AliMUONVTrackerData class
42 /// \author Laurent Aphecetche, Subatech
45 ClassImp(AliMUONTrackerData)
48 const Int_t AliMUONTrackerData::fgkExtraDimension = 2;
49 const Int_t AliMUONTrackerData::fgkVirtualExtraDimension = 1;
51 //_____________________________________________________________________________
52 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
55 : AliMUONVTrackerData(name,title),
62 fDimension(dimension*2+fgkExtraDimension),
64 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
65 fExternalDimension(dimension),
69 fDimensionNames->SetOwner(kTRUE);
70 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
71 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
72 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
76 //_____________________________________________________________________________
77 AliMUONTrackerData::~AliMUONTrackerData()
80 delete fChannelValues;
82 delete fBusPatchValues;
84 delete fChamberValues;
86 delete fDimensionNames;
89 //_____________________________________________________________________________
91 AliMUONTrackerData::Add(const AliMUONVStore& store)
93 /// We first convert the external store to a temporary internal store
94 /// with more dimension (2*store's dimension)
96 AliCodeTimerAuto(GetName())
98 Int_t ndim(NumberOfDimensions()-fgkExtraDimension-fgkVirtualExtraDimension);
100 AliMUONVStore* istore = store.Create();
102 TIter next(store.CreateIterator());
103 AliMUONVCalibParam* external;
105 AliCodeTimerStart("from external to internal store");
107 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
109 Int_t detElemId = external->ID0();
110 Int_t manuId = external->ID1();
112 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
114 AliMUONVCalibParam* internal = static_cast<AliMUONVCalibParam*>
115 (istore->FindObject(detElemId,manuId));
119 internal = new AliMUONCalibParamND(ndim,external->Size(),
122 istore->Add(internal);
125 for ( Int_t i = 0; i < external->Size(); ++i )
127 Bool_t connectPad = de->IsConnectedChannel(manuId,i);
129 if (!connectPad) continue;
131 for ( Int_t j = 0; j < external->Dimension(); ++j )
133 Int_t ix = External2Internal(j);
135 Double_t vext = external->IsDoublePrecision() ?
136 external->ValueAsDouble(i,j) :
137 external->ValueAsFloat(i,j);
139 Double_t sumw = internal->ValueAsDouble(i,ix) + vext;
140 Double_t sumw2 = internal->ValueAsDouble(i,ix+1) + vext*vext;
142 internal->SetValueAsFloat(i,ix,sumw);
143 internal->SetValueAsFloat(i,ix+1,sumw2);
148 AliCodeTimerStop("from external to internal store");
150 /// and we add this internal store to what we already have
152 InternalAdd(*istore);
154 /// delete the temporary internal store.
155 AliCodeTimerStart("delete");
157 AliCodeTimerStop("delete");
162 //_____________________________________________________________________________
164 AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
166 /// Return the value of a given buspatch for a given dimension
167 /// or 0 if not existing
168 AliMUONVCalibParam* param = BusPatchParam(busPatchId);
169 return param ? Value(*param,0,dim) : 0.0;
172 //_____________________________________________________________________________
174 AliMUONTrackerData::BusPatchParam(Int_t busPatchId) const
176 /// Return (if it exist), the VCalibParam for a given busPatch
177 return fBusPatchValues ? static_cast<AliMUONVCalibParam*>
178 (fBusPatchValues->FindObject(busPatchId)) : 0x0;
181 //_____________________________________________________________________________
183 AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
185 /// Return the value fo a given chamber for a given dimension,
186 /// or zero if not existing
187 AliMUONVCalibParam* param = ChamberParam(chamberId);
188 return param ? Value(*param,0,dim) : 0.0;
191 //_____________________________________________________________________________
193 AliMUONTrackerData::ChamberParam(Int_t chamberId) const
195 /// Return (if it exist) the VCalibParam for a given chamber
196 return fChamberValues ? static_cast<AliMUONVCalibParam*>
197 (fChamberValues->FindObject(chamberId)) : 0x0;
200 //_____________________________________________________________________________
202 AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId,
203 Int_t manuChannel, Int_t dim) const
205 /// Return the value for a given channel for a given dimension
207 AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
209 return param ? Value(*param,manuChannel,dim) : 0.0;
212 //_____________________________________________________________________________
214 AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId) const
216 /// Return (if it exist) the VCalibParam for a given manu
217 return fChannelValues ? static_cast<AliMUONVCalibParam*>
218 (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
222 //_____________________________________________________________________________
224 AliMUONTrackerData::Clear(Option_t*)
226 /// Clear all the values
227 if ( fChannelValues ) fChannelValues->Clear();
228 if ( fManuValues ) fManuValues->Clear();
229 if ( fBusPatchValues) fBusPatchValues->Clear();
230 if ( fPCBValues ) fPCBValues->Clear();
231 if ( fDEValues) fDEValues->Clear();
232 if ( fChamberValues) fChamberValues->Clear();
234 NumberOfEventsChanged();
237 //_____________________________________________________________________________
239 AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId,
240 Int_t manuChannel) const
242 /// Return the number of times a given channel had data
243 AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>
244 (fChannelValues->FindObject(detElemId,manuId));
246 if ( !param ) return 0.0;
248 return param->ValueAsDouble(manuChannel,IndexOfOccupancyDimension());
251 //_____________________________________________________________________________
253 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param) const
255 /// Create a double version of VCalibParam, for internal use
256 AliMUONVCalibParam* c = new AliMUONCalibParamND(param.Dimension()+fgkExtraDimension,
262 for ( Int_t i = 0; i < c->Size(); ++i )
264 c->SetValueAsDouble(i,IndexOfNumberDimension(),1.0);
270 //_____________________________________________________________________________
272 AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
274 /// Return the value for a given detection element for a given dimension
275 AliMUONVCalibParam* param = DetectionElementParam(detElemId);
276 return param ? Value(*param,0,dim) : 0.0;
280 //_____________________________________________________________________________
282 AliMUONTrackerData::DetectionElementParam(Int_t detElemId) const
284 /// Return (if it exist) the VCalibParam for a given detection element
285 return fDEValues ? static_cast<AliMUONVCalibParam*>
286 (fDEValues->FindObject(detElemId)) : 0x0 ;
289 //_____________________________________________________________________________
291 AliMUONTrackerData::DimensionName(Int_t dim) const
293 /// Get the name of a given dimension
294 TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
297 return value->String();
301 return TString("Invalid");
305 //_____________________________________________________________________________
307 AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
309 /// Whether we have data for a given buspatch
310 return ( BusPatchParam(busPatchId) != 0 );
313 //_____________________________________________________________________________
315 AliMUONTrackerData::HasChamber(Int_t chamberId) const
317 /// Whether we have data for a given chamber
318 return ( ChamberParam(chamberId) != 0 );
321 //_____________________________________________________________________________
323 AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
325 /// Whether we have data for a given detection element
326 return ( DetectionElementParam(detElemId) != 0 );
329 //_____________________________________________________________________________
331 AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
333 /// Whether we have data for a given manu
334 return ( ManuParam(detElemId,manuId) != 0 );
337 //_____________________________________________________________________________
339 AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
341 /// Whether we have data for a given pcb
342 return ( PCBParam(detElemId,pcbIndex) != 0 );
345 //_____________________________________________________________________________
347 AliMUONTrackerData::InternalAdd(const AliMUONVStore& store)
349 /// Add the given store to our internal store
350 /// Store must be of dimension = fDimension-1
352 AliCodeTimerAuto(GetName());
354 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
357 NumberOfEventsChanged();
361 fChannelValues = store.Create();
362 fManuValues = store.Create();
363 fBusPatchValues = store.Create();
364 fDEValues = store.Create();
365 fChamberValues = store.Create();
366 fPCBValues = store.Create();
369 TIter next(store.CreateIterator());
370 AliMUONVCalibParam* external;
374 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
376 if ( external->Dimension() != fDimension-fgkExtraDimension )
378 AliError(Form("Incompatible dimensions %d vs %d",
379 external->Dimension(),fDimension-fgkExtraDimension));
383 Int_t detElemId = external->ID0();
385 AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
387 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
389 Int_t manuId = external->ID1();
391 AliMpDetElement* mpde = ddlStore->GetDetElement(detElemId);
393 Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
397 if ( stationType == AliMp::kStation345 )
399 pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
402 AliMUONVCalibParam* channel = ChannelParam(detElemId,manuId);
405 channel = CreateDouble(*external);
406 fChannelValues->Add(channel);
409 AliMUONVCalibParam* manu = ManuParam(detElemId,manuId);
412 manu = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
418 // set the number of channels in that manu
420 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
422 manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
424 fManuValues->Add(manu);
427 AliMUONVCalibParam* busPatch = BusPatchParam(busPatchId);
430 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
434 AliError(Form("Got an invalid buspatchId = %d",busPatchId));
438 busPatch = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
444 // set the number of channels in that buspatch
448 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
450 for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
452 Int_t manuId = bp->GetManuId(i);
453 nchannels += de->NofChannelsInManu(manuId);
456 busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
458 fBusPatchValues->Add(busPatch);
461 AliMUONVCalibParam* de = DetectionElementParam(detElemId);
464 de = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
470 AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
473 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
475 Int_t busPatchId = det->GetBusPatchId(i);
476 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
477 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
479 Int_t manuId = bp->GetManuId(j);
480 nchannels += det->NofChannelsInManu(manuId);
484 de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
489 AliMUONVCalibParam* chamber = ChamberParam(chamberId);
492 chamber = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
498 // set the number of channels in that chamber
506 while ( !it.IsDone() )
508 AliMpDetElement* det = it.CurrentDE();
510 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
512 Int_t busPatchId = det->GetBusPatchId(i);
513 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
514 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
516 Int_t manuId = bp->GetManuId(j);
517 nchannels += det->NofChannelsInManu(manuId);
524 chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
526 fChamberValues->Add(chamber);
529 AliMUONVCalibParam* pcb = 0x0;
533 pcb = PCBParam(detElemId,pcbIndex);
536 pcb = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
537 namer.NumberOfPCBs(detElemId),
541 fPCBValues->Add(pcb);
545 for ( Int_t i = 0; i < external->Size(); ++i )
547 Bool_t existingChannel = mpde->IsConnectedChannel(manuId,i);
549 if ( existingChannel )
551 Bool_t validChannel(kFALSE);
553 for ( Int_t j = 0; j < external->Dimension(); ++j )
555 if ( external->ValueAsFloat(i,j) >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
557 validChannel = kTRUE;
559 Double_t vext = external->IsDoublePrecision() ?
560 external->ValueAsDouble(i,j) :
561 external->ValueAsFloat(i,j);
563 Double_t value = channel->ValueAsDouble(i,j) + vext;
565 channel->SetValueAsDouble(i,j,value);
567 manu->SetValueAsDouble(0,j,manu->ValueAsDouble(0,j)+vext);
569 busPatch->SetValueAsDouble(0,j,busPatch->ValueAsDouble(0,j)+vext);
571 de->SetValueAsDouble(0,j,de->ValueAsDouble(0,j)+vext);
573 chamber->SetValueAsDouble(0,j,chamber->ValueAsDouble(0,j)+vext);
577 pcb->SetValueAsDouble(pcbIndex,j,pcb->ValueAsDouble(pcbIndex,j)+vext);
583 channel->SetValueAsDouble(i,IndexOfOccupancyDimension(),
584 channel->ValueAsDouble(i,IndexOfOccupancyDimension())+1.0);
585 manu->SetValueAsDouble(0,IndexOfOccupancyDimension(),
586 manu->ValueAsDouble(0,IndexOfOccupancyDimension())+1.0);
587 busPatch->SetValueAsDouble(0,IndexOfOccupancyDimension(),
588 busPatch->ValueAsDouble(0,IndexOfOccupancyDimension())+1.0);
589 de->SetValueAsDouble(0,IndexOfOccupancyDimension(),
590 de->ValueAsDouble(0,IndexOfOccupancyDimension())+1.0);
591 chamber->SetValueAsDouble(0,IndexOfOccupancyDimension(),
592 chamber->ValueAsDouble(0,IndexOfOccupancyDimension())+1.0);
595 pcb->SetValueAsDouble(pcbIndex,IndexOfOccupancyDimension(),
596 pcb->ValueAsDouble(pcbIndex,IndexOfOccupancyDimension())+1.0);
606 //_____________________________________________________________________________
608 AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
610 /// Return the value for a given manu and a given dimension
612 AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
613 return param ? Value(*param,0,dim) : 0.0;
616 //_____________________________________________________________________________
618 AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId) const
620 /// Get the VCalibParam for a given manu
621 return fManuValues ? static_cast<AliMUONVCalibParam*>
622 (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
625 //_____________________________________________________________________________
627 AliMUONTrackerData::NumberOfDimensions() const
629 /// Number of dimensions we're dealing with
631 return fDimension + fgkVirtualExtraDimension;
634 //_____________________________________________________________________________
636 AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
638 /// Return the value of a given pcb for a given dimension
640 AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
642 return param ? Value(*param,pcbIndex,dim) : 0.0;
645 //_____________________________________________________________________________
647 AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex) const
649 /// Return (if it exist) the VCalibParam for a given pcb
650 return fPCBValues ? static_cast<AliMUONVCalibParam*>
651 (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
654 //_____________________________________________________________________________
656 AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
664 cout << " Nevents=" << fNevents << endl;
667 for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i )
669 TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
670 cout << Form("Dimension %2d Name %s",i,
671 ( name ? name->String().Data() : "null")) << endl;
674 cout << Form("External Dimensions = %d",fExternalDimension) << endl;
679 if ( sopt.Contains("CHANNEL") && fChannelValues )
681 fChannelValues->Print(wildcard,opt);
684 if ( sopt.Contains("MANU") && fManuValues )
686 fManuValues->Print(wildcard,opt);
689 if ( sopt.Contains("BUSPATCH") && fBusPatchValues )
691 fBusPatchValues->Print(wildcard,opt);
694 if ( sopt.Contains("DE") && fDEValues )
696 fDEValues->Print(wildcard,opt);
699 if ( sopt.Contains("CHAMBER") && fChamberValues )
701 fChamberValues->Print(wildcard,opt);
706 //_____________________________________________________________________________
708 AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
710 /// Set the name of a given dimension
712 if ( index >= fExternalDimension )
714 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
718 Int_t ix = External2Internal(index);
720 const char* prefix[] = { "mean", "sigma" };
722 for ( Int_t i = 0; i < 2; ++i )
726 SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
730 //_____________________________________________________________________________
732 AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
734 /// Set the name of a given internal dimension
735 if ( index >= fDimension )
737 AliError(Form("Index out of bounds : %d / %d",index,fDimension));
741 TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
745 fDimensionNames->Remove(ovalue);
748 fDimensionNames->AddAt(new TObjString(value),index);
751 //_____________________________________________________________________________
753 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i, Int_t dim) const
755 /// Compute the value for a given dim, using the internal information we have
756 /// Basically we're converting sum of weights and sum of squares of weights
757 /// into means and sigmas, and number of events into occupancy number.
759 Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
761 if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
763 Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
765 if ( dim >= fDimension )
770 if ( dim == IndexOfOccupancyDimension() ) return occ/n/NumberOfEvents();
772 Double_t value = param.ValueAsDouble(i,dim);
774 if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
776 if ( TMath::Even(dim) )
782 Double_t sumw = param.ValueAsDouble(i,dim-1);
783 Double_t mean = sumw/n;
785 return TMath::Sqrt(TMath::Abs(value/occ - mean*mean));
788 AliError("Why am I here ?");