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 : //-----------------------------------------------------------------------------
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, lv,
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 18 : 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 2 : : TObject(),
88 2 : fkStatusMaker(padStatusMaker),
89 2 : fMask(mask),
90 6 : fStatusMap(new AliMUON2DMap(true)),
91 6 : fRejectProbabilities(new AliMUON2DMap(true)),
92 2 : fRejectList(0x0),
93 2 : fComputeOnDemand(deferredInitialization)
94 6 : {
95 : /// ctor
96 2 : if (!deferredInitialization)
97 : {
98 0 : AliCodeTimerAuto("Computing complete status map at once",0);
99 0 : AliMUONVStore* neighboursStore = padStatusMaker.NeighboursStore();
100 : AliMUONVCalibParam* param;
101 0 : TIter next(neighboursStore->CreateIterator());
102 0 : while ( ( param = static_cast<AliMUONVCalibParam*>(next()) ) )
103 : {
104 0 : Int_t detElemId = param->ID0();
105 0 : Int_t manuId = param->ID1();
106 0 : ComputeStatusMap(detElemId,manuId);
107 : }
108 0 : }
109 :
110 : /// Whatever the deferred flag is, we *have* to compute the reject
111 : /// probabilities here and now, for *all* channels.
112 :
113 2 : AliMUONRejectList* rl = padStatusMaker.CalibrationData().RejectList();
114 :
115 2 : if (rl)
116 : {
117 2 : AliMpManuIterator it;
118 2 : Int_t detElemId;
119 2 : Int_t manuId;
120 :
121 100974 : while ( it.Next(detElemId,manuId) )
122 : {
123 67312 : AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
124 67312 : Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
125 :
126 100968 : AliMUONVCalibParam* param = new AliMUONCalibParamNF(1,AliMpConstants::ManuNofChannels(),detElemId,manuId,0);
127 :
128 : Int_t n(0);
129 :
130 4375280 : for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i )
131 : {
132 : Float_t proba(0.0);
133 :
134 4307968 : if ( de->IsConnectedChannel(manuId,i) )
135 : {
136 6384048 : proba = TMath::Max(rl->DetectionElementProbability(detElemId),rl->BusPatchProbability(busPatchId));
137 :
138 4256032 : proba = TMath::Max(proba,rl->ManuProbability(detElemId,manuId));
139 :
140 4256032 : proba = TMath::Max(proba,rl->ChannelProbability(detElemId,manuId,i));
141 :
142 2128016 : if ( proba > 0 )
143 : {
144 0 : ++n;
145 0 : param->SetValueAsFloat(i,0,proba);
146 : }
147 : }
148 : }
149 :
150 33656 : if ( n > 0 )
151 : {
152 0 : fRejectProbabilities->Add(param);
153 : }
154 : else
155 : {
156 : // no need to add empty stuff...
157 67312 : delete param;
158 : }
159 : }
160 :
161 2 : if ( rl->IsBinary())
162 : {
163 2 : fRejectList = fRejectProbabilities;
164 2 : fRejectProbabilities = 0x0;
165 10 : AliDebug(1,"RejectList = RejectProbabilities");
166 8 : StdoutToAliDebug(1,fRejectList->Print("","MEAN"));
167 2 : }
168 : else
169 : {
170 0 : AliWarning("Will run with non trivial survival probabilities for channels, manus, etc... Better check this is a simulation and not real data !");
171 0 : fRejectList = new AliMUON2DMap(true);
172 : }
173 2 : }
174 : else
175 : {
176 0 : fRejectList = fRejectProbabilities;
177 0 : fRejectProbabilities = 0x0;
178 0 : AliInfo("No RejectList found, so no RejectList will be used.");
179 : }
180 4 : }
181 :
182 : //_____________________________________________________________________________
183 : AliMUONPadStatusMapMaker::~AliMUONPadStatusMapMaker()
184 12 : {
185 : /// dtor
186 4 : delete fStatusMap;
187 2 : delete fRejectProbabilities;
188 4 : delete fRejectList;
189 6 : }
190 :
191 : //_____________________________________________________________________________
192 : AliMUONVCalibParam*
193 : AliMUONPadStatusMapMaker::ComputeStatusMap(Int_t detElemId, Int_t manuId) const
194 : {
195 : /// Compute the status map for a given manu, and add it to our internal
196 : /// fStatusMap internal storage
197 :
198 848 : AliCodeTimerAuto("(Int_t,Int_t)",0)
199 :
200 1272 : AliMUONVCalibParam* param = new AliMUONCalibParamNI(1,AliMpConstants::ManuNofChannels(),
201 : detElemId,manuId,-1);
202 :
203 848 : Bool_t ok = fStatusMap->Add(param);
204 424 : if (!ok)
205 : {
206 0 : AliFatal(Form("Could not add manu %d of de %d",manuId,detElemId));
207 : }
208 :
209 424 : AliMUONVCalibParam* neighbours = fkStatusMaker.Neighbours(detElemId,manuId);
210 :
211 424 : AliMUONVCalibParam* statusParam = fkStatusMaker.PadStatus(detElemId,manuId);
212 :
213 424 : Int_t n = neighbours->Dimension();
214 :
215 82680 : for ( Int_t manuChannel = 0; manuChannel < param->Size(); ++manuChannel )
216 : {
217 : Int_t statusMap(0);
218 :
219 27136 : Int_t x = neighbours->ValueAsIntFast(manuChannel,0);
220 27136 : if ( x < 0 )
221 : {
222 : // channel is not a valid one (i.e. (manuId,manuChannel) is not an existing pad)
223 : statusMap = -1;//fgkSelfDead;
224 160 : continue;
225 : }
226 :
227 647424 : for ( Int_t i = 0; i < n; ++i )
228 : {
229 : // Compute the statusmap related to the status of neighbouring
230 : // pads. An invalid pad means "outside of edges".
231 :
232 296736 : Int_t y = neighbours->ValueAsIntFast(manuChannel,i);
233 296736 : Int_t m,c;
234 296736 : neighbours->UnpackValue(y,m,c);
235 349516 : if ( c < 0 ) continue;
236 : Int_t status = 0;
237 243956 : if ( !m )
238 : {
239 : status = -1;
240 7570 : }
241 : else
242 : {
243 236386 : status = statusParam->ValueAsIntFast(c); //fkStatusMaker.PadStatus(detElemId,m,c);
244 : }
245 487912 : if ( ( fMask != 0 ) && ( (status & fMask) != 0 ) )
246 : {
247 7570 : statusMap |= (1<<i);
248 7570 : }
249 540692 : }
250 26976 : param->SetValueAsIntFast(manuChannel,0,statusMap);
251 26976 : }
252 : return param;
253 424 : }
254 :
255 : //_____________________________________________________________________________
256 : void
257 : AliMUONPadStatusMapMaker::RefreshRejectProbabilities()
258 : {
259 : /// From the (fixed) fRejectProbabilities, compute
260 : /// a fRejectList that will be valid for one event
261 : /// If fRejectProbabilities=0x0 it means we're dealing with
262 : /// trivial probabilities (0 or 1) and those are assumed to be already
263 : /// in fRejectList then.
264 :
265 16 : if ( !fRejectProbabilities ) return;
266 :
267 0 : AliCodeTimerAuto("",0);
268 :
269 0 : fRejectList->Clear();
270 :
271 0 : TIter next(fRejectProbabilities->CreateIterator());
272 : AliMUONVCalibParam* paramProba;
273 : AliMUONVCalibParam* paramReject;
274 :
275 0 : while ( ( paramProba = static_cast<AliMUONVCalibParam*>(next()) ) )
276 : {
277 0 : paramReject = new AliMUONCalibParamNF(1,paramProba->Size(),paramProba->ID0(),paramProba->ID1(),0.0);
278 :
279 : Int_t n(0);
280 :
281 0 : for ( Int_t i = 0; i < paramProba->Size(); ++i )
282 : {
283 0 : Float_t proba = paramProba->ValueAsFloat(i);
284 : Float_t x(proba);
285 :
286 0 : if ( proba > 0.0 && proba < 1.0 )
287 : {
288 0 : x = gRandom->Rndm();
289 0 : proba = ( x < proba ) ? 1.0 : 0.0;
290 0 : }
291 :
292 0 : if (proba>0.0)
293 : {
294 0 : ++n;
295 0 : paramReject->SetValueAsFloat(i,0,proba);
296 : }
297 : }
298 0 : if (n) fRejectList->Add(paramReject);
299 : }
300 8 : }
301 :
302 : //_____________________________________________________________________________
303 : Int_t
304 : AliMUONPadStatusMapMaker::StatusMap(Int_t detElemId, Int_t manuId,
305 : Int_t manuChannel) const
306 :
307 : {
308 : /// Get the pad status map
309 :
310 2832 : AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fStatusMap->FindObject(detElemId,manuId));
311 1416 : if (!param)
312 : {
313 424 : if ( fComputeOnDemand )
314 : {
315 : // not yet computed, so do it now
316 424 : param = ComputeStatusMap(detElemId,manuId);
317 : }
318 : else
319 : {
320 : // we're locked. probably a bad manuId ?
321 0 : return fgkSelfDead;
322 : }
323 424 : }
324 :
325 1416 : Int_t statusMap = param->ValueAsInt(manuChannel);
326 :
327 1416 : AliMUONVCalibParam* r = static_cast<AliMUONVCalibParam*>(fRejectList->FindObject(detElemId,manuId));
328 :
329 1416 : if (r)
330 : {
331 0 : Float_t v= r->ValueAsFloat(manuChannel);
332 :
333 0 : assert (v==0.0 || v==1.0 );
334 :
335 0 : if ( v > 0 )
336 : {
337 0 : statusMap |= fgkSelfDead;
338 0 : }
339 0 : }
340 :
341 : return statusMap;
342 :
343 1416 : }
|