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 "AliCodeTimer.h"
23 #include "AliMUON1DArray.h"
24 #include "AliMUON1DMap.h"
25 #include "AliMUON2DMap.h"
26 #include "AliMUONCalibParamND.h"
27 #include "AliMUONSparseHisto.h"
28 #include "AliMUONVStore.h"
29 #include "AliMpBusPatch.h"
30 #include "AliMpConstants.h"
32 #include "AliMpDDLStore.h"
33 #include "AliMpManuStore.h"
34 #include "AliMpDEIterator.h"
35 #include "AliMpDEManager.h"
36 #include "AliMpDetElement.h"
37 #include "AliMpHVNamer.h"
38 #include "AliMpManuIterator.h"
39 #include <Riostream.h>
42 #include <TObjArray.h>
43 #include <TObjString.h>
48 /// \class AliMUONTrackerData
50 /// Implementation of AliMUONVTrackerData class
52 /// \author Laurent Aphecetche, Subatech
55 ClassImp(AliMUONTrackerData)
58 const Int_t AliMUONTrackerData::fgkExtraDimension = 2;
59 const Int_t AliMUONTrackerData::fgkVirtualExtraDimension = 1;
61 //_____________________________________________________________________________
62 AliMUONTrackerData::AliMUONTrackerData(const char* name, const char* title,
65 : AliMUONVTrackerData(name,title),
66 fIsSingleEvent(issingleevent),
73 fDimension(External2Internal(dimension)+fgkExtraDimension),
75 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
76 fExternalDimensionNames(new TObjArray(dimension)),
77 fExternalDimension(dimension),
78 fHistogramming(new Int_t[fExternalDimension]),
82 fIsChannelLevelEnabled(kTRUE),
83 fIsManuLevelEnabled(kTRUE),
88 memset(fHistogramming,0,sizeof(Int_t)); // histogramming is off by default. Use MakeHistogramForDimension to turn it on.
89 fExternalDimensionNames->SetOwner(kTRUE);
90 fDimensionNames->SetOwner(kTRUE);
91 fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
92 fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
93 fDimensionNames->AddAt(new TObjString("n"),NumberOfDimensions()-fgkVirtualExtraDimension);
97 //_____________________________________________________________________________
98 AliMUONTrackerData::~AliMUONTrackerData()
101 delete fChannelValues;
103 delete fBusPatchValues;
105 delete fChamberValues;
107 delete fDimensionNames;
108 delete fExternalDimensionNames;
109 delete[] fHistogramming;
111 delete[] fNofEventsPerDDL;
114 //_____________________________________________________________________________
116 AliMUONTrackerData::Add(const AliMUONVStore& store, TArrayI* nevents)
118 /// Add the given external store to our internal store
119 return InternalAdd(store,nevents,kFALSE);
122 //_____________________________________________________________________________
124 AliMUONTrackerData::Add(const AliMUONTrackerData& data)
126 /// Add data to *this
127 // We do this by looping on all VCalibParam stored in the various containers,
128 // and simply adding the values there.
129 // Same thing for the number of events per DDL.
130 // Same thing for sparsehistograms, if we have some.
132 // First cross check we have compatible objects.
134 if ( fIsChannelLevelEnabled != data.fIsChannelLevelEnabled )
136 AliError("Incompatible IsChannelLevelEnabled status");
140 if ( fIsManuLevelEnabled != data.fIsManuLevelEnabled )
142 AliError("Incompatible IsManuLevelEnabled status");
146 if ( fIsSingleEvent != data.fIsSingleEvent )
148 AliError("Incompatible IsSingleEvent status");
152 if ( fDimension != data.fDimension || fExternalDimension != data.fExternalDimension )
154 AliError("Incompatible dimensions");
158 if ( fNofDDLs != data.fNofDDLs )
160 AliError("Incompatible number of Ddls");
164 if ( ( !fHistogramming && data.fHistogramming ) || ( fHistogramming && !data.fHistogramming )
165 || fXmin != data.fXmin || fXmax != data.fXmax )
167 AliError(Form("Incompatible histogramming (%x vs %x) (xmax = %e vs %e ; xmin = %e vs %e)",
168 fHistogramming,data.fHistogramming,fXmax,data.fXmax,fXmin,data.fXmin));
172 if ( fHistogramming )
174 for ( Int_t i = 0; i < fExternalDimension; ++i )
176 if ( fHistogramming[i] != data.fHistogramming[i] )
178 AliError(Form("Incompatible histogramming for external dimension %d",i));
184 // OK. Seems we have compatible objects, so we can proceed with the actual
187 if ( data.fChannelValues )
189 Add2D(*(data.fChannelValues),*fChannelValues);
192 if ( data.fManuValues )
194 Add2D(*(data.fManuValues),*fManuValues);
197 if ( data.fPCBValues )
199 Add2D(*(data.fPCBValues),*fPCBValues);
202 if ( data.fBusPatchValues )
204 Add1D(*(data.fBusPatchValues),*fBusPatchValues);
207 if ( data.fDEValues )
209 Add1D(*(data.fDEValues),*fDEValues);
212 if ( data.fChamberValues )
214 Add1D(*(data.fChamberValues),*fChamberValues);
217 for ( Int_t i = 0; i < fNofDDLs; ++i )
219 fNofEventsPerDDL[i] += data.fNofEventsPerDDL[i];
224 TIter nexthisto(data.fHistos->CreateIterator());
225 AliMUONVStore* store;
226 while ( ( store = static_cast<AliMUONVStore*>(nexthisto()) ) )
228 TIter ns(store->CreateIterator());
229 AliMUONSparseHisto* h;
230 while ( ( h = static_cast<AliMUONSparseHisto*>(ns()) ) )
232 AliMUONVStore* thisStore = static_cast<AliMUONVStore*>(fHistos->FindObject(store->GetUniqueID()));
236 thisStore = store->Create();
237 thisStore->SetUniqueID(store->GetUniqueID());
238 fHistos->Add(thisStore);
241 AliMUONSparseHisto* mine = static_cast<AliMUONSparseHisto*>(thisStore->FindObject(h->GetUniqueID()));
258 //_____________________________________________________________________________
260 AliMUONTrackerData::Add2D(const AliMUONVStore& src, AliMUONVStore& dest) const
262 /// Add one 2d store to another
264 TIter next(src.CreateIterator());
265 AliMUONVCalibParam* p;
267 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
269 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->ID0(),p->ID1()));
273 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
277 AddCalibParams(*p,*a);
282 //_____________________________________________________________________________
284 AliMUONTrackerData::Add1D(const AliMUONVStore& src, AliMUONVStore& dest) const
286 /// Add one 1d store to another
288 TIter next(src.CreateIterator());
289 AliMUONVCalibParam* p;
291 while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
293 AliMUONVCalibParam* a = static_cast<AliMUONVCalibParam*>(dest.FindObject(p->GetUniqueID()));
297 dest.Add(static_cast<AliMUONVCalibParam*>(p->Clone()));
301 AddCalibParams(*p,*a);
306 //_____________________________________________________________________________
308 AliMUONTrackerData::AddCalibParams(const AliMUONVCalibParam& src, AliMUONVCalibParam& dest) const
311 for ( Int_t i = 0; i < src.Size(); ++i )
313 for ( Int_t j = 0; j < src.Dimension(); ++j )
315 dest.SetValueAsFloat(i,j,src.ValueAsFloat(i,j));
320 //_____________________________________________________________________________
322 AliMUONTrackerData::Replace(const AliMUONVStore& store)
324 /// Replace our values by values from the given external store
325 Bool_t rv = InternalAdd(store,0x0,kTRUE);
326 AliMUONVTrackerData::Replace(store);
330 //_____________________________________________________________________________
332 AliMUONTrackerData::InternalAdd(const AliMUONVStore& store, TArrayI* nevents, Bool_t replace)
334 /// Add the given external store to our internal store
336 AliCodeTimerAuto(GetName());
340 if ( IsSingleEvent() && NumberOfEvents(-1) == 1 )
342 AliError(Form("%s is supposed to be single event only",GetName()));
349 fNofDDLs = AliDAQ::NumberOfDdls("MUONTRK");
350 fNofEventsPerDDL = new Int_t[fNofDDLs];
351 for ( Int_t i = 0; i < fNofDDLs; ++i )
353 fNofEventsPerDDL[i] = 0;
359 if (nevents->GetSize() != fNofDDLs )
361 AliError(Form("nof of ddl per event array size is incorrect : got %d, expecting %d",
362 nevents->GetSize(),fNofDDLs));
366 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
368 fNofEventsPerDDL[i] += nevents->At(i);
369 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
374 for ( Int_t i = 0 ; i < fNofDDLs; ++i )
376 ++fNofEventsPerDDL[i];
377 fNevents = TMath::Max(fNevents,fNofEventsPerDDL[i]);
383 Int_t numberOfBusPatches(0);
384 Int_t numberOfDEs(0);
386 // get number of bus patches and number of detection element
387 // to initialize fBusPatchValues and fDEValues below
389 TIter next(AliMpDDLStore::Instance()->CreateBusPatchIterator());
390 while ( next() ) ++numberOfBusPatches;
391 AliMpDEIterator deIt;
393 while (!deIt.IsDone())
399 if ( fIsChannelLevelEnabled )
401 fChannelValues = new AliMUON2DMap(kTRUE);
403 if ( fIsManuLevelEnabled )
405 fManuValues = new AliMUON2DMap(kTRUE);
407 fPCBValues = new AliMUON2DMap(kFALSE);
408 fBusPatchValues = new AliMUON1DMap(numberOfBusPatches);
409 fDEValues = new AliMUON1DMap(numberOfDEs);
410 fChamberValues = new AliMUON1DArray;
413 TIter next(store.CreateIterator());
414 AliMUONVCalibParam* external;
418 if ( IsSingleEvent() ) nk = 1;
420 while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
422 if ( external->Dimension() != ExternalDimension() )
424 AliError(Form("Incompatible dimensions %d vs %d",
425 external->Dimension(),ExternalDimension()));
430 AliMUONVCalibParam* chamber, *de, *busPatch, *pcb, *manu, *channel;
431 AliMpDetElement* mpde;
433 Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
435 if ( manuId < 0 ) continue;
437 Int_t detElemId = mpde->GetId();
439 Double_t value[] = { 0.0, 0.0 };
441 Int_t nch = mpde->NofChannelsInManu(manuId);
443 for ( Int_t i = 0; i < external->Size(); ++i )
445 Bool_t existingChannel = ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
446 : mpde->IsConnectedChannel(manuId,i));
447 // note we only use IsConnectedChannel method when really needed, as
448 // it costs (some) CPU time...
450 if ( existingChannel )
452 Bool_t validChannel(kFALSE);
454 for ( Int_t j = 0; j < external->Dimension(); ++j )
456 Double_t vext = external->IsDoublePrecision() ?
457 external->ValueAsDoubleFast(i,j) :
458 external->ValueAsFloatFast(i,j);
460 if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
462 validChannel = kTRUE;
464 Int_t ix = External2Internal(j);
467 value[1] = vext*vext;
469 if ( IsHistogrammed(j) )
471 FillHisto(detElemId,manuId,i,j,vext);
474 for ( Int_t k = 0; k < nk; ++k )
476 Double_t e = ( replace && channel ) ? channel->ValueAsDoubleFast(i,ix+k) : 0.0;
480 channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)-e+value[k]);
485 manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)-e+value[k]);
488 busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)-e+value[k]);
490 de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)-e+value[k]);
492 chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)-e+value[k]);
496 pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)-e+value[k]);
501 if ( validChannel && !replace )
505 channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
506 channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
511 manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
512 manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
515 busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
516 busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
517 de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
518 de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
519 chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
520 chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
523 pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
524 pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);
531 NumberOfEventsChanged();
536 //_____________________________________________________________________________
538 AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
540 /// Return the value of a given buspatch for a given dimension
541 /// or 0 if not existing
542 AliMUONVCalibParam* param = BusPatchParam(busPatchId);
543 return param ? Value(*param,0,dim,DdlIdFromBusPatchId(busPatchId)) : 0.0;
546 //_____________________________________________________________________________
548 AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
550 /// Return (if it exist), the VCalibParam for a given busPatch
552 AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
553 (fBusPatchValues->FindObject(busPatchId)) : 0x0;
555 if (!busPatch && create && fBusPatchValues)
557 busPatch = CreateBusPatchParam(busPatchId);
558 fBusPatchValues->Add(busPatch);
564 //_____________________________________________________________________________
566 AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
568 /// Create storage for one bus patch
570 AliCodeTimerAuto("");
572 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
576 AliError(Form("Got an invalid buspatchId = %d",busPatchId));
580 AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
582 // set the number of channels in that buspatch
586 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
588 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
590 for ( Int_t i = 0; i < bp->GetNofManus(); ++i )
592 Int_t manuId = bp->GetManuId(i);
593 nchannels += de->NofChannelsInManu(manuId);
596 busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
601 //_____________________________________________________________________________
603 AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
605 /// Return the value fo a given chamber for a given dimension,
606 /// or zero if not existing
608 // FIXME: is the Value() correct wrt to number of events in the case of
609 // chamber ? Or should we do something custom at the chamber level
610 // (as it spans several ddls) ?
612 AliMUONVCalibParam* param = ChamberParam(chamberId);
613 return param ? Value(*param,0,dim,DdlIdFromChamberId(chamberId)) : 0.0;
616 //_____________________________________________________________________________
618 AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
620 /// Return (if it exist) the VCalibParam for a given chamber
622 AliMUONVCalibParam* chamber = fChamberValues ? static_cast<AliMUONVCalibParam*>
623 (fChamberValues->FindObject(chamberId)) : 0x0;
625 if (!chamber && create && fChamberValues)
627 chamber = CreateChamberParam(chamberId);
628 fChamberValues->Add(chamber);
634 //_____________________________________________________________________________
636 AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
638 /// Create storage for one chamber
640 AliCodeTimerAuto("");
642 AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
644 // set the number of channels in that chamber
652 while ( !it.IsDone() )
654 AliMpDetElement* det = it.CurrentDE();
656 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
658 Int_t busPatchId = det->GetBusPatchId(i);
659 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
660 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
662 Int_t manuId = bp->GetManuId(j);
663 nchannels += det->NofChannelsInManu(manuId);
670 chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
675 //_____________________________________________________________________________
677 AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId,
678 Int_t manuChannel, Int_t dim) const
680 /// Return the value for a given channel for a given dimension
682 AliMUONVCalibParam* param = ChannelParam(detElemId,manuId);
684 return param ? Value(*param,manuChannel,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
687 //_____________________________________________________________________________
689 AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
690 AliMUONVCalibParam* external) const
692 /// Return (if it exist) the VCalibParam for a given manu
694 AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
695 (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
697 if (!param && external && fChannelValues)
699 param = CreateDouble(*external,detElemId,manuId);
700 fChannelValues->Add(param);
706 //_____________________________________________________________________________
708 AliMUONTrackerData::Clear(Option_t*)
710 /// Clear all the values
711 if ( fChannelValues ) fChannelValues->Clear();
712 if ( fManuValues ) fManuValues->Clear();
713 if ( fBusPatchValues) fBusPatchValues->Clear();
714 if ( fPCBValues ) fPCBValues->Clear();
715 if ( fDEValues) fDEValues->Clear();
716 if ( fChamberValues ) fChamberValues->Clear();
717 if ( fHistos ) fHistos->Clear();
718 for ( Int_t i = 0; i < fNofDDLs; ++i )
720 fNofEventsPerDDL[i] = 0;
722 NumberOfEventsChanged();
725 //_____________________________________________________________________________
727 AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId,
728 Int_t manuChannel) const
730 /// Return the number of times a given channel had data
732 return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
735 //_____________________________________________________________________________
737 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param,
738 Int_t detElemId, Int_t manuId) const
740 /// Create a double version of VCalibParam, for internal use
742 AliCodeTimerAuto("");
744 AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
750 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId,manuId);
752 for ( Int_t i = 0; i < c->Size(); ++i )
756 if ( de->IsConnectedChannel(manuId,i) ) value = 1.0;
758 c->SetValueAsDouble(i,IndexOfNumberDimension(),value);
764 //_____________________________________________________________________________
766 AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
768 /// Return the value for a given detection element for a given dimension
769 AliMUONVCalibParam* param = DetectionElementParam(detElemId);
770 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
774 //_____________________________________________________________________________
776 AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
778 /// Return (if it exist) the VCalibParam for a given detection element
780 AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
781 (fDEValues->FindObject(detElemId)) : 0x0 ;
783 if (!de && create && fDEValues)
785 de = CreateDetectionElementParam(detElemId);
793 //_____________________________________________________________________________
795 AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
797 /// Create storage for one detection element
799 AliCodeTimerAuto("");
801 AliMUONVCalibParam* de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
803 AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
806 for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i )
808 Int_t busPatchId = det->GetBusPatchId(i);
809 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
810 for ( Int_t j = 0; j < bp->GetNofManus(); ++j )
812 Int_t manuId = bp->GetManuId(j);
813 nchannels += det->NofChannelsInManu(manuId);
817 de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
822 //_____________________________________________________________________________
824 AliMUONTrackerData::DdlIdFromBusPatchId(Int_t buspatchid) const
826 /// Get the "local" ddlid (0..19) of a given buspatch
827 AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(buspatchid);
830 return bp->GetDdlId();
835 //_____________________________________________________________________________
837 AliMUONTrackerData::DdlIdFromDetElemId(Int_t detelemid) const
839 /// Get the "local" ddlid (0..19) of a given detection element
840 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detelemid);
843 return de->GetDdlId();
848 //_____________________________________________________________________________
850 AliMUONTrackerData::DdlIdFromChamberId(Int_t chamberid) const
852 /// Get the "local" ddlid (0..19) of a given chamber
853 /// This has no real meaning (as there are several ddls per chamber),
854 /// so we take the ddlid where we got the max number of events
864 Int_t detElemId = it.CurrentDEId();
865 Int_t ddlId = DdlIdFromDetElemId(detElemId);
866 if ( NumberOfEvents(ddlId) > n )
868 n = NumberOfEvents(ddlId);
877 //_____________________________________________________________________________
879 AliMUONTrackerData::DimensionName(Int_t dim) const
881 /// Get the name of a given dimension
882 TObjString* value = static_cast<TObjString*>(fDimensionNames->At(dim));
885 return value->String();
889 return TString("Invalid");
893 //_____________________________________________________________________________
895 AliMUONTrackerData::DisableChannelLevel()
897 /// Disable the storing of data at channel level
899 delete fChannelValues;
900 fChannelValues = 0x0;
901 fIsChannelLevelEnabled = kFALSE;
904 //_____________________________________________________________________________
906 AliMUONTrackerData::DisableManuLevel()
908 /// Disable the storing of data at manu level (and below)
910 DisableChannelLevel();
913 fIsManuLevelEnabled = kFALSE;
916 //_____________________________________________________________________________
918 AliMUONTrackerData::External2Internal(Int_t index) const
920 /// From external to internal dimension
921 return IsSingleEvent() ? index : index*2;
924 //_____________________________________________________________________________
926 AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
928 /// Get the name of a given external dimension
930 TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
933 return value->String();
937 return TString("Invalid");
941 //_____________________________________________________________________________
943 AliMUONTrackerData::FillHisto(Int_t detElemId, Int_t manuId, Int_t manuChannel,
944 Int_t dim, Double_t value)
946 /// Fill histogram of a given channel
948 AliMUONSparseHisto* h(0x0);
950 if ( fIsChannelLevelEnabled )
952 h = GetChannelSparseHisto(detElemId, manuId, manuChannel,dim);
954 else if ( fIsManuLevelEnabled )
956 h = GetManuSparseHisto(detElemId,manuId,dim);
959 AliDebug(1,Form("DE %04d MANU %04d CH %02d dim %d value %e h %p",detElemId,manuId,manuChannel,dim,value,h));
963 h->Fill(static_cast<Int_t>(TMath::Nint(value)));
967 //_____________________________________________________________________________
969 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId,
972 /// Get histogram of a given manu
974 if (!fHistos) return 0x0;
976 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
979 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
984 //_____________________________________________________________________________
986 AliMUONTrackerData::GetManuSparseHisto(Int_t detElemId, Int_t manuId, Int_t dim)
988 /// Get histogram of a given manu. Create it if necessary
990 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
992 AliMUON1DArray* m = static_cast<AliMUON1DArray*>(fHistos->FindObject(detElemId,manuId));
995 m = new AliMUON1DArray(NumberOfDimensions());
996 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1000 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(dim));
1003 h = new AliMUONSparseHisto(fXmin,fXmax);
1005 h->SetUniqueID(dim);
1013 //_____________________________________________________________________________
1015 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1016 Int_t manuChannel, Int_t dim) const
1018 /// Get histogram of a given channel
1020 if (!fHistos) return 0x0;
1022 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1025 UInt_t uid = ( manuChannel << 16 ) | dim;
1027 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1032 //_____________________________________________________________________________
1034 AliMUONTrackerData::GetChannelSparseHisto(Int_t detElemId, Int_t manuId,
1035 Int_t manuChannel, Int_t dim)
1037 /// Get histogram of a given channel. Create it if necessary
1039 if (!fHistos) fHistos = new AliMUON2DMap(kTRUE);
1041 AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fHistos->FindObject(detElemId,manuId));
1044 m = new AliMUON1DMap(AliMpConstants::ManuNofChannels()); // start with only 1 dim
1045 m->SetUniqueID( ( manuId << 16 ) | detElemId );
1049 UInt_t uid = ( manuChannel << 16 ) | dim;
1051 AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
1054 h = new AliMUONSparseHisto(fXmin,fXmax);
1056 h->SetUniqueID(uid);
1064 //_____________________________________________________________________________
1066 AliMUONTrackerData::GetDEManu(const AliMUONVCalibParam& param,
1067 Int_t& detElemId, Int_t& manuId) const
1069 /// Tries to get (detElemId,manuId) of param
1071 // Load mapping manu store
1072 if ( ! AliMpCDB::LoadManuStore() ) {
1073 AliError("Could not access manu store from OCDB !");
1077 if ( param.ID1() <= 0 )
1079 // we (probably) get a manu serial number
1080 Int_t serial = param.ID0();
1081 AliMpIntPair pair = AliMpManuStore::Instance()->GetDetElemIdManu(serial);
1082 detElemId = pair.GetFirst();
1083 manuId = pair.GetSecond();
1086 AliError(Form("DE %d manuId %d from serial %d is not correct !",
1087 detElemId,manuId,serial));
1092 // we get a (de,manu) pair
1093 detElemId = param.ID0();
1094 manuId = param.ID1();
1099 //_____________________________________________________________________________
1101 AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
1102 AliMUONVCalibParam*& chamber,
1103 AliMUONVCalibParam*& de,
1104 AliMUONVCalibParam*& busPatch,
1105 AliMUONVCalibParam*& pcb,
1106 AliMUONVCalibParam*& manu,
1107 AliMUONVCalibParam*& channel,
1108 AliMpDetElement*& mpde)
1110 /// Get containers at all levels
1112 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1117 GetDEManu(*external,detElemId,manuId);
1119 mpde = ddlStore->GetDetElement(detElemId);
1121 if (!mpde) // can happen if reading e.g. capacitances store where we have data for non-connected manus
1126 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
1128 Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1130 Int_t pcbIndex = -1;
1132 AliMp::StationType stationType = mpde->GetStationType();
1134 if ( stationType == AliMp::kStation345 )
1137 pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
1140 channel = ChannelParam(detElemId,manuId,external);
1142 manu = ManuParam(detElemId,manuId,kTRUE);
1144 busPatch = BusPatchParam(busPatchId,kTRUE);
1146 de = DetectionElementParam(detElemId,kTRUE);
1148 chamber = ChamberParam(chamberId,kTRUE);
1152 if ( pcbIndex >= 0 )
1154 pcb = PCBParam(detElemId,pcbIndex,kTRUE);
1160 //_____________________________________________________________________________
1162 AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
1164 /// Whether we have data for a given buspatch
1165 return ( BusPatchParam(busPatchId) != 0 );
1168 //_____________________________________________________________________________
1170 AliMUONTrackerData::HasChamber(Int_t chamberId) const
1172 /// Whether we have data for a given chamber
1173 return ( ChamberParam(chamberId) != 0 );
1176 //_____________________________________________________________________________
1178 AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
1180 /// Whether we have data for a given detection element
1181 return ( DetectionElementParam(detElemId) != 0 );
1184 //_____________________________________________________________________________
1186 AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
1188 /// Whether we have data for a given manu
1189 return ( ManuParam(detElemId,manuId) != 0 );
1192 //_____________________________________________________________________________
1194 AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
1196 /// Whether we have data for a given pcb
1197 return ( PCBParam(detElemId,pcbIndex) != 0 );
1200 //_____________________________________________________________________________
1202 AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
1204 /// Return the value for a given manu and a given dimension
1206 AliMUONVCalibParam* param = ManuParam(detElemId,manuId);
1207 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1210 //_____________________________________________________________________________
1212 AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
1214 /// Get the VCalibParam for a given manu
1216 AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
1217 (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
1219 if (!manu && create && fManuValues)
1221 manu = CreateManuParam(detElemId,manuId);
1222 fManuValues->Add(manu);
1228 //_____________________________________________________________________________
1230 AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
1232 /// Create storage for one manu
1234 AliCodeTimerAuto("");
1236 AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
1238 // set the number of channels in that manu
1240 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
1242 manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
1247 //_____________________________________________________________________________
1249 AliMUONTrackerData::Merge(TCollection* list)
1251 /// Merge this with a list of AliMUONVTrackerData
1253 if (!list) return 0;
1255 if ( list->IsEmpty() ) return NumberOfEvents(-1);
1258 const TObject* o(0x0);
1260 while ( ( o = next() ) )
1262 const AliMUONTrackerData* data = dynamic_cast<const AliMUONTrackerData*>(o);
1265 AliError(Form("Object named %s is not an AliMUONTrackerData ! Skipping it",
1270 Bool_t ok = Add(*data);
1273 AliError("Got incompatible objects");
1278 return NumberOfEvents(-1);
1281 //_____________________________________________________________________________
1283 AliMUONTrackerData::NumberOfDimensions() const
1285 /// Number of dimensions we're dealing with
1287 return fDimension + fgkVirtualExtraDimension;
1290 //_____________________________________________________________________________
1292 AliMUONTrackerData::NumberOfEvents(Int_t ddlNumber) const
1294 /// Get the number of events we've seen for a given DDL, or the max
1295 /// in case ddlNumber<0
1299 if ( fNofEventsPerDDL && ddlNumber >= 0 && ddlNumber < fNofDDLs )
1301 n = fNofEventsPerDDL[ddlNumber];
1305 // get the max number of events
1312 //_____________________________________________________________________________
1314 AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
1316 /// Return the value of a given pcb for a given dimension
1318 AliMUONVCalibParam* param = PCBParam(detElemId,pcbIndex);
1320 return param ? Value(*param,0,dim,DdlIdFromDetElemId(detElemId)) : 0.0;
1323 //_____________________________________________________________________________
1325 AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
1327 /// Return (if it exist) the VCalibParam for a given pcb
1329 AliMUONVCalibParam* pcb = fPCBValues ? static_cast<AliMUONVCalibParam*>
1330 (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
1332 if (create && fPCBValues && !pcb)
1334 pcb = CreatePCBParam(detElemId,pcbIndex);
1335 fPCBValues->Add(pcb);
1341 //_____________________________________________________________________________
1343 AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
1345 /// Create storage for one PCB (station345 only)
1347 AliCodeTimerAuto("");
1351 AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
1352 namer.NumberOfPCBs(detElemId),
1359 //_____________________________________________________________________________
1361 AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
1367 if ( !fIsSingleEvent )
1369 for ( Int_t i = 0; i < fNofDDLs; ++i )
1371 cout << Form("DDL %04d Nevents=%10d",AliDAQ::DdlID("MUONTRK",i),fNofEventsPerDDL[i]) << endl;
1375 if ( !fIsChannelLevelEnabled )
1377 cout << "Is not storing data at the channel level" << endl;
1380 if ( !fIsManuLevelEnabled )
1382 cout << "Is not storing data at the manu level" << endl;
1385 for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i )
1387 TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
1388 cout << Form("External Dimension %2d Name %s %s",i,
1389 ( name ? name->String().Data() : "null"),
1390 ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
1393 for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i )
1395 TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
1396 cout << Form("Internal Dimension %2d Name %s",i,
1397 ( name ? name->String().Data() : "null")) << endl;
1403 if ( sopt.Contains("CHANNEL") )
1405 if ( fIsChannelLevelEnabled )
1407 if ( fChannelValues ) fChannelValues->Print(wildcard,opt);
1411 AliWarning("You requested channel values, but they were not stored !");
1415 if ( sopt.Contains("MANU") )
1417 if ( fIsManuLevelEnabled )
1419 if ( fManuValues ) fManuValues->Print(wildcard,opt);
1423 AliWarning("You requested manu values, but they were not stored !");
1427 if ( sopt.Contains("BUSPATCH") && fBusPatchValues )
1429 fBusPatchValues->Print(wildcard,opt);
1432 if ( sopt.Contains("DE") && fDEValues )
1434 fDEValues->Print(wildcard,opt);
1437 if ( sopt.Contains("CHAMBER") && fChamberValues )
1439 fChamberValues->Print(wildcard,opt);
1444 //_____________________________________________________________________________
1446 AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
1448 /// Set the name of a given dimension
1450 if ( index >= fExternalDimension )
1452 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
1456 Int_t ix = External2Internal(index);
1458 if ( !IsSingleEvent() )
1460 const char* prefix[] = { "mean", "sigma" };
1462 for ( Int_t i = 0; i < 2; ++i )
1466 SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
1471 SetInternalDimensionName(index,name);
1474 SetExternalDimensionName(index,name);
1477 //_____________________________________________________________________________
1479 AliMUONTrackerData::MakeHistogramForDimension(Int_t index, Bool_t value, Double_t xmin, Double_t xmax)
1481 /// decide to make histos for a given dimension
1482 if ( index >= ExternalDimension() )
1484 AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
1488 fHistogramming[index] = value;
1493 //_____________________________________________________________________________
1495 AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
1497 /// Set the name of a given internal dimension
1498 if ( index >= fDimension )
1500 AliError(Form("Index out of bounds : %d / %d",index,fDimension));
1504 TObjString* ovalue = static_cast<TObjString*>(fDimensionNames->At(index));
1508 fDimensionNames->Remove(ovalue);
1511 fDimensionNames->AddAt(new TObjString(value),index);
1514 //_____________________________________________________________________________
1516 AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
1518 /// Set the name of a given external dimension
1519 if ( index >= fExternalDimension )
1521 AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
1525 TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
1529 fExternalDimensionNames->Remove(ovalue);
1532 fExternalDimensionNames->AddAt(new TObjString(value),index);
1535 //_____________________________________________________________________________
1537 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i,
1538 Int_t dim, Int_t ddlId) const
1540 /// Compute the value for a given dim, using the internal information we have
1541 /// Basically we're converting sum of weights and sum of squares of weights
1542 /// into means and sigmas, and number of events into occupancy number.
1544 Double_t n = param.ValueAsDouble(i,IndexOfNumberDimension());
1546 if ( dim == IndexOfNumberDimension() ) return n; // the number of channels in any given element does not depend on the number of events
1548 Double_t occ = param.ValueAsDouble(i,IndexOfOccupancyDimension());
1550 if ( dim >= fDimension )
1555 if ( dim == IndexOfOccupancyDimension() )
1557 if ( ddlId < 0 ) AliError("Got a negative ddl id !");
1558 return occ/n/NumberOfEvents(ddlId);
1561 Double_t value = param.ValueAsDouble(i,dim);
1563 if ( value >= AliMUONVCalibParam::InvalidFloatValue() ) return AliMUONVCalibParam::InvalidFloatValue();
1565 if ( TMath::Even(dim) || IsSingleEvent() )
1567 Double_t x = value/occ;
1569 return ( TMath::Finite(x) ? x : 0.0 ) ;
1577 Double_t mean = param.ValueAsDouble(i,dim-1)/nn;
1579 return TMath::Sqrt(TMath::Abs((value-nn*mean*mean)/(nn-1.0)));
1587 AliError("Why am I here ?");
1591 //_____________________________________________________________________________
1593 AliMUONTrackerData::Streamer(TBuffer &R__b)
1595 /// Customized streamer
1597 if (R__b.IsReading()) {
1598 AliMUONTrackerData::Class()->ReadBuffer(R__b, this);
1601 // backward compatible mode : we set number of events
1602 // per DDL to the total number of events (the only information
1603 // we had before version 7 of that class)
1604 delete[] fNofEventsPerDDL;
1606 fNofEventsPerDDL = new Int_t[fNofDDLs];
1607 for ( Int_t i = 0; i < fNofDDLs; ++i )
1609 fNofEventsPerDDL[i] = fNevents;
1614 AliMUONTrackerData::Class()->WriteBuffer(R__b, this);