Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / MUON / AliMUONVDigit.cxx
CommitLineData
d6c3334d 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
3d1463c8 18//-----------------------------------------------------------------------------
d6c3334d 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///
05315e71 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///
d6c3334d 55/// \author Laurent Aphecetche, Subatech
3d1463c8 56//-----------------------------------------------------------------------------
d6c3334d 57
58#include "AliMUONVDigit.h"
59
60#include <Riostream.h>
61#include <TClass.h>
62
b80faac0 63using std::cout;
64using std::endl;
65using std::setw;
d6c3334d 66/// \cond CLASSIMP
67ClassImp(AliMUONVDigit)
68/// \endcond
69
70//_____________________________________________________________________________
71AliMUONVDigit::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//_____________________________________________________________________________
80AliMUONVDigit::AliMUONVDigit()
7332f213 81: TObject()
d6c3334d 82{
83 /// Default ctor
84}
85
86//_____________________________________________________________________________
87AliMUONVDigit::~AliMUONVDigit()
88{
89 /// dtor
90}
91
92//_____________________________________________________________________________
36a01415 93Bool_t
94AliMUONVDigit::IsEqual(const TObject* object) const
95{
22dce0e3 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
36a01415 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//_____________________________________________________________________________
109Int_t
110AliMUONVDigit::Compare(const TObject* object) const
111{
22dce0e3 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 ///
36a01415 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 {
be296517 137 if ( ManuId() > d->ManuId() )
36a01415 138 {
139 return 1;
140 }
be296517 141 else if ( ManuId() < d->ManuId() )
36a01415 142 {
143 return -1;
144 }
145 else
146 {
be296517 147 if ( ManuChannel() > d->ManuChannel() )
148 {
149 return 1;
150 }
151 else if ( ManuChannel() < d->ManuChannel() )
152 {
153 return -1;
154 }
36a01415 155 }
156 }
157 }
158 return 0;
159}
160
161//_____________________________________________________________________________
d6c3334d 162UInt_t
163AliMUONVDigit::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//_____________________________________________________________________________
172Int_t
173AliMUONVDigit::DetElemId(UInt_t uniqueID)
174{
175 /// Return detection element id part of the uniqueID
176 return uniqueID & 0xFFF;
177}
178
179//_____________________________________________________________________________
180Int_t
181AliMUONVDigit::ManuChannel(UInt_t uniqueID)
182{
183 /// Return manuChannel part of the uniqueID
184 return ( uniqueID & 0x3F000000 ) >> 24;
185}
186
187//_____________________________________________________________________________
188Int_t
189AliMUONVDigit::ManuId(UInt_t uniqueID)
190{
191 /// Return manuId part of the uniqueID
192 return ( uniqueID & 0xFFF000 ) >> 12;
193}
194
195//_____________________________________________________________________________
196Int_t
197AliMUONVDigit::Cathode(UInt_t uniqueID)
198{
199 /// Return the cathode part of the uniqueID
200 return ( uniqueID & 0x40000000 ) >> 30;
201}
202
203//_____________________________________________________________________________
204void
205AliMUONVDigit::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//_____________________________________________________________________________
217const char*
218AliMUONVDigit::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//_____________________________________________________________________________
226void
227AliMUONVDigit::Print(Option_t* opt) const
228{
229 /// Dump to screen.
05315e71 230 ///
d6c3334d 231 /// If opt=="tracks", info on tracks are printed too.
05315e71 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 }
d6c3334d 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());
05315e71 261
262
d6c3334d 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
05315e71 281 if ( IsChargeInFC() )
282 {
283 cout << "[fC]";
284 }
285 else
286 {
287 cout << " ";
288 }
289
d6c3334d 290 if ( IsUsed() )
291 {
292 cout << "(U)";
293 }
294 else
295 {
296 cout << " ";
297 }
298
05315e71 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 }
d6c3334d 325
d6c3334d 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}