Create the magnetic field map in the reconstruction macros (Yuri)
[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 /// \author Laurent Aphecetche
51 //-----------------------------------------------------------------------------
52
53 #include "AliMUONPadStatusMapMaker.h"
54
55 #include "AliLog.h"
56 #include "AliMUON2DMap.h"
57 #include "AliMUONCalibParamNI.h"
58 #include "AliMUONPadStatusMaker.h"
59 #include "AliMUONVStore.h"
60 #include "AliMUONVCalibParam.h"
61 #include "AliMpConstants.h"
62 #include <Riostream.h>
63 #include <TList.h>
64 #include "AliCodeTimer.h"
65
66 /// \cond CLASSIMP
67 ClassImp(AliMUONPadStatusMapMaker)
68 /// \endcond
69
70 Int_t AliMUONPadStatusMapMaker::fgkSelfDead = 1;
71
72 //_____________________________________________________________________________
73 AliMUONPadStatusMapMaker::AliMUONPadStatusMapMaker(const AliMUONPadStatusMaker& padStatusMaker,
74                                                    Int_t mask,
75                                                    Bool_t deferredInitialization) 
76 : TObject(),
77 fStatusMaker(padStatusMaker),
78 fMask(mask),
79 fStatusMap(new AliMUON2DMap(true))
80 {
81   /// ctor
82   if (!deferredInitialization)
83   {
84     AliCodeTimerAuto("Computing complete status map at once");
85     AliMUONVStore* neighboursStore = padStatusMaker.NeighboursStore();
86     AliMUONVCalibParam* param;
87     TIter next(neighboursStore->CreateIterator());
88     while ( ( param = static_cast<AliMUONVCalibParam*>(next()) ) )
89     {
90       Int_t detElemId = param->ID0();
91       Int_t manuId = param->ID1();
92       ComputeStatusMap(detElemId,manuId);
93     }
94   }
95 }
96
97 //_____________________________________________________________________________
98 AliMUONPadStatusMapMaker::~AliMUONPadStatusMapMaker()
99 {
100   /// dtor
101   delete fStatusMap;
102 }
103
104 //_____________________________________________________________________________
105 AliMUONVCalibParam*
106 AliMUONPadStatusMapMaker::ComputeStatusMap(Int_t detElemId, Int_t manuId) const
107 {
108   /// Compute the status map for a given manu, and add it to our internal
109   /// fStatusMap internal storage
110   
111   AliCodeTimerAuto("(Int_t,Int_t)")
112     
113   AliMUONVCalibParam* param = new AliMUONCalibParamNI(1,AliMpConstants::ManuNofChannels(),
114                                                       detElemId,manuId,-1);    
115                                     
116   Bool_t ok = fStatusMap->Add(param);
117   if (!ok)
118   {
119     AliFatal(Form("Could not add manu %d of de %d",manuId,detElemId));
120   }
121                                   
122   AliMUONVCalibParam* neighbours = fStatusMaker.Neighbours(detElemId,manuId);
123   
124   AliMUONVCalibParam* statusParam = fStatusMaker.PadStatus(detElemId,manuId);
125   
126   Int_t n = neighbours->Dimension();
127   
128   for ( Int_t manuChannel = 0; manuChannel < param->Size(); ++manuChannel )
129   {
130     Int_t statusMap(0);
131     
132     Int_t x = neighbours->ValueAsIntFast(manuChannel,0);
133     if ( x < 0 ) 
134     {
135       // channel is not a valid one (i.e. (manuId,manuChannel) is not an existing pad)
136       statusMap = -1;//fgkSelfDead;
137       continue;
138     }
139         
140     for ( Int_t i = 0; i < n; ++i )
141     {
142       // Compute the statusmap related to the status of neighbouring
143       // pads. An invalid pad means "outside of edges".
144             
145       Int_t x = neighbours->ValueAsIntFast(manuChannel,i);      
146       Int_t m,c;
147       neighbours->UnpackValue(x,m,c);
148       if ( c < 0 ) continue;
149       Int_t status = 0;
150       if ( !m )
151       {
152         status = -1;
153       }
154       else
155       {
156         status = statusParam->ValueAsIntFast(c); //fStatusMaker.PadStatus(detElemId,m,c);
157       }
158       if ( ( fMask==0 && status !=0 ) || ( (status & fMask) != 0 ) )
159       {
160         statusMap |= (1<<i);
161       }
162     }    
163     param->SetValueAsIntFast(manuChannel,0,statusMap);
164   }
165   return param;
166 }
167
168 //_____________________________________________________________________________
169 Int_t
170 AliMUONPadStatusMapMaker::StatusMap(Int_t detElemId, Int_t manuId, 
171                                     Int_t manuChannel) const
172                                       
173 {
174   /// Get the pad status map
175   
176   AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fStatusMap->FindObject(detElemId,manuId));
177   if (!param)
178   {
179     // not yet computed, so do it now
180     param = ComputeStatusMap(detElemId,manuId);
181   }
182   return param->ValueAsInt(manuChannel);
183 }