]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONDigitStoreVImpl.cxx
No more misaligned_geometry
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitStoreVImpl.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 /// \class AliMUONDigitStoreVImpl
19 ///
20 /// Base implementation of VDigitStore, where digits are simply put
21 /// within a single TClonesArray (to get compact output on disk) and
22 /// fast search is achieved by using a separate index (a 2Dmap)
23 ///
24 /// Note that this class is a base implementation only, because to add
25 /// a digit to a TClonesArray, you need to give the concrete class
26 /// name (made in subclass by overriding :
27 ///
28 /// AliMUONVDigit* AddConcreteDigit(TClonesArray&,const AliMUONVDigit&, Int_t)
29 ///
30 /// and
31 ///
32 /// AliMUONVDigit* CreateDigit((Int_t detElemId, Int_t manuId,
33 /// Int_t manuChannel, Int_t cathode) const
34 /// 
35 /// methods.
36 ///
37 /// \author Laurent Aphecetche
38
39 #include "AliMUONDigitStoreVImpl.h"
40
41 #include "AliLog.h"
42 #include "AliMUONDigitStoreVImplIterator.h"
43 #include "AliMUON2DMap.h"
44 #include "AliMUONTreeManager.h"
45 #include "AliMUONCalibParamNI.h"
46 #include "AliMpConstants.h"
47 #include <TClonesArray.h>
48 #include <TTree.h>
49 #include <TString.h>
50 #include <Riostream.h>
51
52 /// \cond CLASSIMP
53 ClassImp(AliMUONDigitStoreVImpl)
54 /// \endcond
55
56 namespace
57 {
58   TString BaseName(const TString& name)
59   {
60     /// Name of the branch, depending on the tree name
61     if ( name == "TreeS" ) return "MUONSDigit";
62     if ( name == "TreeD" ) return "MUONDigit";
63     return "";
64   }
65   
66   Int_t InternalManuId(Int_t cathode, Int_t manuId)
67   {
68     /// Very local convention to insure that trigger digits are not
69     /// mixed (as by default a same manuId can be in cath 0 or 1, which
70     /// is never the case for tracker)
71     ///
72     /// WARNING : the resulting manuId must still be contained within 16 bits !
73     ///
74     return manuId | ( cathode << 15 );
75   }
76   
77 }
78
79 //_____________________________________________________________________________
80 AliMUONDigitStoreVImpl::AliMUONDigitStoreVImpl(const char* concreteClassName)
81 : AliMUONVDigitStore(),
82   fDigits(new TClonesArray(concreteClassName,100)),
83   fMap(0x0),
84   fIndexed(kFALSE)
85 {
86     /// ctor
87 }
88
89 //_____________________________________________________________________________
90 AliMUONDigitStoreVImpl::AliMUONDigitStoreVImpl(const AliMUONDigitStoreVImpl&)
91 : AliMUONVDigitStore(),
92 fDigits(0x0),
93 fMap(0x0),
94 fIndexed(kFALSE)
95 {
96   /// copy ctor
97   AliError("Please implement me");
98 }
99
100 //_____________________________________________________________________________
101 AliMUONDigitStoreVImpl& 
102 AliMUONDigitStoreVImpl::operator=(const AliMUONDigitStoreVImpl&)
103 {
104   /// assignement operator
105   AliError("Please implement me");
106   return *this;
107 }
108
109
110 //_____________________________________________________________________________
111 AliMUONDigitStoreVImpl::~AliMUONDigitStoreVImpl()
112 {
113   /// dtor
114   delete fDigits;
115   delete fMap;
116 }
117
118 //_____________________________________________________________________________
119 Bool_t 
120 AliMUONDigitStoreVImpl::Connect(TTree& tree, Bool_t alone) const
121 {
122   /// Connect this to the tree.
123   
124   TString branchName(BaseName(tree.GetName()));
125   branchName += ".";
126   AliMUONTreeManager tman;
127   Bool_t ok;
128   
129   if (tree.GetBranch(branchName.Data()))
130   {
131     if ( alone ) tman.UpdateBranchStatuses(tree,BaseName(tree.GetName()));
132     ok = tman.SetAddress(tree,branchName.Data(),
133                          const_cast<TClonesArray**>(&fDigits));
134   }
135   else
136   {
137     ok = tman.MakeBranch(tree,ClassName(),"TClonesArray",branchName.Data(),
138                          const_cast<TClonesArray**>(&fDigits));
139   }
140   
141   return ok;
142 }
143
144 //_____________________________________________________________________________
145 void 
146 AliMUONDigitStoreVImpl::Clear(Option_t*)
147 {
148   /// Clear the internal digit array AND the index
149   fDigits->Clear("C");
150   ClearIndex();
151 }
152
153 //_____________________________________________________________________________
154 void
155 AliMUONDigitStoreVImpl::ClearIndex()
156 {
157   /// Clear our internal index
158   if ( fMap ) 
159   {
160     fMap->Clear();
161   }
162   else
163   {
164     fMap = new AliMUON2DMap(true);
165   }
166   fIndexed = kFALSE;
167 }
168
169 //_____________________________________________________________________________
170 AliMUONVDigit* 
171 AliMUONDigitStoreVImpl::Add(const AliMUONVDigit& vdigit, EReplacePolicy replace)
172 {
173   /// Try to add a digit to the store. Return whether the try was successfull
174   /// or not.
175   /// 
176   /// If the digit is already there, the action taken depends on "replace"
177   /// kAllow -> replacement will occur (i.e. return kTRUE)
178   /// kDeny -> replacement will *not* occur (and returned value is kFALSE)
179   /// kMerge -> both digits will be merged into one (return kTRUE)
180   ///
181   
182   if ( replace != kIgnore )
183   {
184     AliMUONVDigit* alreadyThere = Find(vdigit);
185     if ( alreadyThere ) 
186     {
187       if ( replace == kDeny ) return 0x0;
188       if ( replace == kMerge )
189       {
190         alreadyThere->MergeWith(vdigit);
191         return alreadyThere;
192       }
193     }
194   }
195   
196   
197   Int_t n = fDigits->GetLast()+1;
198
199   AliMUONVDigit* d = AddConcreteDigit(*fDigits,vdigit,n);
200   
201   if ( d )
202   {
203     UpdateIndex(*d,n);
204   }
205   
206   return d;
207 }
208
209 //_____________________________________________________________________________
210 TIterator* 
211 AliMUONDigitStoreVImpl::CreateIterator() const
212 {
213   /// Create an iterator over the full store
214   return fDigits->MakeIterator();
215 }
216
217 //_____________________________________________________________________________
218 TIterator* 
219 AliMUONDigitStoreVImpl::CreateIterator(Int_t firstDetElemId, 
220                                     Int_t lastDetElemId,
221                                     Int_t cathode) const
222 {
223   /// Create an iterator on a given part of the store
224   (const_cast<AliMUONDigitStoreVImpl*>(this))->ReIndex();
225
226   return new AliMUONDigitStoreVImplIterator(this,firstDetElemId,lastDetElemId,cathode);
227 }
228
229 //_____________________________________________________________________________
230 TIterator*
231 AliMUONDigitStoreVImpl::CreateTrackerIterator() const
232 {
233   /// Create an iterator to loop over tracker digits only
234   
235   (const_cast<AliMUONDigitStoreVImpl*>(this))->ReIndex();
236
237   return new AliMUONDigitStoreVImplIterator(this,100,1025);
238 }
239
240 //_____________________________________________________________________________
241 TIterator* 
242 AliMUONDigitStoreVImpl::CreateTriggerIterator() const
243 {
244   /// Create an iterator to loop over trigger digits only
245   (const_cast<AliMUONDigitStoreVImpl*>(this))->ReIndex();
246
247   return new AliMUONDigitStoreVImplIterator(this,1100,1417);
248 }
249
250 //_____________________________________________________________________________
251 AliMUONVDigit* 
252 AliMUONDigitStoreVImpl::Find(const AliMUONVDigit& digit) const
253 {
254   /// Find a given digit
255   /// Note that we only check for the id of the digit (i.e. de,manu,...)
256   /// not for the actual content (charge, ...) to decide whether
257   /// it's the same digit or not
258   
259   return FindObject(digit.DetElemId(),digit.ManuId(),digit.ManuChannel(),
260                     digit.Cathode());
261 }
262
263 //_____________________________________________________________________________
264 void
265 AliMUONDigitStoreVImpl::ReIndex()
266 {
267   /// Recompute the fMap, which map (de,manu,ch) to an index within
268   /// the fDigits array
269   
270   if ( fIndexed ) return;
271   
272   ClearIndex();
273   
274   TIter next(fDigits);
275   AliMUONVDigit* d;
276   Int_t digitIndex(0);
277   
278   while ( ( d = static_cast<AliMUONVDigit*>(next()) ) )
279   {
280     UpdateIndex(*d,digitIndex++);
281   }
282   
283   fIndexed = kTRUE;
284 }
285
286 //_____________________________________________________________________________
287 void
288 AliMUONDigitStoreVImpl::UpdateIndex(const AliMUONVDigit& digit, Int_t index)
289 {
290   /// Update the internal index given this new digit
291   if (!fMap) fMap = new AliMUON2DMap(true);
292   
293   Int_t manuId = InternalManuId(digit.Cathode(),digit.ManuId());
294                         
295   AliMUONVCalibParam* param = 
296   static_cast<AliMUONVCalibParam*>
297   (fMap->FindObject(digit.DetElemId(),manuId));
298
299   if (!param)
300   {
301     param = new AliMUONCalibParamNI(1,64,digit.DetElemId(),manuId,-1);
302     fMap->Add(param);
303   }
304   param->SetValueAsInt(digit.ManuChannel(),0,index);
305   fIndexed = kTRUE;
306 }
307
308 //_____________________________________________________________________________
309 Int_t
310 AliMUONDigitStoreVImpl::FindIndex(Int_t detElemId, Int_t internalManuId,
311                                   Int_t manuChannel) const
312 {
313   /// Find the index of a given (de,internalManu,ch) triplet
314   
315   AliMUONVCalibParam* param = 
316   static_cast<AliMUONVCalibParam*>
317   (fMap->FindObject(detElemId,internalManuId));
318   
319   if (param)
320   {
321     return param->ValueAsInt(manuChannel);
322   }
323   
324   return -1;
325 }
326
327 //_____________________________________________________________________________
328 Int_t
329 AliMUONDigitStoreVImpl::FindIndex(const AliMUONVDigit& digit) const
330 {
331   /// Find the index of a given digit
332   return FindIndex(digit.DetElemId(),
333                    InternalManuId(digit.Cathode(),digit.ManuId()),
334                    digit.ManuChannel());
335 }
336
337 //_____________________________________________________________________________
338 AliMUONVDigit* 
339 AliMUONDigitStoreVImpl::FindObject(UInt_t uniqueID) const
340 {
341   /// Find digit by its uniqueID
342   
343   return FindObject(AliMUONVDigit::DetElemId(uniqueID),
344                     AliMUONVDigit::ManuId(uniqueID),
345                     AliMUONVDigit::ManuChannel(uniqueID),
346                     AliMUONVDigit::Cathode(uniqueID));
347 }
348
349 //_____________________________________________________________________________
350 AliMUONVDigit* 
351 AliMUONDigitStoreVImpl::FindObject(Int_t detElemId, Int_t manuId, Int_t manuChannel, 
352                                 Int_t cathode) const
353 {
354   /// Find a digit
355
356   (const_cast<AliMUONDigitStoreVImpl*>(this))->ReIndex();
357
358   Int_t index = FindIndex(detElemId,InternalManuId(cathode,manuId),manuChannel);
359   
360   if (index>=0 ) 
361   {
362     return static_cast<AliMUONVDigit*>(fDigits->UncheckedAt(index));
363   }
364   
365   return 0x0;
366 }
367
368 //_____________________________________________________________________________
369 Int_t 
370 AliMUONDigitStoreVImpl::GetSize() const
371 {
372   /// Return the number of digits we hold
373   return fDigits->GetLast()+1;
374 }
375
376 //_____________________________________________________________________________
377 AliMUONVDigit* 
378 AliMUONDigitStoreVImpl::Remove(AliMUONVDigit& digit)
379 {
380   /// Remove a digit
381   AliMUONVDigit* d = static_cast<AliMUONVDigit*>(fDigits->Remove(&digit));
382   if (d) 
383   {
384     UpdateIndex(*d,-1);
385   }
386   return d;
387 }
388