Line data Source code
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 18 : 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 60 : if ( name == "TreeS" ) return "MUONSDigit";
64 24 : if ( name == "TreeD" ) return "MUONDigit";
65 0 : return "";
66 24 : }
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 1039412 : return manuId | ( cathode << 15 );
77 : }
78 :
79 : }
80 :
81 : //_____________________________________________________________________________
82 : AliMUONDigitStoreVImpl::AliMUONDigitStoreVImpl(const char* concreteClassName)
83 22 : : AliMUONVDigitStore(),
84 66 : fDigits(new TClonesArray(concreteClassName,100)),
85 22 : fMap(0x0),
86 22 : fIndexed(kFALSE)
87 66 : {
88 : /// ctor
89 22 : }
90 :
91 : //_____________________________________________________________________________
92 : AliMUONDigitStoreVImpl::AliMUONDigitStoreVImpl(const AliMUONDigitStoreVImpl&)
93 0 : : AliMUONVDigitStore(),
94 0 : fDigits(0x0),
95 0 : fMap(0x0),
96 0 : fIndexed(kFALSE)
97 0 : {
98 : /// copy ctor
99 0 : AliError("Please implement me");
100 0 : }
101 :
102 : //_____________________________________________________________________________
103 : AliMUONDigitStoreVImpl&
104 : AliMUONDigitStoreVImpl::operator=(const AliMUONDigitStoreVImpl&)
105 : {
106 : /// assignement operator
107 0 : AliError("Please implement me");
108 0 : return *this;
109 : }
110 :
111 :
112 : //_____________________________________________________________________________
113 : AliMUONDigitStoreVImpl::~AliMUONDigitStoreVImpl()
114 44 : {
115 : /// dtor
116 44 : delete fDigits;
117 43 : delete fMap;
118 22 : }
119 :
120 : //_____________________________________________________________________________
121 : Bool_t
122 : AliMUONDigitStoreVImpl::Connect(TTree& tree, Bool_t alone) const
123 : {
124 : /// Connect this to the tree.
125 :
126 40 : TString branchName(BaseName(tree.GetName()));
127 20 : branchName += ".";
128 20 : AliMUONTreeManager tman;
129 : Bool_t ok;
130 :
131 60 : if (tree.GetBranch(branchName.Data()))
132 : {
133 36 : if ( alone ) tman.UpdateBranchStatuses(tree,BaseName(tree.GetName()));
134 36 : ok = tman.SetAddress(tree,branchName.Data(),
135 12 : const_cast<TClonesArray**>(&fDigits));
136 12 : }
137 : else
138 : {
139 32 : ok = tman.MakeBranch(tree,ClassName(),"TClonesArray",branchName.Data(),
140 8 : const_cast<TClonesArray**>(&fDigits));
141 : }
142 :
143 20 : return ok;
144 20 : }
145 :
146 : //_____________________________________________________________________________
147 : void
148 : AliMUONDigitStoreVImpl::Clear(Option_t*)
149 : {
150 : /// Clear the internal digit array AND the index
151 1466 : fDigits->Clear("C");
152 733 : ClearIndex();
153 733 : }
154 :
155 : //_____________________________________________________________________________
156 : void
157 : AliMUONDigitStoreVImpl::ClearIndex()
158 : {
159 : /// Clear our internal index
160 2926 : if ( fMap )
161 : {
162 1442 : fMap->Clear();
163 1442 : }
164 : else
165 : {
166 42 : fMap = new AliMUON2DMap(true);
167 : }
168 1463 : fIndexed = kFALSE;
169 1463 : }
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 491920 : if ( replace != kIgnore )
185 : {
186 245140 : AliMUONVDigit* alreadyThere = Find(vdigit);
187 245140 : if ( alreadyThere )
188 : {
189 72343 : if ( replace == kDeny ) return 0x0;
190 5 : if ( replace == kMerge )
191 : {
192 5 : alreadyThere->MergeWith(vdigit);
193 5 : return alreadyThere;
194 : }
195 : }
196 208966 : }
197 :
198 :
199 209786 : Int_t n = fDigits->GetLast()+1;
200 :
201 209786 : AliMUONVDigit* d = AddConcreteDigit(*fDigits,vdigit,n);
202 :
203 209786 : if ( d )
204 : {
205 209786 : UpdateIndex(*d,n);
206 209786 : }
207 :
208 : return d;
209 245960 : }
210 :
211 : //_____________________________________________________________________________
212 : TIterator*
213 : AliMUONDigitStoreVImpl::CreateIterator() const
214 : {
215 : /// Create an iterator over the full store
216 46 : 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 0 : (const_cast<AliMUONDigitStoreVImpl*>(this))->ReIndex();
227 :
228 0 : return new AliMUONDigitStoreVImplIterator(this,firstDetElemId,lastDetElemId,cathode);
229 0 : }
230 :
231 : //_____________________________________________________________________________
232 : TIterator*
233 : AliMUONDigitStoreVImpl::CreateTrackerIterator() const
234 : {
235 : /// Create an iterator to loop over tracker digits only
236 :
237 24 : (const_cast<AliMUONDigitStoreVImpl*>(this))->ReIndex();
238 :
239 24 : return new AliMUONDigitStoreVImplIterator(this,100,1025);
240 0 : }
241 :
242 : //_____________________________________________________________________________
243 : TIterator*
244 : AliMUONDigitStoreVImpl::CreateTriggerIterator() const
245 : {
246 : /// Create an iterator to loop over trigger digits only
247 1898 : (const_cast<AliMUONDigitStoreVImpl*>(this))->ReIndex();
248 :
249 1898 : return new AliMUONDigitStoreVImplIterator(this,1100,1417);
250 0 : }
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 735420 : return FindObject(digit.DetElemId(),digit.ManuId(),digit.ManuChannel(),
262 245140 : 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 618482 : if ( fIndexed ) return;
273 :
274 730 : ClearIndex();
275 :
276 730 : TIter next(fDigits);
277 : AliMUONVDigit* d;
278 : Int_t digitIndex(0);
279 :
280 5470 : while ( ( d = static_cast<AliMUONVDigit*>(next()) ) )
281 : {
282 1640 : UpdateIndex(*d,digitIndex++);
283 : }
284 :
285 730 : fIndexed = kTRUE;
286 309971 : }
287 :
288 : //_____________________________________________________________________________
289 : void
290 : AliMUONDigitStoreVImpl::UpdateIndex(const AliMUONVDigit& digit, Int_t index)
291 : {
292 : /// Update the internal index given this new digit
293 422852 : if (!fMap) fMap = new AliMUON2DMap(true);
294 :
295 211426 : Int_t manuId = InternalManuId(digit.Cathode(),digit.ManuId());
296 :
297 : AliMUONVCalibParam* param =
298 211426 : static_cast<AliMUONVCalibParam*>
299 211426 : (fMap->FindObject(digit.DetElemId(),manuId));
300 :
301 211426 : if (!param)
302 : {
303 47844 : param = new AliMUONCalibParamNI(1,64,digit.DetElemId(),manuId,-1);
304 15948 : fMap->Add(param);
305 15948 : }
306 211426 : param->SetValueAsInt(digit.ManuChannel(),0,index);
307 211426 : fIndexed = kTRUE;
308 211426 : }
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 308280 : static_cast<AliMUONVCalibParam*>
319 616560 : (fMap->FindObject(detElemId,internalManuId));
320 :
321 308280 : if (param)
322 : {
323 293196 : return param->ValueAsInt(manuChannel);
324 : }
325 :
326 15084 : return -1;
327 308280 : }
328 :
329 : //_____________________________________________________________________________
330 : Int_t
331 : AliMUONDigitStoreVImpl::FindIndex(const AliMUONVDigit& digit) const
332 : {
333 : /// Find the index of a given digit
334 0 : return FindIndex(digit.DetElemId(),
335 0 : InternalManuId(digit.Cathode(),digit.ManuId()),
336 0 : digit.ManuChannel());
337 : }
338 :
339 : //_____________________________________________________________________________
340 : AliMUONVDigit*
341 : AliMUONDigitStoreVImpl::FindObject(UInt_t uniqueID) const
342 : {
343 : /// Find digit by its uniqueID
344 :
345 0 : return FindObject(AliMUONVDigit::DetElemId(uniqueID),
346 0 : AliMUONVDigit::ManuId(uniqueID),
347 0 : AliMUONVDigit::ManuChannel(uniqueID),
348 0 : 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 616560 : (const_cast<AliMUONDigitStoreVImpl*>(this))->ReIndex();
359 :
360 308280 : Int_t index = FindIndex(detElemId,InternalManuId(cathode,manuId),manuChannel);
361 :
362 308280 : if (index>=0 )
363 : {
364 99314 : return static_cast<AliMUONVDigit*>(fDigits->UncheckedAt(index));
365 : }
366 :
367 208966 : return 0x0;
368 308280 : }
369 :
370 : //_____________________________________________________________________________
371 : Int_t
372 : AliMUONDigitStoreVImpl::GetSize() const
373 : {
374 : /// Return the number of digits we hold
375 0 : return fDigits->GetLast()+1;
376 : }
377 :
378 : //_____________________________________________________________________________
379 : AliMUONVDigit*
380 : AliMUONDigitStoreVImpl::Remove(AliMUONVDigit& digit)
381 : {
382 : /// Remove a digit
383 0 : AliMUONVDigit* d = static_cast<AliMUONVDigit*>(fDigits->Remove(&digit));
384 0 : if (d)
385 : {
386 0 : UpdateIndex(*d,-1);
387 0 : }
388 0 : return d;
389 : }
390 :
|