Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[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
3d1463c8 18//-----------------------------------------------------------------------------
97d7844b 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
3d1463c8 39//-----------------------------------------------------------------------------
97d7844b 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
55ClassImp(AliMUONDigitStoreVImpl)
56/// \endcond
57
58namespace
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//_____________________________________________________________________________
82AliMUONDigitStoreVImpl::AliMUONDigitStoreVImpl(const char* concreteClassName)
83: AliMUONVDigitStore(),
84 fDigits(new TClonesArray(concreteClassName,100)),
85 fMap(0x0),
86 fIndexed(kFALSE)
87{
88 /// ctor
89}
90
91//_____________________________________________________________________________
92AliMUONDigitStoreVImpl::AliMUONDigitStoreVImpl(const AliMUONDigitStoreVImpl&)
93: AliMUONVDigitStore(),
94fDigits(0x0),
95fMap(0x0),
96fIndexed(kFALSE)
97{
98 /// copy ctor
99 AliError("Please implement me");
100}
101
102//_____________________________________________________________________________
103AliMUONDigitStoreVImpl&
104AliMUONDigitStoreVImpl::operator=(const AliMUONDigitStoreVImpl&)
105{
106 /// assignement operator
107 AliError("Please implement me");
108 return *this;
109}
110
111
112//_____________________________________________________________________________
113AliMUONDigitStoreVImpl::~AliMUONDigitStoreVImpl()
114{
115 /// dtor
116 delete fDigits;
117 delete fMap;
118}
119
120//_____________________________________________________________________________
121Bool_t
122AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
147void
148AliMUONDigitStoreVImpl::Clear(Option_t*)
149{
150 /// Clear the internal digit array AND the index
151 fDigits->Clear("C");
152 ClearIndex();
153}
154
155//_____________________________________________________________________________
156void
157AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
172AliMUONVDigit*
173AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
212TIterator*
213AliMUONDigitStoreVImpl::CreateIterator() const
214{
215 /// Create an iterator over the full store
216 return fDigits->MakeIterator();
217}
218
219//_____________________________________________________________________________
220TIterator*
221AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
232TIterator*
233AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
243TIterator*
244AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
253AliMUONVDigit*
254AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
266void
267AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
289void
290AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
311Int_t
312AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
330Int_t
331AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
340AliMUONVDigit*
341AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
352AliMUONVDigit*
353AliMUONDigitStoreVImpl::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//_____________________________________________________________________________
371Int_t
372AliMUONDigitStoreVImpl::GetSize() const
373{
374 /// Return the number of digits we hold
375 return fDigits->GetLast()+1;
376}
377
378//_____________________________________________________________________________
379AliMUONVDigit*
380AliMUONDigitStoreVImpl::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