minor coverity defect: added protection for self-assignment
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitStoreV1.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 #include "AliMUONDigitStoreV1.h"
19
20 //-----------------------------------------------------------------------------
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
29 //-----------------------------------------------------------------------------
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
46 ClassImp(AliMUONDigitStoreV1)
47 /// \endcond
48
49 namespace
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 //_____________________________________________________________________________
60 AliMUONDigitStoreV1::AliMUONDigitStoreV1()
61 : AliMUONVDigitStore(), 
62 fDigits(new TObjArray(AliMpConstants::NofChambers())),
63 fChamberDigits(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 //_____________________________________________________________________________
78 AliMUONDigitStoreV1::AliMUONDigitStoreV1(const AliMUONDigitStoreV1&)
79 : AliMUONVDigitStore(), 
80 fDigits(0x0),
81 fChamberDigits(0x0)
82 {
83   /// copy ctor
84   AliError("Please implement me");
85 }
86
87 //_____________________________________________________________________________
88 AliMUONDigitStoreV1& 
89 AliMUONDigitStoreV1::operator=(const AliMUONDigitStoreV1&)
90 {
91   /// assignement operator
92   AliError("Please implement me");
93   return *this;
94 }
95
96 //_____________________________________________________________________________
97 AliMUONDigitStoreV1::~AliMUONDigitStoreV1()
98 {
99   /// dtor
100   delete fDigits;
101 }
102
103
104 //_____________________________________________________________________________
105 void 
106 AliMUONDigitStoreV1::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 //_____________________________________________________________________________
117 AliMUONVDigit* 
118 AliMUONDigitStoreV1::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 //_____________________________________________________________________________
169 Bool_t
170 AliMUONDigitStoreV1::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 //_____________________________________________________________________________
213 TObject**
214 AliMUONDigitStoreV1::ChamberDigitsPtr(Int_t chamberId) const
215 {
216   /// Get the address of the TClonesArray storing digits for chamberId.
217
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 //_____________________________________________________________________________
232 TClonesArray*
233 AliMUONDigitStoreV1::ChamberDigits(Int_t chamberId)
234 {
235   /// Returns the tclonesarray storing digits for chamberId
236   return static_cast<TClonesArray*>(fDigits->At(chamberId));
237 }
238
239 //_____________________________________________________________________________
240 const TClonesArray*
241 AliMUONDigitStoreV1::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 //_____________________________________________________________________________
248 AliMUONVDigit* 
249 AliMUONDigitStoreV1::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 //_____________________________________________________________________________
256 AliMUONVDigit* 
257 AliMUONDigitStoreV1::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);
264   if ( ( d = FindIndex(digit.DetElemId(),digit.ManuId(),
265                        digit.ManuChannel(),digit.Cathode(),index) ) )
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
275 //_____________________________________________________________________________
276 AliMUONVDigit* 
277 AliMUONDigitStoreV1::Find(const AliMUONVDigit& digit, Int_t& index) const
278 {
279   /// Find a digit, and return its index.
280   return FindIndex(digit.DetElemId(),digit.ManuId(),digit.ManuChannel(),digit.Cathode(),index);
281 }
282
283 //_____________________________________________________________________________
284 AliMUONVDigit* 
285 AliMUONDigitStoreV1::FindObject(Int_t detElemId, Int_t manuId, 
286                                 Int_t manuChannel, Int_t cathode) const
287 {
288   /// Find a (trigger) digit
289   Int_t index;
290   return FindIndex(detElemId,manuId,manuChannel,cathode,index);
291 }
292
293 //_____________________________________________________________________________
294 AliMUONVDigit* 
295 AliMUONDigitStoreV1::FindIndex(Int_t detElemId, Int_t manuId, 
296                                Int_t manuChannel, Int_t cathode, Int_t& index) const
297 {
298   /// Find and return the index of a digit
299   
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 &&
309          digit->ManuId() == manuId &&
310          digit->ManuChannel() == manuChannel &&
311          digit->Cathode() == cathode ) 
312     {
313       return digit;
314     }
315     ++index;
316   }
317   return 0x0;
318   
319 }
320
321 //_____________________________________________________________________________
322 TIterator* 
323 AliMUONDigitStoreV1::CreateIterator() const
324 {
325   /// Return an iterator on the full store
326   return new AliMUONTOTCAStoreIterator(fDigits,0,13);
327 }
328
329 //_____________________________________________________________________________
330 TIterator* 
331 AliMUONDigitStoreV1::CreateTrackerIterator() const
332 {
333   /// Return an iterator on the tracker part of the store
334   return new AliMUONTOTCAStoreIterator(fDigits,0,9);
335 }
336
337 //_____________________________________________________________________________
338 TIterator* 
339 AliMUONDigitStoreV1::CreateTriggerIterator() const
340 {
341   /// Return an iterator on the trigger part of the store
342   return new AliMUONTOTCAStoreIterator(fDigits,10,13);
343 }
344
345 //_____________________________________________________________________________
346 TIterator* 
347 AliMUONDigitStoreV1::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 //_____________________________________________________________________________
355 Int_t
356 AliMUONDigitStoreV1::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 }
367
368 //_____________________________________________________________________________
369 Bool_t 
370 AliMUONDigitStoreV1::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