Adding PiKP-only histograms and eliminating a number of switches where histograms...
[u/mrichter/AliRoot.git] / MUON / AliMUONVDigit.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 //-----------------------------------------------------------------------------
19 /// \class AliMUONVDigit
20 ///
21 /// This is the base class of a MUON digit that most client code should deal with.
22 /// There should be no reason to have to use a concrete class in most cases.
23 ///
24 /// All digits have basic features, like :
25 ///
26 /// - a way to identify it : detection element, electronics card and
27 ///   channel, cathode. Note that some static methods exists to compact 
28 ///   those 4 informations into a single 4 bytes integer (stored in the
29 ///   fUniqueID data member present in all TObjects). 
30 ///
31 /// - its charge
32 ///
33 /// - a set of boolean methods to indicate whether the digit has been calibrated, etc...
34 ///
35 /// In addition, if HasMCInformation is true, the digit store also the list
36 /// of MC tracks that contributed to its charge
37 ///
38 /// Also, if HasGeometryInformation is true, the digit knows the position and
39 /// the (half) dimensions (in cm) of the pad it corresponds to.
40 ///
41 /// Note 1.
42 ///
43 /// Please note that IsCalibrated and IsChargeInFC are two 
44 /// concepts closely related, but not equivalent, at least for SDigits.
45 ///
46 /// For instance a SDigit can have its charge in fC but not being calibrated.
47 ///
48 /// { SDigits coming from a simulation are yet to be merged (i.e. the
49 ///   SDigitStore can contain several SDigits objects per channel), so, while
50 ///   their charge is in femto-coulomb, they are not calibrated (e.g. pedestal
51 ///   is not subtracted yet). }
52 ///
53 /// Conversely, a calibrated (s)digit always has its charge in fC.
54 ///
55 /// \author Laurent Aphecetche, Subatech
56 //-----------------------------------------------------------------------------
57
58 #include "AliMUONVDigit.h"
59
60 #include <Riostream.h>
61 #include <TClass.h>
62
63 /// \cond CLASSIMP
64 ClassImp(AliMUONVDigit)
65 /// \endcond
66
67 //_____________________________________________________________________________
68 AliMUONVDigit::AliMUONVDigit(Int_t detElemId, Int_t eCardId,
69                              Int_t eCardChannel, Int_t cathode)
70 : TObject() 
71 {
72   /// Normal constructor for trigger digits
73   SetUniqueID(BuildUniqueID(detElemId,eCardId,eCardChannel,cathode));
74 }
75
76 //_____________________________________________________________________________
77 AliMUONVDigit::AliMUONVDigit()
78 : TObject() 
79 {
80   /// Default ctor
81 }
82
83 //_____________________________________________________________________________
84 AliMUONVDigit::~AliMUONVDigit()
85 {
86   /// dtor
87 }
88
89 //_____________________________________________________________________________
90 Bool_t 
91 AliMUONVDigit::IsEqual(const TObject* object) const
92 {
93   /// Whether we're equal to object. 
94   /// WARNING : only based on our identifiers (de,manu,channel,cathode), not our
95   /// content (i.e. charge, status...)
96   
97   const AliMUONVDigit* d = static_cast<const AliMUONVDigit*>(object);
98     
99   return ( DetElemId() == d->DetElemId() &&
100            Cathode() == d->Cathode() &&
101            ManuId() == d->ManuId() &&
102            ManuChannel() == d->ManuChannel() );
103 }
104
105 //_____________________________________________________________________________
106 Int_t 
107 AliMUONVDigit::Compare(const TObject* object) const
108 {
109   /// Compare two digits, trying to get as complete an order as possible.
110   /// We sort by DE, then by charge, then by manu, etc...
111   ///
112   const AliMUONVDigit* d = static_cast<const AliMUONVDigit*>(object);
113   
114   if ( DetElemId() > d->DetElemId() ) 
115   {
116     return 1;
117   }
118   else if ( DetElemId() < d->DetElemId() )
119   {
120     return -1;
121   }
122   else
123   {
124     if ( Charge() > d->Charge() )
125     {
126       return 1;
127     }
128     else if ( Charge() < d->Charge() )
129     {
130       return -1;
131     }
132     else
133     {
134       if ( ManuId() > d->ManuId() )
135       {
136         return 1;
137       }
138       else if ( ManuId() < d->ManuId() )
139       {
140         return -1;
141       }
142       else
143       {
144         if ( ManuChannel() > d->ManuChannel() )
145         {
146           return 1;
147         }
148         else if ( ManuChannel() < d->ManuChannel() )
149         {
150           return -1;
151         }
152       }
153     }
154   }
155   return 0;
156 }
157
158 //_____________________________________________________________________________
159 UInt_t 
160 AliMUONVDigit::BuildUniqueID(Int_t detElemId, Int_t manuId, 
161                              Int_t manuChannel, Int_t cathode)
162 {
163   /// Build a single integer with id information
164   return ( ( detElemId ) | ( manuId << 12 ) | ( manuChannel << 24 )
165                 | ( cathode << 30 ) );
166 }
167
168 //_____________________________________________________________________________
169 Int_t
170 AliMUONVDigit::DetElemId(UInt_t uniqueID)
171 {
172   /// Return detection element id part of the uniqueID
173   return uniqueID & 0xFFF;
174 }
175
176 //_____________________________________________________________________________
177 Int_t
178 AliMUONVDigit::ManuChannel(UInt_t uniqueID)
179 {
180   /// Return manuChannel part of the uniqueID
181   return ( uniqueID & 0x3F000000 ) >> 24;
182 }
183
184 //_____________________________________________________________________________
185 Int_t
186 AliMUONVDigit::ManuId(UInt_t uniqueID)
187 {
188   /// Return manuId part of the uniqueID
189   return ( uniqueID & 0xFFF000 ) >> 12;
190 }
191
192 //_____________________________________________________________________________
193 Int_t
194 AliMUONVDigit::Cathode(UInt_t uniqueID)
195 {
196   /// Return the cathode part of the uniqueID
197   return ( uniqueID & 0x40000000 ) >> 30;
198 }
199
200 //_____________________________________________________________________________
201 void
202 AliMUONVDigit::DecodeUniqueID(UInt_t uniqueID,
203                               Int_t& detElemId, Int_t& manuId, 
204                               Int_t& manuChannel, Int_t& cathode)
205 {
206   /// Unpack uniqueID into 4 elements
207   detElemId = DetElemId(uniqueID);
208   manuId = ManuId(uniqueID);
209   manuChannel = ManuChannel(uniqueID);
210   cathode = Cathode(uniqueID);
211 }
212
213 //_____________________________________________________________________________
214 const char*
215 AliMUONVDigit::GetName() const
216 {
217   /// Return the name of this digit, composed of its id parts.
218   return Form("DE%04d-%04d-%02d-%d",
219               DetElemId(),ManuId(),ManuChannel(),Cathode());
220 }
221
222 //_____________________________________________________________________________
223 void
224 AliMUONVDigit::Print(Option_t* opt) const
225 {
226   /// Dump to screen.
227   ///
228   /// If opt=="tracks", info on tracks are printed too.
229   /// 
230   /// The last part of the printout indicated the status of the digit :
231   /// (S) means that digit is saturated
232   /// (C) means that digit has been calibrated
233   /// [fC] means that digit's charge is in femto-coulombs (fC)
234   /// (U) means that digit is part of (has been used in) a cluster
235   /// (+) is noise-only digit (added by the simulation)
236   /// (X) has the IsConverted flag on (e.g. has been embedded)
237   
238   TString options(opt);
239   options.ToLower();
240
241   if ( options.Contains("zs") )
242   {
243     if ( IsCalibrated() && Charge() <= 0 )
244     {
245       return;
246     }
247     
248     if ( !IsCalibrated() && ADC() <= 0 )
249     {
250       return;
251     }
252   }
253   
254   cout << Form("<%s>: ID %12u DE %4d Cath %d (Ix,Iy)=(%3d,%3d) (Manu,Channel)=(%4d,%2d)"
255                ", Charge=%7.2f",
256                ClassName(),GetUniqueID(),
257                DetElemId(),Cathode(),PadX(),PadY(),ManuId(),ManuChannel(),Charge());  
258   
259   
260   if ( IsSaturated() ) 
261   {
262     cout << "(S)";
263   }
264   else
265   {
266     cout << "   ";
267   }
268   
269   if ( IsCalibrated() )
270   {
271     cout << "(C)";
272   }
273   else
274   {
275     cout << "   ";
276   }
277
278   if ( IsChargeInFC() )
279   {
280     cout << "[fC]";
281   }
282   else
283   {
284     cout << "    ";
285   }
286   
287   if ( IsUsed() )
288   {
289     cout << "(U)";
290   }
291   else
292   {
293     cout << "   ";
294   }
295   
296   if ( IsNoiseOnly() )
297   {
298     cout << "(+)";
299   }
300   else
301   {
302     cout << "   ";
303   }
304   
305   if ( IsConverted() )
306   {
307     cout << "(X)";
308   }
309   else
310   {
311     cout << "   ";
312   }
313     
314   cout << Form(" ADC=%4d",ADC());
315   
316   if ( IsCalibrated() )
317   {
318     // StatusMap is not set before calibration has occured (e.g.
319     // SDigits cannot have it meaningfully filled)
320     cout << Form(" StatusMap=%04x",StatusMap());    
321   }
322
323   if ( options.Contains("tracks") && HasMCInformation() )
324   {
325     cout << " Hit " << setw(3) << Hit();
326     Int_t ntracks = Ntracks();
327     if (ntracks) 
328     {
329       cout << " Tracks : " << setw(2) << ntracks;
330       for ( Int_t i = 0; i < ntracks; ++i )
331       {
332         cout << " Track(" << i << ")=" << setw(3) << Track(i)
333         << " Charge(" << i << ")=" << setw(5) << TrackCharge(i);
334       }
335     }
336     else
337     {
338       cout << " no track info.";
339     }
340   }
341   cout << endl;  
342 }