]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONPadStatusMapMaker.cxx
No longer uses TObject::Clone default implementation as it turns out to be too slow...
[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 status container into a pad status *map* container
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 "AliMUONCalibrationData.h"
59 #include "AliMUONVStore.h"
60 #include "AliMUONVCalibParam.h"
61 #include "AliMpConstants.h"
62 #include "AliMpIntPair.h"
63 #include "AliMpManuList.h"
64 #include <Riostream.h>
65 #include <TList.h>
66 #include <TStopwatch.h>
67
68 /// \cond CLASSIMP
69 ClassImp(AliMUONPadStatusMapMaker)
70 /// \endcond
71
72 Int_t AliMUONPadStatusMapMaker::fgkSelfDead = 1;
73
74 //_____________________________________________________________________________
75 AliMUONPadStatusMapMaker::AliMUONPadStatusMapMaker(const AliMUONCalibrationData& calibData) 
76 : TObject(),
77 fStatus(0x0),
78 fMask(0),
79 fCalibrationData(calibData)
80 {
81   /// ctor
82 }
83
84 //_____________________________________________________________________________
85 AliMUONPadStatusMapMaker::~AliMUONPadStatusMapMaker()
86 {
87   /// dtor
88 }
89
90 //_____________________________________________________________________________
91 Int_t
92 AliMUONPadStatusMapMaker::ComputeStatusMap(const AliMUONVCalibParam& neighbours,
93                                           Int_t manuChannel,
94                                           Int_t detElemId) const
95 {
96   /// Given a list of neighbours of one pad (which includes the pad itself)
97   /// compute the status map (aka deadmap) for that pad.
98   
99   Int_t statusMap(0);
100
101   //Compute the statusmap related to the status of neighbouring
102   //pads. An invalid pad means "outside of edges".
103
104   Int_t n = neighbours.Dimension();
105   for ( Int_t i = 0; i < n; ++i )
106   {
107     Int_t x = neighbours.ValueAsInt(manuChannel,i);
108     Int_t m,c;
109     neighbours.UnpackValue(x,m,c);
110     if ( c < 0 ) continue;
111     Int_t status = 0;
112     if ( !m )
113     {
114       status = -1;
115     }
116     else
117     {
118       status = GetPadStatus(detElemId,m,c);
119     }
120     if ( ( fMask==0 && status !=0 ) || ( (status & fMask) != 0 ) )
121     {
122       statusMap |= (1<<i);
123     }
124   }
125   return statusMap;
126 }
127
128 //_____________________________________________________________________________
129 Int_t
130 AliMUONPadStatusMapMaker::GetPadStatus(Int_t detElemId, 
131                                        Int_t manuId, Int_t manuChannel) const
132                                       
133 {
134   /// Get the pad status
135   AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fStatus->FindObject(detElemId,manuId));
136   return param->ValueAsInt(manuChannel);
137 }
138
139 //_____________________________________________________________________________
140 AliMUONVStore*
141 AliMUONPadStatusMapMaker::MakeEmptyPadStatusMap()
142 {
143   /// Make an empty (but complete) statusMap
144     
145     AliMUONVStore* store = new AliMUON2DMap(true);
146     
147     TList* list = AliMpManuList::ManuList();
148     
149     AliMpIntPair* pair;
150     
151     TIter next(list);
152     
153     while ( ( pair = static_cast<AliMpIntPair*>(next()) ) ) 
154     {
155       Int_t detElemId = pair->GetFirst();
156       Int_t manuId = pair->GetSecond();
157       AliMUONVCalibParam* param = new AliMUONCalibParamNI(1,AliMpConstants::ManuNofChannels(),
158                                                           detElemId,manuId,
159                                                           0);
160       store->Add(param);
161     }
162     
163     delete list;
164     
165     return store;
166 }
167
168 //_____________________________________________________________________________
169 AliMUONVStore*
170 AliMUONPadStatusMapMaker::MakePadStatusMap(const AliMUONVStore& status,
171                                            Int_t mask)
172 {
173   /// Given the status store for all pads, compute a status map store
174   /// for all pads. 
175   /// \param status
176   /// \param mask is the status mask to be tested to tell if a pad is ok or not
177   
178   fStatus = &status;
179   fMask = mask;
180   
181   TStopwatch timer;  
182   timer.Start(kTRUE);
183   
184   AliMUONVStore* neighbourStore = fCalibrationData.Neighbours();
185   
186   AliMUONVStore* statusMap = status.Create();
187   
188   TIter next(status.CreateIterator());
189   AliMUONVCalibParam* statusEntry;
190   
191   while ( ( statusEntry = static_cast<AliMUONVCalibParam*>(next()) ) )
192   {
193     Int_t detElemId = statusEntry->ID0();
194     Int_t manuId = statusEntry->ID1();
195         
196     AliMUONVCalibParam* statusMapEntry = static_cast<AliMUONVCalibParam*>
197       (statusMap->FindObject(detElemId,manuId));
198
199     if (!statusMapEntry)
200     {
201       statusMapEntry = new AliMUONCalibParamNI(1,AliMpConstants::ManuNofChannels(),
202                                                detElemId,manuId,0);
203       statusMap->Add(statusMapEntry);
204     }
205     
206     AliMUONVCalibParam* neighbours = static_cast<AliMUONVCalibParam*>
207       (neighbourStore->FindObject(detElemId,manuId));
208     
209     if (!neighbours)
210     {
211       AliFatal(Form("Could not find neighbours for DE %d manuId %d",
212                     detElemId,manuId));
213       continue;
214     }
215     
216     for ( Int_t manuChannel = 0; manuChannel < statusEntry->Size(); ++manuChannel ) 
217     {
218       // Loop over channels and for each channel loop on its immediate neighbours
219       // to produce a statusMap word for this channel.
220       
221       Int_t statusMapValue(0);
222
223       Int_t x = neighbours->ValueAsInt(manuChannel,0);
224       
225       if ( x > 0 )
226       { 
227         // channel is a valid one (i.e. (manuId,manuChannel) is an existing pad)
228         statusMapValue = ComputeStatusMap(*neighbours,manuChannel,detElemId);
229       }
230       else
231       {
232         statusMapValue = fgkSelfDead;
233       }
234       
235       statusMapEntry->SetValueAsInt(manuChannel,0,statusMapValue);
236     }
237   }
238   timer.Stop();
239   
240   StdoutToAliInfo(
241                   cout << "MakePadStatusMap total timer : ";
242                   timer.Print();
243                   cout << endl;
244                   );
245
246   return statusMap;
247 }
248