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