]>
Commit | Line | Data |
---|---|---|
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 | ClassImp(AliMUONTrackerDataHistogrammer) | |
47 | ///\endcond CLASSIMP | |
48 | ||
49 | //_____________________________________________________________________________ | |
50 | AliMUONTrackerDataHistogrammer::AliMUONTrackerDataHistogrammer(const AliMUONVTrackerData& data, | |
51 | Int_t externalDim, | |
52 | Int_t internalDim) | |
53 | : TObject(), | |
54 | fkData(data), | |
55 | fExternalDim(externalDim), | |
56 | fInternalDim(internalDim) | |
57 | { | |
58 | /// ctor | |
59 | } | |
60 | ||
61 | //_____________________________________________________________________________ | |
62 | AliMUONTrackerDataHistogrammer::~AliMUONTrackerDataHistogrammer() | |
63 | { | |
64 | /// dtor | |
65 | } | |
66 | ||
67 | //_____________________________________________________________________________ | |
68 | void | |
69 | AliMUONTrackerDataHistogrammer::Add(TH1& h, const AliMUONSparseHisto& sh) const | |
70 | { | |
71 | /// Add sparse histo content to histogram. | |
72 | ||
73 | Double_t entries(h.GetEntries()); | |
74 | ||
75 | for ( Int_t i = 0; i < sh.GetNbins(); ++i ) | |
76 | { | |
77 | Int_t count = sh.GetBinContent(i); | |
78 | ||
79 | h.Fill(sh.GetBinCenter(i),count); | |
80 | ||
81 | entries += count; | |
82 | } | |
83 | ||
84 | h.SetEntries(entries); | |
85 | ||
86 | if (sh.HasUnderflow()) h.SetBinContent(0,1); | |
87 | if (sh.HasOverflow()) h.SetBinContent(h.GetNbinsX()+1,1); | |
88 | } | |
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 | if ( fkData.HasBusPatch(busPatchId ) ) | |
97 | { | |
98 | AliMpBusPatch* busPatch = AliMpDDLStore::Instance()->GetBusPatch(busPatchId); | |
99 | for ( Int_t i = 0; i < busPatch->GetNofManus(); ++i ) | |
100 | { | |
101 | Int_t manuId = busPatch->GetManuId(i); | |
102 | AddManuHisto(h,busPatch->GetDEId(),manuId); | |
103 | } | |
104 | } | |
105 | } | |
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 | if ( fkData.HasDetectionElement(detElemId) ) | |
113 | { | |
114 | AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId); | |
115 | for ( Int_t i = 0; i < de->GetNofBusPatches(); ++ i ) | |
116 | { | |
117 | Int_t busPatchId = de->GetBusPatchId(i); | |
118 | AddBusPatchHisto(h,busPatchId); | |
119 | } | |
120 | } | |
121 | } | |
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 | if ( fkData.HasManu(detElemId,manuId) ) | |
130 | { | |
131 | if ( fkData.IsChannelLevelEnabled() ) | |
132 | { | |
133 | for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i ) | |
134 | { | |
135 | if ( fkData.HasChannel(detElemId,manuId,i) ) | |
136 | { | |
137 | if ( IsInternalMode() ) | |
138 | { | |
139 | h.Fill(fkData.Channel(detElemId,manuId,i,fInternalDim)); | |
140 | } | |
141 | else | |
142 | { | |
143 | AliMUONSparseHisto* sh = fkData.GetChannelSparseHisto(detElemId,manuId,i,fExternalDim); | |
144 | ||
145 | if ( sh ) | |
146 | { | |
147 | Add(h,*sh); | |
148 | } | |
149 | } | |
150 | } | |
151 | } | |
152 | } | |
153 | else | |
154 | { | |
155 | if ( IsInternalMode() ) | |
156 | { | |
157 | h.Fill(fkData.Manu(detElemId,manuId,fInternalDim)); | |
158 | } | |
159 | else | |
160 | { | |
161 | AliMUONSparseHisto* sh = fkData.GetManuSparseHisto(detElemId,manuId,fExternalDim); | |
162 | if (sh) | |
163 | { | |
164 | Add(h,*sh); | |
165 | } | |
166 | } | |
167 | } | |
168 | } | |
169 | } | |
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 | if ( fkData.HasChannel(detElemId, manuId, manuChannel) && fkData.IsHistogrammed(fExternalDim) ) | |
182 | { | |
183 | AliMUONSparseHisto* sh = fkData.GetChannelSparseHisto(detElemId,manuId,manuChannel); | |
184 | ||
185 | if ( sh ) | |
186 | { | |
187 | Int_t nbins((1<<sh->Nbits())); | |
188 | Double_t xmin,xmax; | |
189 | fkData.HistogramRange(xmin,xmax); | |
190 | ||
191 | TH1* h = CreateHisto(Form("DE%04dMANU%04dCH%02d",detElemId,manuId,manuChannel), | |
192 | nbins,xmin,xmax); | |
193 | if (h ) | |
194 | { | |
195 | Add(*h,*sh); | |
196 | } | |
197 | return h; | |
198 | } | |
199 | } | |
200 | return 0x0; | |
201 | } | |
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 | if ( xmin < xmax ) | |
215 | { | |
216 | h = new TH1F(name,name,nbins,xmin,xmax); | |
217 | h->SetDirectory(gROOT); | |
218 | } | |
219 | else | |
220 | { | |
221 | AliError(Form("Cannot create histo for name=%s nbins=%d xmin=%e xmax=%e",name,nbins,xmin,xmax)); | |
222 | } | |
223 | return h; | |
224 | } | |
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 | AliMUONPainterGroup* group = painter.Master()->PlotterGroup(); | |
236 | ||
237 | if ( !group ) return 0x0; // no data to histogram in this painter | |
238 | ||
239 | AliMUONVTrackerData* data = group->Data(); | |
240 | ||
241 | if ( externalDim >= data->ExternalDimension() ) | |
242 | { | |
243 | AliErrorClass(Form("externalDim %d is out of bounds",externalDim)); | |
244 | return 0x0; | |
245 | } | |
246 | ||
247 | if ( internalDim >= data->NumberOfDimensions() ) | |
248 | { | |
249 | AliErrorClass(Form("internalDim %d is out of bounds",internalDim)); | |
250 | return 0x0; | |
251 | } | |
252 | ||
253 | if ( internalDim < 0 && externalDim < 0 ) | |
254 | { | |
255 | AliErrorClass("Both internal and external dim are < 0 !!!"); | |
256 | return 0x0; | |
257 | } | |
258 | ||
259 | AliMUONTrackerDataHistogrammer tdh(*data,externalDim,internalDim); | |
260 | ||
261 | TObjArray manuArray; | |
262 | ||
263 | painter.FillManuList(manuArray); | |
264 | ||
265 | AliMpManuUID* mid; | |
266 | TIter next(&manuArray); | |
267 | ||
268 | TString basename(Form("%s-%s",painter.PathName().Data(),painter.Attributes().GetName())); | |
269 | TString ext; | |
270 | Int_t nbins((1<<12)); | |
271 | Double_t xmin(0.0); | |
272 | Double_t xmax(0.0); | |
273 | ||
274 | if ( !tdh.IsInternalMode() ) | |
275 | { | |
276 | data->HistogramRange(xmin,xmax); | |
277 | ||
278 | xmin -= 0.5; | |
279 | xmax -= 0.5; | |
280 | ||
281 | ext = data->ExternalDimensionName(externalDim).Data(); | |
282 | } | |
283 | else | |
284 | { | |
285 | tdh.GetDataRange(manuArray,xmin,xmax); | |
286 | ext = data->DimensionName(internalDim).Data(); | |
287 | nbins = 100; | |
288 | } | |
289 | ||
290 | TString name(Form("%s-%s",basename.Data(),ext.Data())); | |
291 | ||
292 | TH1* histo = tdh.CreateHisto(name.Data(),nbins,xmin,xmax); | |
293 | ||
294 | if ( histo ) | |
295 | { | |
296 | while ( ( mid = static_cast<AliMpManuUID*>(next()) ) ) | |
297 | { | |
298 | TH1* h = tdh.CreateManuHisto(mid->DetElemId(),mid->ManuId(),nbins,xmin,xmax); | |
299 | if ( h ) | |
300 | { | |
301 | histo->Add(h); | |
302 | } | |
303 | delete h; | |
304 | } | |
305 | } | |
306 | else | |
307 | { | |
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)); | |
311 | } | |
312 | ||
313 | if (histo) histo->SetDirectory(gROOT); | |
314 | ||
315 | return histo; | |
316 | } | |
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 | if ( !fkData.HasManu(detElemId,manuId) ) return 0x0; | |
332 | ||
333 | if ( ( fExternalDim >= 0 && fkData.IsHistogrammed(fExternalDim) ) || | |
334 | ( fInternalDim >= 0 && fInternalDim < fkData.NumberOfDimensions() ) ) | |
335 | { | |
336 | h = CreateHisto(Form("DE%04dMANU%04d",detElemId,manuId), | |
337 | nbins,xmin,xmax); | |
338 | if ( h ) AddManuHisto(*h,detElemId,manuId); | |
339 | } | |
340 | ||
341 | return h; | |
342 | } | |
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 | xmin = FLT_MAX; | |
353 | xmax = -FLT_MAX; | |
354 | ||
355 | if (!IsInternalMode()) | |
356 | { | |
357 | AliError("Cannot use this method for external mode !"); | |
358 | } | |
359 | ||
360 | AliMpManuUID* mid; | |
361 | TIter next(&manuArray); | |
362 | ||
363 | while ( ( mid = static_cast<AliMpManuUID*>(next()) ) ) | |
364 | { | |
365 | Int_t detElemId = mid->DetElemId(); | |
366 | Int_t manuId = mid->ManuId(); | |
367 | ||
368 | for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i ) | |
369 | { | |
370 | if ( fkData.HasChannel(detElemId,manuId,i) ) | |
371 | { | |
372 | Double_t value = fkData.Channel(detElemId,manuId,i,fInternalDim); | |
373 | ||
374 | if ( ! TMath::Finite(value) ) | |
375 | { | |
376 | AliError(Form("Got a NaN for DE %d manu %d ch %d",detElemId,manuId,i)); | |
377 | } | |
378 | else | |
379 | { | |
380 | xmin = TMath::Min(xmin,value); | |
381 | xmax = TMath::Max(xmax,value); | |
382 | } | |
383 | } | |
384 | } | |
385 | } | |
386 | ||
387 | } | |
388 |