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