Fix histo name
[u/mrichter/AliRoot.git] / MUON / AliMUONPadStatusMapMaker.cxx
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 }