]>
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 | //----------------------------------------------------------------------------- | |
19 | /// \class AliMUONPadStatusMapMaker | |
20 | /// | |
21 | /// Convert a pad statuses into pad status maps. | |
22 | /// | |
23 | /// A pad status is one 32-bits word describing whether this pad pedestal, gains | |
24 | /// hv is correct or not. | |
25 | /// | |
26 | /// A pad status *map* is one 32-bits (of which 24 only are used) | |
27 | /// word describing whether this pad neighbours are ok or not | |
28 | /// (whether a pad is ok or not is determined by applying a given | |
29 | /// bitmask to the pad status word). Each bit in this word is related to one | |
30 | /// neighbour, assuming the pad itself is at bit 0 | |
31 | /// | |
32 | /// ---------------- | |
33 | /// | 3 | 5 | 8 | | |
34 | /// ---------------- | |
35 | /// | 2 | 0 | 7 | | |
36 | /// ---------------- | |
37 | /// | 1 | 4 | 6 | | |
38 | /// ---------------- | |
39 | /// | |
40 | /// Note that for instance in NonBending plane of slats, at the boundaries | |
41 | /// between two pad densities, the pictures is a bit different, e.g. | |
42 | /// (bits in () are always zero) | |
43 | /// | |
44 | /// so some care must be taken when designing a mask to be tested ;-) if you | |
45 | /// want to go farther than immediate neighbours... | |
46 | /// | |
47 | /// If a pad is at a physical boundary, is will for sure have some bits at 1 | |
48 | /// (i.e. a non-existing neighbour is considered = bad). | |
49 | /// | |
50 | /// | |
51 | /// add something about the reject list/probabilities here... (LA) | |
52 | /// | |
53 | /// \author Laurent Aphecetche | |
54 | //----------------------------------------------------------------------------- | |
55 | ||
56 | #include "AliMUONPadStatusMapMaker.h" | |
57 | ||
58 | #include "AliCodeTimer.h" | |
59 | #include "AliLog.h" | |
60 | #include "AliMpDDLStore.h" | |
61 | #include "AliMpDetElement.h" | |
62 | #include "AliMpManuIterator.h" | |
63 | #include "AliMUON2DMap.h" | |
64 | #include "AliMUONCalibParamNF.h" | |
65 | #include "AliMUONCalibParamNI.h" | |
66 | #include "AliMUONCalibrationData.h" | |
67 | #include "AliMUONPadStatusMaker.h" | |
68 | #include "AliMUONRejectList.h" | |
69 | #include "AliMUONVCalibParam.h" | |
70 | #include "AliMUONVStore.h" | |
71 | #include "AliMpConstants.h" | |
72 | #include <Riostream.h> | |
73 | #include <TList.h> | |
74 | #include "TRandom.h" | |
75 | #include <cassert> | |
76 | ||
77 | /// \cond CLASSIMP | |
78 | ClassImp(AliMUONPadStatusMapMaker) | |
79 | /// \endcond | |
80 | ||
81 | Int_t AliMUONPadStatusMapMaker::fgkSelfDead = 1; | |
82 | ||
83 | //_____________________________________________________________________________ | |
84 | AliMUONPadStatusMapMaker::AliMUONPadStatusMapMaker(const AliMUONPadStatusMaker& padStatusMaker, | |
85 | Int_t mask, | |
86 | Bool_t deferredInitialization) | |
87 | : TObject(), | |
88 | fkStatusMaker(padStatusMaker), | |
89 | fMask(mask), | |
90 | fStatusMap(new AliMUON2DMap(true)), | |
91 | fRejectProbabilities(new AliMUON2DMap(true)), | |
92 | fRejectList(0x0) | |
93 | { | |
94 | /// ctor | |
95 | if (!deferredInitialization) | |
96 | { | |
97 | AliCodeTimerAuto("Computing complete status map at once"); | |
98 | AliMUONVStore* neighboursStore = padStatusMaker.NeighboursStore(); | |
99 | AliMUONVCalibParam* param; | |
100 | TIter next(neighboursStore->CreateIterator()); | |
101 | while ( ( param = static_cast<AliMUONVCalibParam*>(next()) ) ) | |
102 | { | |
103 | Int_t detElemId = param->ID0(); | |
104 | Int_t manuId = param->ID1(); | |
105 | ComputeStatusMap(detElemId,manuId); | |
106 | } | |
107 | } | |
108 | ||
109 | /// Whatever the deferred flag is, we *have* to compute the reject | |
110 | /// probabilities here and now, for *all* channels. | |
111 | ||
112 | AliMUONRejectList* rl = padStatusMaker.CalibrationData().RejectList(); | |
113 | ||
114 | if (rl) | |
115 | { | |
116 | AliMpManuIterator it; | |
117 | Int_t detElemId; | |
118 | Int_t manuId; | |
119 | ||
120 | while ( it.Next(detElemId,manuId) ) | |
121 | { | |
122 | AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId); | |
123 | Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId); | |
124 | ||
125 | AliMUONVCalibParam* param = new AliMUONCalibParamNF(1,AliMpConstants::ManuNofChannels(),detElemId,manuId,0); | |
126 | ||
127 | Int_t n(0); | |
128 | ||
129 | for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i ) | |
130 | { | |
131 | Float_t proba(0.0); | |
132 | ||
133 | if ( de->IsConnectedChannel(manuId,i) ) | |
134 | { | |
135 | proba = TMath::Max(rl->DetectionElementProbability(detElemId),rl->BusPatchProbability(busPatchId)); | |
136 | ||
137 | proba = TMath::Max(proba,rl->ManuProbability(detElemId,manuId)); | |
138 | ||
139 | proba = TMath::Max(proba,rl->ChannelProbability(detElemId,manuId,i)); | |
140 | ||
141 | if ( proba > 0 ) | |
142 | { | |
143 | ++n; | |
144 | param->SetValueAsFloat(i,0,proba); | |
145 | } | |
146 | } | |
147 | } | |
148 | ||
149 | if ( n > 0 ) | |
150 | { | |
151 | fRejectProbabilities->Add(param); | |
152 | } | |
153 | else | |
154 | { | |
155 | // no need to add empty stuff... | |
156 | delete param; | |
157 | } | |
158 | } | |
159 | ||
160 | if ( rl->IsBinary()) | |
161 | { | |
162 | fRejectList = fRejectProbabilities; | |
163 | fRejectProbabilities = 0x0; | |
164 | AliDebug(1,"RejectList = RejectProbabilities"); | |
165 | StdoutToAliDebug(1,fRejectList->Print("","MEAN")); | |
166 | } | |
167 | else | |
168 | { | |
169 | AliWarning("Will run with non trivial survival probabilities for channels, manus, etc... Better check this is a simulation and not real data !"); | |
170 | fRejectList = new AliMUON2DMap(true); | |
171 | } | |
172 | } | |
173 | else | |
174 | { | |
175 | fRejectList = fRejectProbabilities; | |
176 | fRejectProbabilities = 0x0; | |
177 | AliInfo("No RejectList found, so no RejectList will be used."); | |
178 | } | |
179 | } | |
180 | ||
181 | //_____________________________________________________________________________ | |
182 | AliMUONPadStatusMapMaker::~AliMUONPadStatusMapMaker() | |
183 | { | |
184 | /// dtor | |
185 | delete fStatusMap; | |
186 | delete fRejectProbabilities; | |
187 | delete fRejectList; | |
188 | } | |
189 | ||
190 | //_____________________________________________________________________________ | |
191 | AliMUONVCalibParam* | |
192 | AliMUONPadStatusMapMaker::ComputeStatusMap(Int_t detElemId, Int_t manuId) const | |
193 | { | |
194 | /// Compute the status map for a given manu, and add it to our internal | |
195 | /// fStatusMap internal storage | |
196 | ||
197 | AliCodeTimerAuto("(Int_t,Int_t)") | |
198 | ||
199 | AliMUONVCalibParam* param = new AliMUONCalibParamNI(1,AliMpConstants::ManuNofChannels(), | |
200 | detElemId,manuId,-1); | |
201 | ||
202 | Bool_t ok = fStatusMap->Add(param); | |
203 | if (!ok) | |
204 | { | |
205 | AliFatal(Form("Could not add manu %d of de %d",manuId,detElemId)); | |
206 | } | |
207 | ||
208 | AliMUONVCalibParam* neighbours = fkStatusMaker.Neighbours(detElemId,manuId); | |
209 | ||
210 | AliMUONVCalibParam* statusParam = fkStatusMaker.PadStatus(detElemId,manuId); | |
211 | ||
212 | Int_t n = neighbours->Dimension(); | |
213 | ||
214 | for ( Int_t manuChannel = 0; manuChannel < param->Size(); ++manuChannel ) | |
215 | { | |
216 | Int_t statusMap(0); | |
217 | ||
218 | Int_t x = neighbours->ValueAsIntFast(manuChannel,0); | |
219 | if ( x < 0 ) | |
220 | { | |
221 | // channel is not a valid one (i.e. (manuId,manuChannel) is not an existing pad) | |
222 | statusMap = -1;//fgkSelfDead; | |
223 | continue; | |
224 | } | |
225 | ||
226 | for ( Int_t i = 0; i < n; ++i ) | |
227 | { | |
228 | // Compute the statusmap related to the status of neighbouring | |
229 | // pads. An invalid pad means "outside of edges". | |
230 | ||
231 | Int_t y = neighbours->ValueAsIntFast(manuChannel,i); | |
232 | Int_t m,c; | |
233 | neighbours->UnpackValue(y,m,c); | |
234 | if ( c < 0 ) continue; | |
235 | Int_t status = 0; | |
236 | if ( !m ) | |
237 | { | |
238 | status = -1; | |
239 | } | |
240 | else | |
241 | { | |
242 | status = statusParam->ValueAsIntFast(c); //fkStatusMaker.PadStatus(detElemId,m,c); | |
243 | } | |
244 | if ( ( fMask==0 && status !=0 ) || ( (status & fMask) != 0 ) ) | |
245 | { | |
246 | statusMap |= (1<<i); | |
247 | } | |
248 | } | |
249 | param->SetValueAsIntFast(manuChannel,0,statusMap); | |
250 | } | |
251 | return param; | |
252 | } | |
253 | ||
254 | //_____________________________________________________________________________ | |
255 | void | |
256 | AliMUONPadStatusMapMaker::RefreshRejectProbabilities() | |
257 | { | |
258 | /// From the (fixed) fRejectProbabilities, compute | |
259 | /// a fRejectList that will be valid for one event | |
260 | /// If fRejectProbabilities=0x0 it means we're dealing with | |
261 | /// trivial probabilities (0 or 1) and those are assumed to be already | |
262 | /// in fRejectList then. | |
263 | ||
264 | if ( !fRejectProbabilities ) return; | |
265 | ||
266 | AliCodeTimerAuto(""); | |
267 | ||
268 | fRejectList->Clear(); | |
269 | ||
270 | TIter next(fRejectProbabilities->CreateIterator()); | |
271 | AliMUONVCalibParam* paramProba; | |
272 | AliMUONVCalibParam* paramReject; | |
273 | ||
274 | while ( ( paramProba = static_cast<AliMUONVCalibParam*>(next()) ) ) | |
275 | { | |
276 | paramReject = new AliMUONCalibParamNF(1,paramProba->Size(),paramProba->ID0(),paramProba->ID1(),0.0); | |
277 | ||
278 | Int_t n(0); | |
279 | ||
280 | for ( Int_t i = 0; i < paramProba->Size(); ++i ) | |
281 | { | |
282 | Float_t proba = paramProba->ValueAsFloat(i); | |
283 | Float_t x(proba); | |
284 | ||
285 | if ( proba > 0.0 && proba < 1.0 ) | |
286 | { | |
287 | x = gRandom->Rndm(); | |
288 | proba = ( x < proba ) ? 1.0 : 0.0; | |
289 | } | |
290 | ||
291 | if (proba>0.0) | |
292 | { | |
293 | ++n; | |
294 | paramReject->SetValueAsFloat(i,0,proba); | |
295 | } | |
296 | } | |
297 | if (n) fRejectList->Add(paramReject); | |
298 | } | |
299 | } | |
300 | ||
301 | //_____________________________________________________________________________ | |
302 | Int_t | |
303 | AliMUONPadStatusMapMaker::StatusMap(Int_t detElemId, Int_t manuId, | |
304 | Int_t manuChannel) const | |
305 | ||
306 | { | |
307 | /// Get the pad status map | |
308 | ||
309 | AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fStatusMap->FindObject(detElemId,manuId)); | |
310 | if (!param) | |
311 | { | |
312 | // not yet computed, so do it now | |
313 | param = ComputeStatusMap(detElemId,manuId); | |
314 | } | |
315 | ||
316 | Int_t statusMap = param->ValueAsInt(manuChannel); | |
317 | ||
318 | AliMUONVCalibParam* r = static_cast<AliMUONVCalibParam*>(fRejectList->FindObject(detElemId,manuId)); | |
319 | ||
320 | if (r) | |
321 | { | |
322 | Float_t v= r->ValueAsFloat(manuChannel); | |
323 | ||
324 | assert (v==0.0 || v==1.0 ); | |
325 | ||
326 | if ( v > 0 ) | |
327 | { | |
328 | statusMap |= fgkSelfDead; | |
329 | } | |
330 | } | |
331 | ||
332 | return statusMap; | |
333 | ||
334 | } |