More efficient implementation(s) of AliMUONVDigitStore (Laurent)
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitStoreVImpl.cxx
CommitLineData
97d7844b 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
53ClassImp(AliMUONDigitStoreVImpl)
54/// \endcond
55
56namespace
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//_____________________________________________________________________________
80AliMUONDigitStoreVImpl::AliMUONDigitStoreVImpl(const char* concreteClassName)
81: AliMUONVDigitStore(),
82 fDigits(new TClonesArray(concreteClassName,100)),
83 fMap(0x0),
84 fIndexed(kFALSE)
85{
86 /// ctor
87}
88
89//_____________________________________________________________________________
90AliMUONDigitStoreVImpl::AliMUONDigitStoreVImpl(const AliMUONDigitStoreVImpl&)
91: AliMUONVDigitStore(),
92fDigits(0x0),
93fMap(0x0),
94fIndexed(kFALSE)
95{
96 /// copy ctor
97 AliError("Please implement me");
98}
99
100//_____________________________________________________________________________
101AliMUONDigitStoreVImpl&
102AliMUONDigitStoreVImpl::operator=(const AliMUONDigitStoreVImpl&)
103{
104 /// assignement operator
105 AliError("Please implement me");
106 return *this;
107}
108
109
110//_____________________________________________________________________________
111AliMUONDigitStoreVImpl::~AliMUONDigitStoreVImpl()
112{
113 /// dtor
114 delete fDigits;
115 delete fMap;
116}
117
118//_____________________________________________________________________________
119Bool_t
120AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
145void
146AliMUONDigitStoreVImpl::Clear(Option_t*)
147{
148 /// Clear the internal digit array AND the index
149 fDigits->Clear("C");
150 ClearIndex();
151}
152
153//_____________________________________________________________________________
154void
155AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
170AliMUONVDigit*
171AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
210TIterator*
211AliMUONDigitStoreVImpl::CreateIterator() const
212{
213 /// Create an iterator over the full store
214 return fDigits->MakeIterator();
215}
216
217//_____________________________________________________________________________
218TIterator*
219AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
230TIterator*
231AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
241TIterator*
242AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
251AliMUONVDigit*
252AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
264void
265AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
287void
288AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
309Int_t
310AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
328Int_t
329AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
338AliMUONVDigit*
339AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
350AliMUONVDigit*
351AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
369Int_t
370AliMUONDigitStoreVImpl::GetSize() const
371{
372 /// Return the number of digits we hold
373 return fDigits->GetLast()+1;
374}
375
376//_____________________________________________________________________________
377AliMUONVDigit*
378AliMUONDigitStoreVImpl::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