]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONDigitStoreV1.cxx
Fixes for #86279 Improper usage of TClonesArrays in MUON
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitStoreV1.cxx
CommitLineData
4d3f0fd0 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#include "AliMUONDigitStoreV1.h"
19
3d1463c8 20//-----------------------------------------------------------------------------
4d3f0fd0 21/// \class AliMUONDigitStoreV1
22///
23/// (Legacy) Implementation of AliMUONVDigitStore.
24/// Called legacy as the internal structure corresponds to what we
25/// used to write as MUON.(S)Digits.root files, before the switch
26/// to data stores.
27///
28// \author Laurent Aphecetche, Subatech
3d1463c8 29//-----------------------------------------------------------------------------
4d3f0fd0 30
31#include "AliLog.h"
32#include "AliMUONDigit.h"
33#include "AliMUONDigitStoreV1Iterator.h"
34#include "AliMUONTOTCAStoreIterator.h"
35#include "AliMUONTreeManager.h"
36#include "AliMpConstants.h"
37#include "AliMpDEManager.h"
38#include "AliMpDEManager.h"
39#include "AliMpStationType.h"
40#include <Riostream.h>
41#include <TClonesArray.h>
42#include <TObjArray.h>
43#include <TTree.h>
44
45/// \cond CLASSIMP
46ClassImp(AliMUONDigitStoreV1)
47/// \endcond
48
49namespace
50{
51 TString BaseName(const TString& name)
52 {
53 if ( name == "TreeS" ) return "MUONSDigit";
54 if ( name == "TreeD" ) return "MUONDigit";
55 return "";
56 }
57}
58
59//_____________________________________________________________________________
60AliMUONDigitStoreV1::AliMUONDigitStoreV1()
61: AliMUONVDigitStore(),
62fDigits(new TObjArray(AliMpConstants::NofChambers())),
63fChamberDigits(0x0)
64{
65 /// ctor
66 fDigits->SetOwner(kTRUE);
67 for ( Int_t i = 0; i < fDigits->GetSize(); ++i )
68 {
69 TClonesArray* tca = new TClonesArray("AliMUONDigit",100);
70 tca->SetOwner(kTRUE);
71 fDigits->AddAt(tca,i);
72 }
73 Clear();
74 AliDebug(1,"");
75}
76
77//_____________________________________________________________________________
78AliMUONDigitStoreV1::AliMUONDigitStoreV1(const AliMUONDigitStoreV1&)
79: AliMUONVDigitStore(),
80fDigits(0x0),
81fChamberDigits(0x0)
82{
83 /// copy ctor
84 AliError("Please implement me");
85}
86
87//_____________________________________________________________________________
88AliMUONDigitStoreV1&
89AliMUONDigitStoreV1::operator=(const AliMUONDigitStoreV1&)
90{
91 /// assignement operator
92 AliError("Please implement me");
93 return *this;
94}
95
96//_____________________________________________________________________________
97AliMUONDigitStoreV1::~AliMUONDigitStoreV1()
98{
99 /// dtor
100 delete fDigits;
101}
102
103
104//_____________________________________________________________________________
105void
106AliMUONDigitStoreV1::Clear(Option_t* /*opt*/)
107{
108 /// Clear the tclonesarray, but keep the tobjarray's size constant.
109
110 for ( Int_t i = 0; i <= fDigits->GetLast(); ++i )
111 {
112 ChamberDigits(i)->Clear("C");
113 }
114}
115
116//_____________________________________________________________________________
117AliMUONVDigit*
118AliMUONDigitStoreV1::Add(const AliMUONVDigit& vdigit, EReplacePolicy replace)
119{
120 /// Try to add a digit to the store. Return whether the try was successfull
121 /// or not.
122 ///
123 /// If the digit is already there, the action taken depends on "replace"
124 /// kAllow -> replacement will occur (i.e. return kTRUE)
125 /// kDeny -> replacement will *not* occur (and returned value is kFALSE)
126 /// kMerge -> both digits will be merged into one (return kTRUE)
127 ///
128
129 const AliMUONDigit* digit = dynamic_cast<const AliMUONDigit*>(&vdigit);
130
131 if (!digit)
132 {
133 AliError(Form("Digit is not of the expected type (%s vs AliMUONdigit)",
134 vdigit.ClassName()));
135 return 0x0;
136 }
137
138 Int_t index(-1);
139
140 if ( replace != kIgnore )
141 {
142 AliMUONVDigit* alreadyThere = Find(*digit,index);
143
144 if ( alreadyThere )
145 {
146 if ( replace == kDeny )
147 {
148 return 0x0;
149 }
150 if ( replace == kMerge )
151 {
152 alreadyThere->MergeWith(*digit);
153 return alreadyThere;
154 }
155 }
156 }
157
158 Int_t detElemId = digit->DetElemId();
159 Int_t iChamber = AliMpDEManager::GetChamberId(detElemId);
160 TClonesArray* array = ChamberDigits(iChamber);
161 if ( index < 0 )
162 {
163 index = array->GetLast()+1;
164 }
165 return (new((*array)[index]) AliMUONDigit(*digit));
166}
167
168//_____________________________________________________________________________
169Bool_t
170AliMUONDigitStoreV1::Connect(TTree& tree, Bool_t alone) const
171{
172 /// Connect this to the tree.
173
174 AliMUONTreeManager tman;
175 Bool_t ok(kTRUE);
176
177 TString baseName(BaseName(tree.GetName()));
178
179 // Search for branch MUON(S)Digits1 to know if we need to set branch addresses
180 // or to make them.
181 TBranch* branch = tree.GetBranch(Form("%ss%d",baseName.Data(),1));
182
183 Bool_t isMaking = (branch==0);
184
185 if ( isMaking )
186 {
187 for ( Int_t i = 0; i < AliMpConstants::NofChambers(); ++i )
188 {
189 TString branchName(Form("%ss%d",baseName.Data(),i+1));
190 ok = ok && tman.MakeBranch(tree,ClassName(),"TClonesArray",
191 branchName.Data(),ChamberDigitsPtr(i));
192 }
193 }
194 else
195 {
196 if ( alone && baseName != "MUONSDigit" )
197 {
198 // TreeS only has digits, so there's not need to play the branch status
199 // game
200 tman.UpdateBranchStatuses(tree,baseName.Data());
201 }
202 for ( Int_t i = 0; i < AliMpConstants::NofChambers(); ++i )
203 {
204 TString branchName(Form("%ss%d",baseName.Data(),i+1));
205 ok = ok && tman.SetAddress(tree,branchName.Data(),ChamberDigitsPtr(i));
206 }
207 }
208
209 return ok;
210}
211
212//_____________________________________________________________________________
213TObject**
214AliMUONDigitStoreV1::ChamberDigitsPtr(Int_t chamberId) const
215{
216 /// Get the address of the TClonesArray storing digits for chamberId.
217
4d3f0fd0 218 TObject* object = fDigits->At(chamberId);
219
220 if (!object)
221 {
222 AliError(Form("Cannot get digits for chamberId=%d",chamberId));
223 return 0x0;
224 }
225 else
226 {
227 return fDigits->GetObjectRef(object);
228 }
229}
230
231//_____________________________________________________________________________
232TClonesArray*
233AliMUONDigitStoreV1::ChamberDigits(Int_t chamberId)
234{
235 /// Returns the tclonesarray storing digits for chamberId
236 return static_cast<TClonesArray*>(fDigits->At(chamberId));
237}
238
239//_____________________________________________________________________________
240const TClonesArray*
241AliMUONDigitStoreV1::ChamberDigits(Int_t chamberId) const
242{
243 /// Returns the tclonesarray storing digits for chamberId
244 return static_cast<TClonesArray*>(fDigits->At(chamberId));
245}
246
247//_____________________________________________________________________________
248AliMUONVDigit*
249AliMUONDigitStoreV1::CreateDigit(Int_t detElemId, Int_t manuId,
250 Int_t manuChannel, Int_t cathode) const
251{
252 return new AliMUONDigit(detElemId,manuId,manuChannel,cathode);
253}
254
255//_____________________________________________________________________________
256AliMUONVDigit*
257AliMUONDigitStoreV1::Remove(AliMUONVDigit& digit)
258{
259 /// Remove one digit, and returns it, thus returning 0x0 if digit
260 /// is not present.
261
262 Int_t index;
263 AliMUONVDigit* d(0x0);
02ab99ac 264 if ( ( d = FindIndex(digit.DetElemId(),digit.ManuId(),
265 digit.ManuChannel(),digit.Cathode(),index) ) )
4d3f0fd0 266 {
267 Int_t iChamber = AliMpDEManager::GetChamberId(digit.DetElemId());
268 TClonesArray* array = ChamberDigits(iChamber);
269 array->RemoveAt(index);
270 array->Compress();
271 }
272 return d;
273}
274
4d3f0fd0 275//_____________________________________________________________________________
276AliMUONVDigit*
277AliMUONDigitStoreV1::Find(const AliMUONVDigit& digit, Int_t& index) const
278{
279 /// Find a digit, and return its index.
02ab99ac 280 return FindIndex(digit.DetElemId(),digit.ManuId(),digit.ManuChannel(),digit.Cathode(),index);
4d3f0fd0 281}
282
283//_____________________________________________________________________________
284AliMUONVDigit*
02ab99ac 285AliMUONDigitStoreV1::FindObject(Int_t detElemId, Int_t manuId,
286 Int_t manuChannel, Int_t cathode) const
4d3f0fd0 287{
288 /// Find a (trigger) digit
289 Int_t index;
02ab99ac 290 return FindIndex(detElemId,manuId,manuChannel,cathode,index);
4d3f0fd0 291}
292
293//_____________________________________________________________________________
294AliMUONVDigit*
02ab99ac 295AliMUONDigitStoreV1::FindIndex(Int_t detElemId, Int_t manuId,
296 Int_t manuChannel, Int_t cathode, Int_t& index) const
4d3f0fd0 297{
02ab99ac 298 /// Find and return the index of a digit
4d3f0fd0 299
4d3f0fd0 300 Int_t iChamber = AliMpDEManager::GetChamberId(detElemId);
301 const TClonesArray* array = ChamberDigits(iChamber);
302 if (!array) return 0x0;
303 TIter next(array);
304 AliMUONVDigit* digit;
305 index=0;
306 while ( ( digit = static_cast<AliMUONVDigit*>(next()) ) )
307 {
308 if ( digit->DetElemId() == detElemId &&
02ab99ac 309 digit->ManuId() == manuId &&
310 digit->ManuChannel() == manuChannel &&
4d3f0fd0 311 digit->Cathode() == cathode )
312 {
313 return digit;
314 }
315 ++index;
316 }
317 return 0x0;
318
319}
320
4d3f0fd0 321//_____________________________________________________________________________
322TIterator*
323AliMUONDigitStoreV1::CreateIterator() const
324{
325 /// Return an iterator on the full store
326 return new AliMUONTOTCAStoreIterator(fDigits,0,13);
327}
328
329//_____________________________________________________________________________
330TIterator*
331AliMUONDigitStoreV1::CreateTrackerIterator() const
332{
333 /// Return an iterator on the tracker part of the store
334 return new AliMUONTOTCAStoreIterator(fDigits,0,9);
335}
336
337//_____________________________________________________________________________
338TIterator*
339AliMUONDigitStoreV1::CreateTriggerIterator() const
340{
341 /// Return an iterator on the trigger part of the store
342 return new AliMUONTOTCAStoreIterator(fDigits,10,13);
343}
344
345//_____________________________________________________________________________
346TIterator*
347AliMUONDigitStoreV1::CreateIterator(Int_t firstDetElemId, Int_t lastDetElemId,
348 Int_t cathode) const
349{
350 /// Return an iterator on part of the store
351 return new AliMUONDigitStoreV1Iterator(fDigits,firstDetElemId,lastDetElemId,cathode);
352}
353
354//_____________________________________________________________________________
355Int_t
356AliMUONDigitStoreV1::GetSize() const
357{
358 /// Return the number of digits we store
359 Int_t n(0);
360
361 for ( Int_t i = 0; i <= fDigits->GetLast(); ++i )
362 {
363 n += ChamberDigits(i)->GetEntries();
364 }
365 return n;
366}
91b67b6f 367
368//_____________________________________________________________________________
369Bool_t
370AliMUONDigitStoreV1::HasMCInformation() const
371{
372 /// As this class is legacy, don't care about looping and loosing a bit of
373 /// time...
374 TIter next(CreateIterator());
375 AliMUONVDigit* digit;
376 while ( ( digit = static_cast<AliMUONVDigit*>(next()) ) )
377 {
378 if ( digit->HasMCInformation() ) return kTRUE;
379 }
380 return kFALSE;
381}
382