next50 trigger mask in AliHLTGlobalEsdConverterComponent
[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 using std::cout;
64 using std::endl;
65 using std::setw;
66 /// \cond CLASSIMP
67 ClassImp(AliMUONVDigit)
68 /// \endcond
69
70 //_____________________________________________________________________________
71 AliMUONVDigit::AliMUONVDigit(Int_t detElemId, Int_t eCardId,
72                              Int_t eCardChannel, Int_t cathode)
73 : TObject() 
74 {
75   /// Normal constructor for trigger digits
76   SetUniqueID(BuildUniqueID(detElemId,eCardId,eCardChannel,cathode));
77 }
78
79 //_____________________________________________________________________________
80 AliMUONVDigit::AliMUONVDigit()
81 : TObject() 
82 {
83   /// Default ctor
84 }
85
86 //_____________________________________________________________________________
87 AliMUONVDigit::~AliMUONVDigit()
88 {
89   /// dtor
90 }
91
92 //_____________________________________________________________________________
93 Bool_t 
94 AliMUONVDigit::IsEqual(const TObject* object) const
95 {
96   /// Whether we're equal to object. 
97   /// WARNING : only based on our identifiers (de,manu,channel,cathode), not our
98   /// content (i.e. charge, status...)
99   
100   const AliMUONVDigit* d = static_cast<const AliMUONVDigit*>(object);
101     
102   return ( DetElemId() == d->DetElemId() &&
103            Cathode() == d->Cathode() &&
104            ManuId() == d->ManuId() &&
105            ManuChannel() == d->ManuChannel() );
106 }
107
108 //_____________________________________________________________________________
109 Int_t 
110 AliMUONVDigit::Compare(const TObject* object) const
111 {
112   /// Compare two digits, trying to get as complete an order as possible.
113   /// We sort by DE, then by charge, then by manu, etc...
114   ///
115   const AliMUONVDigit* d = static_cast<const AliMUONVDigit*>(object);
116   
117   if ( DetElemId() > d->DetElemId() ) 
118   {
119     return 1;
120   }
121   else if ( DetElemId() < d->DetElemId() )
122   {
123     return -1;
124   }
125   else
126   {
127     if ( Charge() > d->Charge() )
128     {
129       return 1;
130     }
131     else if ( Charge() < d->Charge() )
132     {
133       return -1;
134     }
135     else
136     {
137       if ( ManuId() > d->ManuId() )
138       {
139         return 1;
140       }
141       else if ( ManuId() < d->ManuId() )
142       {
143         return -1;
144       }
145       else
146       {
147         if ( ManuChannel() > d->ManuChannel() )
148         {
149           return 1;
150         }
151         else if ( ManuChannel() < d->ManuChannel() )
152         {
153           return -1;
154         }
155       }
156     }
157   }
158   return 0;
159 }
160
161 //_____________________________________________________________________________
162 UInt_t 
163 AliMUONVDigit::BuildUniqueID(Int_t detElemId, Int_t manuId, 
164                              Int_t manuChannel, Int_t cathode)
165 {
166   /// Build a single integer with id information
167   return ( ( detElemId ) | ( manuId << 12 ) | ( manuChannel << 24 )
168                 | ( cathode << 30 ) );
169 }
170
171 //_____________________________________________________________________________
172 Int_t
173 AliMUONVDigit::DetElemId(UInt_t uniqueID)
174 {
175   /// Return detection element id part of the uniqueID
176   return uniqueID & 0xFFF;
177 }
178
179 //_____________________________________________________________________________
180 Int_t
181 AliMUONVDigit::ManuChannel(UInt_t uniqueID)
182 {
183   /// Return manuChannel part of the uniqueID
184   return ( uniqueID & 0x3F000000 ) >> 24;
185 }
186
187 //_____________________________________________________________________________
188 Int_t
189 AliMUONVDigit::ManuId(UInt_t uniqueID)
190 {
191   /// Return manuId part of the uniqueID
192   return ( uniqueID & 0xFFF000 ) >> 12;
193 }
194
195 //_____________________________________________________________________________
196 Int_t
197 AliMUONVDigit::Cathode(UInt_t uniqueID)
198 {
199   /// Return the cathode part of the uniqueID
200   return ( uniqueID & 0x40000000 ) >> 30;
201 }
202
203 //_____________________________________________________________________________
204 void
205 AliMUONVDigit::DecodeUniqueID(UInt_t uniqueID,
206                               Int_t& detElemId, Int_t& manuId, 
207                               Int_t& manuChannel, Int_t& cathode)
208 {
209   /// Unpack uniqueID into 4 elements
210   detElemId = DetElemId(uniqueID);
211   manuId = ManuId(uniqueID);
212   manuChannel = ManuChannel(uniqueID);
213   cathode = Cathode(uniqueID);
214 }
215
216 //_____________________________________________________________________________
217 const char*
218 AliMUONVDigit::GetName() const
219 {
220   /// Return the name of this digit, composed of its id parts.
221   return Form("DE%04d-%04d-%02d-%d",
222               DetElemId(),ManuId(),ManuChannel(),Cathode());
223 }
224
225 //_____________________________________________________________________________
226 void
227 AliMUONVDigit::Print(Option_t* opt) const
228 {
229   /// Dump to screen.
230   ///
231   /// If opt=="tracks", info on tracks are printed too.
232   /// 
233   /// The last part of the printout indicated the status of the digit :
234   /// (S) means that digit is saturated
235   /// (C) means that digit has been calibrated
236   /// [fC] means that digit's charge is in femto-coulombs (fC)
237   /// (U) means that digit is part of (has been used in) a cluster
238   /// (+) is noise-only digit (added by the simulation)
239   /// (X) has the IsConverted flag on (e.g. has been embedded)
240   
241   TString options(opt);
242   options.ToLower();
243
244   if ( options.Contains("zs") )
245   {
246     if ( IsCalibrated() && Charge() <= 0 )
247     {
248       return;
249     }
250     
251     if ( !IsCalibrated() && ADC() <= 0 )
252     {
253       return;
254     }
255   }
256   
257   cout << Form("<%s>: ID %12u DE %4d Cath %d (Ix,Iy)=(%3d,%3d) (Manu,Channel)=(%4d,%2d)"
258                ", Charge=%7.2f",
259                ClassName(),GetUniqueID(),
260                DetElemId(),Cathode(),PadX(),PadY(),ManuId(),ManuChannel(),Charge());  
261   
262   
263   if ( IsSaturated() ) 
264   {
265     cout << "(S)";
266   }
267   else
268   {
269     cout << "   ";
270   }
271   
272   if ( IsCalibrated() )
273   {
274     cout << "(C)";
275   }
276   else
277   {
278     cout << "   ";
279   }
280
281   if ( IsChargeInFC() )
282   {
283     cout << "[fC]";
284   }
285   else
286   {
287     cout << "    ";
288   }
289   
290   if ( IsUsed() )
291   {
292     cout << "(U)";
293   }
294   else
295   {
296     cout << "   ";
297   }
298   
299   if ( IsNoiseOnly() )
300   {
301     cout << "(+)";
302   }
303   else
304   {
305     cout << "   ";
306   }
307   
308   if ( IsConverted() )
309   {
310     cout << "(X)";
311   }
312   else
313   {
314     cout << "   ";
315   }
316     
317   cout << Form(" ADC=%4d",ADC());
318   
319   if ( IsCalibrated() )
320   {
321     // StatusMap is not set before calibration has occured (e.g.
322     // SDigits cannot have it meaningfully filled)
323     cout << Form(" StatusMap=%04x",StatusMap());    
324   }
325
326   if ( options.Contains("tracks") && HasMCInformation() )
327   {
328     cout << " Hit " << setw(3) << Hit();
329     Int_t ntracks = Ntracks();
330     if (ntracks) 
331     {
332       cout << " Tracks : " << setw(2) << ntracks;
333       for ( Int_t i = 0; i < ntracks; ++i )
334       {
335         cout << " Track(" << i << ")=" << setw(3) << Track(i)
336         << " Charge(" << i << ")=" << setw(5) << TrackCharge(i);
337       }
338     }
339     else
340     {
341       cout << " no track info.";
342     }
343   }
344   cout << endl;  
345 }