Line data Source code
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 "AliMUONTrackerDataHistogrammer.h"
19 :
20 : #include "AliLog.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"
31 : #include <TClass.h>
32 : #include <TH1.h>
33 : #include <TObjArray.h>
34 : #include <TROOT.h>
35 : #include <TMath.h>
36 :
37 : ///\class AliMUONTrackerDataHistogrammer
38 : ///
39 : /// Class to generate histograms from AliMUONVTrackerData
40 : /// (and AliMUONVPainter) objects
41 : ///
42 : /// \author Laurent Aphecetche, Subatech
43 : ///
44 :
45 : ///\cond CLASSIMP
46 12 : ClassImp(AliMUONTrackerDataHistogrammer)
47 : ///\endcond CLASSIMP
48 :
49 : //_____________________________________________________________________________
50 : AliMUONTrackerDataHistogrammer::AliMUONTrackerDataHistogrammer(const AliMUONVTrackerData& data,
51 : Int_t externalDim,
52 : Int_t internalDim)
53 0 : : TObject(),
54 0 : fkData(data),
55 0 : fExternalDim(externalDim),
56 0 : fInternalDim(internalDim)
57 0 : {
58 : /// ctor
59 0 : }
60 :
61 : //_____________________________________________________________________________
62 : AliMUONTrackerDataHistogrammer::~AliMUONTrackerDataHistogrammer()
63 0 : {
64 : /// dtor
65 0 : }
66 :
67 : //_____________________________________________________________________________
68 : void
69 : AliMUONTrackerDataHistogrammer::Add(TH1& h, const AliMUONSparseHisto& sh) const
70 : {
71 : /// Add sparse histo content to histogram.
72 :
73 0 : Double_t entries(h.GetEntries());
74 :
75 0 : for ( Int_t i = 0; i < sh.GetNbins(); ++i )
76 : {
77 0 : Int_t count = sh.GetBinContent(i);
78 :
79 0 : h.Fill(sh.GetBinCenter(i),count);
80 :
81 0 : entries += count;
82 : }
83 :
84 0 : h.SetEntries(entries);
85 :
86 0 : if (sh.HasUnderflow()) h.SetBinContent(0,1);
87 0 : if (sh.HasOverflow()) h.SetBinContent(h.GetNbinsX()+1,1);
88 0 : }
89 :
90 : //_____________________________________________________________________________
91 : void
92 : AliMUONTrackerDataHistogrammer::AddBusPatchHisto(TH1& h, Int_t busPatchId) const
93 : {
94 : /// Add data from one bus patch to the histogram
95 :
96 0 : if ( fkData.HasBusPatch(busPatchId ) )
97 : {
98 0 : AliMpBusPatch* busPatch = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
99 0 : for ( Int_t i = 0; i < busPatch->GetNofManus(); ++i )
100 : {
101 0 : Int_t manuId = busPatch->GetManuId(i);
102 0 : AddManuHisto(h,busPatch->GetDEId(),manuId);
103 : }
104 0 : }
105 0 : }
106 : //_____________________________________________________________________________
107 : void
108 : AliMUONTrackerDataHistogrammer::AddDEHisto(TH1& h, Int_t detElemId) const
109 : {
110 : /// Add data from one detection element to the histogram
111 :
112 0 : if ( fkData.HasDetectionElement(detElemId) )
113 : {
114 0 : AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
115 0 : for ( Int_t i = 0; i < de->GetNofBusPatches(); ++ i )
116 : {
117 0 : Int_t busPatchId = de->GetBusPatchId(i);
118 0 : AddBusPatchHisto(h,busPatchId);
119 : }
120 0 : }
121 0 : }
122 :
123 : //_____________________________________________________________________________
124 : void
125 : AliMUONTrackerDataHistogrammer::AddManuHisto(TH1& h, Int_t detElemId, Int_t manuId) const
126 : {
127 : /// Add data from a given manu to histogram
128 :
129 0 : if ( fkData.HasManu(detElemId,manuId) )
130 : {
131 0 : if ( fkData.IsChannelLevelEnabled() )
132 : {
133 0 : for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i )
134 : {
135 0 : if ( fkData.HasChannel(detElemId,manuId,i) )
136 : {
137 0 : if ( IsInternalMode() )
138 : {
139 0 : h.Fill(fkData.Channel(detElemId,manuId,i,fInternalDim));
140 0 : }
141 : else
142 : {
143 0 : AliMUONSparseHisto* sh = fkData.GetChannelSparseHisto(detElemId,manuId,i,fExternalDim);
144 :
145 0 : if ( sh )
146 : {
147 0 : Add(h,*sh);
148 0 : }
149 : }
150 : }
151 : }
152 0 : }
153 : else
154 : {
155 0 : if ( IsInternalMode() )
156 : {
157 0 : h.Fill(fkData.Manu(detElemId,manuId,fInternalDim));
158 0 : }
159 : else
160 : {
161 0 : AliMUONSparseHisto* sh = fkData.GetManuSparseHisto(detElemId,manuId,fExternalDim);
162 0 : if (sh)
163 : {
164 0 : Add(h,*sh);
165 0 : }
166 : }
167 : }
168 : }
169 0 : }
170 :
171 : //_____________________________________________________________________________
172 : TH1*
173 : AliMUONTrackerDataHistogrammer::CreateChannelHisto(Int_t detElemId,
174 : Int_t manuId,
175 : Int_t manuChannel) const
176 : {
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...
180 :
181 0 : if ( fkData.HasChannel(detElemId, manuId, manuChannel) && fkData.IsHistogrammed(fExternalDim) )
182 : {
183 0 : AliMUONSparseHisto* sh = fkData.GetChannelSparseHisto(detElemId,manuId,manuChannel);
184 :
185 0 : if ( sh )
186 : {
187 0 : Int_t nbins((1<<sh->Nbits()));
188 0 : Double_t xmin,xmax;
189 0 : fkData.HistogramRange(xmin,xmax);
190 :
191 0 : TH1* h = CreateHisto(Form("DE%04dMANU%04dCH%02d",detElemId,manuId,manuChannel),
192 0 : nbins,xmin,xmax);
193 0 : if (h )
194 : {
195 0 : Add(*h,*sh);
196 0 : }
197 : return h;
198 0 : }
199 0 : }
200 0 : return 0x0;
201 0 : }
202 :
203 : //_____________________________________________________________________________
204 : TH1*
205 : AliMUONTrackerDataHistogrammer::CreateHisto(const char* name,
206 : Int_t nbins,
207 : Double_t xmin,
208 : Double_t xmax) const
209 : {
210 : /// Create a single histogram
211 :
212 : TH1* h(0);
213 :
214 0 : if ( xmin < xmax )
215 : {
216 0 : h = new TH1F(name,name,nbins,xmin,xmax);
217 0 : h->SetDirectory(gROOT);
218 0 : }
219 : else
220 : {
221 0 : AliError(Form("Cannot create histo for name=%s nbins=%d xmin=%e xmax=%e",name,nbins,xmin,xmax));
222 : }
223 0 : return h;
224 0 : }
225 :
226 : //_____________________________________________________________________________
227 : TH1*
228 : AliMUONTrackerDataHistogrammer::CreateHisto(const AliMUONVPainter& painter,
229 : Int_t externalDim,
230 : Int_t internalDim)
231 : {
232 : /// Create an histogram, from given dim of given data,
233 : /// for all the channels handled by painter
234 :
235 0 : AliMUONPainterGroup* group = painter.Master()->PlotterGroup();
236 :
237 0 : if ( !group ) return 0x0; // no data to histogram in this painter
238 :
239 0 : AliMUONVTrackerData* data = group->Data();
240 :
241 0 : if ( externalDim >= data->ExternalDimension() )
242 : {
243 0 : AliErrorClass(Form("externalDim %d is out of bounds",externalDim));
244 0 : return 0x0;
245 : }
246 :
247 0 : if ( internalDim >= data->NumberOfDimensions() )
248 : {
249 0 : AliErrorClass(Form("internalDim %d is out of bounds",internalDim));
250 0 : return 0x0;
251 : }
252 :
253 0 : if ( internalDim < 0 && externalDim < 0 )
254 : {
255 0 : AliErrorClass("Both internal and external dim are < 0 !!!");
256 0 : return 0x0;
257 : }
258 :
259 0 : AliMUONTrackerDataHistogrammer tdh(*data,externalDim,internalDim);
260 :
261 0 : TObjArray manuArray;
262 :
263 0 : painter.FillManuList(manuArray);
264 :
265 : AliMpManuUID* mid;
266 0 : TIter next(&manuArray);
267 :
268 0 : TString basename(Form("%s-%s",painter.PathName().Data(),painter.Attributes().GetName()));
269 0 : TString ext;
270 : Int_t nbins((1<<12));
271 0 : Double_t xmin(0.0);
272 0 : Double_t xmax(0.0);
273 :
274 0 : if ( !tdh.IsInternalMode() )
275 : {
276 0 : data->HistogramRange(xmin,xmax);
277 :
278 0 : xmin -= 0.5;
279 0 : xmax -= 0.5;
280 :
281 0 : ext = data->ExternalDimensionName(externalDim).Data();
282 0 : }
283 : else
284 : {
285 0 : tdh.GetDataRange(manuArray,xmin,xmax);
286 0 : ext = data->DimensionName(internalDim).Data();
287 : nbins = 100;
288 : }
289 :
290 0 : TString name(Form("%s-%s",basename.Data(),ext.Data()));
291 :
292 0 : TH1* histo = tdh.CreateHisto(name.Data(),nbins,xmin,xmax);
293 :
294 0 : if ( histo )
295 : {
296 0 : while ( ( mid = static_cast<AliMpManuUID*>(next()) ) )
297 : {
298 0 : TH1* h = tdh.CreateManuHisto(mid->DetElemId(),mid->ManuId(),nbins,xmin,xmax);
299 0 : if ( h )
300 : {
301 0 : histo->Add(h);
302 : }
303 0 : delete h;
304 : }
305 : }
306 : else
307 : {
308 0 : 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));
311 : }
312 :
313 0 : if (histo) histo->SetDirectory(gROOT);
314 :
315 : return histo;
316 0 : }
317 :
318 : //_____________________________________________________________________________
319 : TH1*
320 : AliMUONTrackerDataHistogrammer::CreateManuHisto(Int_t detElemId, Int_t manuId,
321 : Int_t nbins,
322 : Double_t xmin,
323 : Double_t xmax) const
324 : {
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...
328 :
329 : TH1* h(0x0);
330 :
331 0 : if ( !fkData.HasManu(detElemId,manuId) ) return 0x0;
332 :
333 0 : if ( ( fExternalDim >= 0 && fkData.IsHistogrammed(fExternalDim) ) ||
334 0 : ( fInternalDim >= 0 && fInternalDim < fkData.NumberOfDimensions() ) )
335 : {
336 0 : h = CreateHisto(Form("DE%04dMANU%04d",detElemId,manuId),
337 : nbins,xmin,xmax);
338 0 : if ( h ) AddManuHisto(*h,detElemId,manuId);
339 : }
340 :
341 0 : return h;
342 0 : }
343 :
344 : //_____________________________________________________________________________
345 : void
346 : AliMUONTrackerDataHistogrammer::GetDataRange(const TObjArray& manuArray,
347 : Double_t& xmin, Double_t& xmax) const
348 : {
349 : /// Get data range (in case of InternalMode() only) spanned by the manus in
350 : /// manuArray
351 :
352 0 : xmin = FLT_MAX;
353 0 : xmax = -FLT_MAX;
354 :
355 0 : if (!IsInternalMode())
356 : {
357 0 : AliError("Cannot use this method for external mode !");
358 0 : }
359 :
360 : AliMpManuUID* mid;
361 0 : TIter next(&manuArray);
362 :
363 0 : while ( ( mid = static_cast<AliMpManuUID*>(next()) ) )
364 : {
365 0 : Int_t detElemId = mid->DetElemId();
366 0 : Int_t manuId = mid->ManuId();
367 :
368 0 : for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i )
369 : {
370 0 : if ( fkData.HasChannel(detElemId,manuId,i) )
371 : {
372 0 : Double_t value = fkData.Channel(detElemId,manuId,i,fInternalDim);
373 :
374 0 : if ( ! TMath::Finite(value) )
375 : {
376 0 : AliError(Form("Got a NaN for DE %d manu %d ch %d",detElemId,manuId,i));
377 : }
378 : else
379 : {
380 0 : xmin = TMath::Min(xmin,value);
381 0 : xmax = TMath::Max(xmax,value);
382 : }
383 0 : }
384 : }
385 : }
386 :
387 0 : }
388 :
|