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 "AliMUONTrackerDataHistogrammer.h"
21 #include "AliMUONPainterGroup.h"
22 #include "AliMUONSparseHisto.h"
23 #include "AliMUONVPainter.h"
24 #include "AliMUONVTrackerData.h"
25 #include "AliMpBusPatch.h"
26 #include "AliMpConstants.h"
27 #include "AliMpDDLStore.h"
28 #include "AliMpDEIterator.h"
29 #include "AliMpDetElement.h"
30 #include "AliMpManuUID.h"
33 #include <TObjArray.h>
37 ///\class AliMUONTrackerDataHistogrammer
39 /// Class to generate histograms from AliMUONVTrackerData
40 /// (and AliMUONVPainter) objects
42 /// \author Laurent Aphecetche, Subatech
46 ClassImp(AliMUONTrackerDataHistogrammer)
49 //_____________________________________________________________________________
50 AliMUONTrackerDataHistogrammer::AliMUONTrackerDataHistogrammer(const AliMUONVTrackerData& data,
55 fExternalDim(externalDim),
56 fInternalDim(internalDim)
61 //_____________________________________________________________________________
62 AliMUONTrackerDataHistogrammer::~AliMUONTrackerDataHistogrammer()
67 //_____________________________________________________________________________
69 AliMUONTrackerDataHistogrammer::Add(TH1& h, const AliMUONSparseHisto& sh) const
71 /// Add sparse histo content to histogram.
73 Double_t entries(h.GetEntries());
75 for ( Int_t i = 0; i < sh.GetNbins(); ++i )
77 Int_t count = sh.GetBinContent(i);
79 h.Fill(sh.GetBinCenter(i),count);
84 h.SetEntries(entries);
86 if (sh.HasUnderflow()) h.SetBinContent(0,1);
87 if (sh.HasOverflow()) h.SetBinContent(h.GetNbinsX()+1,1);
90 //_____________________________________________________________________________
92 AliMUONTrackerDataHistogrammer::AddBusPatchHisto(TH1& h, Int_t busPatchId) const
94 /// Add data from one bus patch to the histogram
96 if ( fkData.HasBusPatch(busPatchId ) )
98 AliMpBusPatch* busPatch = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
99 for ( Int_t i = 0; i < busPatch->GetNofManus(); ++i )
101 Int_t manuId = busPatch->GetManuId(i);
102 AddManuHisto(h,busPatch->GetDEId(),manuId);
106 //_____________________________________________________________________________
108 AliMUONTrackerDataHistogrammer::AddDEHisto(TH1& h, Int_t detElemId) const
110 /// Add data from one detection element to the histogram
112 if ( fkData.HasDetectionElement(detElemId) )
114 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
115 for ( Int_t i = 0; i < de->GetNofBusPatches(); ++ i )
117 Int_t busPatchId = de->GetBusPatchId(i);
118 AddBusPatchHisto(h,busPatchId);
123 //_____________________________________________________________________________
125 AliMUONTrackerDataHistogrammer::AddManuHisto(TH1& h, Int_t detElemId, Int_t manuId) const
127 /// Add data from a given manu to histogram
129 if ( fkData.HasManu(detElemId,manuId) )
131 if ( fkData.IsChannelLevelEnabled() )
133 for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i )
135 if ( fkData.HasChannel(detElemId,manuId,i) )
137 if ( IsInternalMode() )
139 h.Fill(fkData.Channel(detElemId,manuId,i,fInternalDim));
143 AliMUONSparseHisto* sh = fkData.GetChannelSparseHisto(detElemId,manuId,i,fExternalDim);
155 if ( IsInternalMode() )
157 h.Fill(fkData.Manu(detElemId,manuId,fInternalDim));
161 AliMUONSparseHisto* sh = fkData.GetManuSparseHisto(detElemId,manuId,fExternalDim);
171 //_____________________________________________________________________________
173 AliMUONTrackerDataHistogrammer::CreateChannelHisto(Int_t detElemId,
175 Int_t manuChannel) const
177 /// Create histogram of a given channel. Note that in order
178 /// to keep memory footprint as low as possible, you should delete
179 /// the returned pointer as soon as possible...
181 if ( fkData.HasChannel(detElemId, manuId, manuChannel) && fkData.IsHistogrammed(fExternalDim) )
183 AliMUONSparseHisto* sh = fkData.GetChannelSparseHisto(detElemId,manuId,manuChannel);
187 Int_t nbins((1<<sh->Nbits()));
189 fkData.HistogramRange(xmin,xmax);
191 TH1* h = CreateHisto(Form("DE%04dMANU%04dCH%02d",detElemId,manuId,manuChannel),
203 //_____________________________________________________________________________
205 AliMUONTrackerDataHistogrammer::CreateHisto(const char* name,
210 /// Create a single histogram
216 h = new TH1F(name,name,nbins,xmin,xmax);
217 h->SetDirectory(gROOT);
221 AliError(Form("Cannot create histo for name=%s nbins=%d xmin=%e xmax=%e",name,nbins,xmin,xmax));
226 //_____________________________________________________________________________
228 AliMUONTrackerDataHistogrammer::CreateHisto(const AliMUONVPainter& painter,
232 /// Create an histogram, from given dim of given data,
233 /// for all the channels handled by painter
235 AliMUONPainterGroup* group = painter.Master()->PlotterGroup();
237 if ( !group ) return 0x0; // no data to histogram in this painter
239 AliMUONVTrackerData* data = group->Data();
241 if ( externalDim >= data->ExternalDimension() )
243 AliErrorClass(Form("externalDim %d is out of bounds",externalDim));
247 if ( internalDim >= data->NumberOfDimensions() )
249 AliErrorClass(Form("internalDim %d is out of bounds",internalDim));
253 if ( internalDim < 0 && externalDim < 0 )
255 AliErrorClass("Both internal and external dim are < 0 !!!");
259 AliMUONTrackerDataHistogrammer tdh(*data,externalDim,internalDim);
263 painter.FillManuList(manuArray);
266 TIter next(&manuArray);
268 TString basename(Form("%s-%s",painter.PathName().Data(),painter.Attributes().GetName()));
270 Int_t nbins((1<<12));
274 if ( !tdh.IsInternalMode() )
276 data->HistogramRange(xmin,xmax);
281 ext = data->ExternalDimensionName(externalDim).Data();
285 tdh.GetDataRange(manuArray,xmin,xmax);
286 ext = data->DimensionName(internalDim).Data();
290 TString name(Form("%s-%s",basename.Data(),ext.Data()));
292 TH1* histo = tdh.CreateHisto(name.Data(),nbins,xmin,xmax);
296 while ( ( mid = static_cast<AliMpManuUID*>(next()) ) )
298 TH1* h = tdh.CreateManuHisto(mid->DetElemId(),mid->ManuId(),nbins,xmin,xmax);
308 AliErrorClass(Form("Could not create histo for painter %s (%p) data %s (%p) external dim %d internal dim %d",
309 painter.PathName().Data(),&painter,
310 data->GetName(),data,externalDim,internalDim));
313 if (histo) histo->SetDirectory(gROOT);
318 //_____________________________________________________________________________
320 AliMUONTrackerDataHistogrammer::CreateManuHisto(Int_t detElemId, Int_t manuId,
325 /// Create histogram of a given manu. Note that in order
326 /// to keep memory footprint as low as possible, you should delete
327 /// the returned pointer as soon as possible...
331 if ( !fkData.HasManu(detElemId,manuId) ) return 0x0;
333 if ( ( fExternalDim >= 0 && fkData.IsHistogrammed(fExternalDim) ) ||
334 ( fInternalDim >= 0 && fInternalDim < fkData.NumberOfDimensions() ) )
336 h = CreateHisto(Form("DE%04dMANU%04d",detElemId,manuId),
338 if ( h ) AddManuHisto(*h,detElemId,manuId);
344 //_____________________________________________________________________________
346 AliMUONTrackerDataHistogrammer::GetDataRange(const TObjArray& manuArray,
347 Double_t& xmin, Double_t& xmax) const
349 /// Get data range (in case of InternalMode() only) spanned by the manus in
355 if (!IsInternalMode())
357 AliError("Cannot use this method for external mode !");
361 TIter next(&manuArray);
363 while ( ( mid = static_cast<AliMpManuUID*>(next()) ) )
365 Int_t detElemId = mid->DetElemId();
366 Int_t manuId = mid->ManuId();
368 for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i )
370 if ( fkData.HasChannel(detElemId,manuId,i) )
372 Double_t value = fkData.Channel(detElemId,manuId,i,fInternalDim);
374 if ( ! TMath::Finite(value) )
376 AliError(Form("Got a NaN for DE %d manu %d ch %d",detElemId,manuId,i));
380 xmin = TMath::Min(xmin,value);
381 xmax = TMath::Max(xmax,value);