1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 //-----------------------------------------------------------------------------
19 /// \class AliMUONVDigit
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.
24 /// All digits have basic features, like :
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).
33 /// - a set of boolean methods to indicate whether the digit has been calibrated, etc...
35 /// In addition, if HasMCInformation is true, the digit store also the list
36 /// of MC tracks that contributed to its charge
38 /// Also, if HasGeometryInformation is true, the digit knows the position and
39 /// the (half) dimensions (in cm) of the pad it corresponds to.
43 /// Please note that IsCalibrated and IsChargeInFC are two
44 /// concepts closely related, but not equivalent, at least for SDigits.
46 /// For instance a SDigit can have its charge in fC but not being calibrated.
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). }
53 /// Conversely, a calibrated (s)digit always has its charge in fC.
55 /// \author Laurent Aphecetche, Subatech
56 //-----------------------------------------------------------------------------
58 #include "AliMUONVDigit.h"
60 #include <Riostream.h>
67 ClassImp(AliMUONVDigit)
70 //_____________________________________________________________________________
71 AliMUONVDigit::AliMUONVDigit(Int_t detElemId, Int_t eCardId,
72 Int_t eCardChannel, Int_t cathode)
75 /// Normal constructor for trigger digits
76 SetUniqueID(BuildUniqueID(detElemId,eCardId,eCardChannel,cathode));
79 //_____________________________________________________________________________
80 AliMUONVDigit::AliMUONVDigit()
86 //_____________________________________________________________________________
87 AliMUONVDigit::~AliMUONVDigit()
92 //_____________________________________________________________________________
94 AliMUONVDigit::IsEqual(const TObject* object) const
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...)
100 const AliMUONVDigit* d = static_cast<const AliMUONVDigit*>(object);
102 return ( DetElemId() == d->DetElemId() &&
103 Cathode() == d->Cathode() &&
104 ManuId() == d->ManuId() &&
105 ManuChannel() == d->ManuChannel() );
108 //_____________________________________________________________________________
110 AliMUONVDigit::Compare(const TObject* object) const
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...
115 const AliMUONVDigit* d = static_cast<const AliMUONVDigit*>(object);
117 if ( DetElemId() > d->DetElemId() )
121 else if ( DetElemId() < d->DetElemId() )
127 if ( Charge() > d->Charge() )
131 else if ( Charge() < d->Charge() )
137 if ( ManuId() > d->ManuId() )
141 else if ( ManuId() < d->ManuId() )
147 if ( ManuChannel() > d->ManuChannel() )
151 else if ( ManuChannel() < d->ManuChannel() )
161 //_____________________________________________________________________________
163 AliMUONVDigit::BuildUniqueID(Int_t detElemId, Int_t manuId,
164 Int_t manuChannel, Int_t cathode)
166 /// Build a single integer with id information
167 return ( ( detElemId ) | ( manuId << 12 ) | ( manuChannel << 24 )
168 | ( cathode << 30 ) );
171 //_____________________________________________________________________________
173 AliMUONVDigit::DetElemId(UInt_t uniqueID)
175 /// Return detection element id part of the uniqueID
176 return uniqueID & 0xFFF;
179 //_____________________________________________________________________________
181 AliMUONVDigit::ManuChannel(UInt_t uniqueID)
183 /// Return manuChannel part of the uniqueID
184 return ( uniqueID & 0x3F000000 ) >> 24;
187 //_____________________________________________________________________________
189 AliMUONVDigit::ManuId(UInt_t uniqueID)
191 /// Return manuId part of the uniqueID
192 return ( uniqueID & 0xFFF000 ) >> 12;
195 //_____________________________________________________________________________
197 AliMUONVDigit::Cathode(UInt_t uniqueID)
199 /// Return the cathode part of the uniqueID
200 return ( uniqueID & 0x40000000 ) >> 30;
203 //_____________________________________________________________________________
205 AliMUONVDigit::DecodeUniqueID(UInt_t uniqueID,
206 Int_t& detElemId, Int_t& manuId,
207 Int_t& manuChannel, Int_t& cathode)
209 /// Unpack uniqueID into 4 elements
210 detElemId = DetElemId(uniqueID);
211 manuId = ManuId(uniqueID);
212 manuChannel = ManuChannel(uniqueID);
213 cathode = Cathode(uniqueID);
216 //_____________________________________________________________________________
218 AliMUONVDigit::GetName() const
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());
225 //_____________________________________________________________________________
227 AliMUONVDigit::Print(Option_t* opt) const
231 /// If opt=="tracks", info on tracks are printed too.
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)
241 TString options(opt);
244 if ( options.Contains("zs") )
246 if ( IsCalibrated() && Charge() <= 0 )
251 if ( !IsCalibrated() && ADC() <= 0 )
257 cout << Form("<%s>: ID %12u DE %4d Cath %d (Ix,Iy)=(%3d,%3d) (Manu,Channel)=(%4d,%2d)"
259 ClassName(),GetUniqueID(),
260 DetElemId(),Cathode(),PadX(),PadY(),ManuId(),ManuChannel(),Charge());
272 if ( IsCalibrated() )
281 if ( IsChargeInFC() )
317 cout << Form(" ADC=%4d",ADC());
319 if ( IsCalibrated() )
321 // StatusMap is not set before calibration has occured (e.g.
322 // SDigits cannot have it meaningfully filled)
323 cout << Form(" StatusMap=%04x",StatusMap());
326 if ( options.Contains("tracks") && HasMCInformation() )
328 cout << " Hit " << setw(3) << Hit();
329 Int_t ntracks = Ntracks();
332 cout << " Tracks : " << setw(2) << ntracks;
333 for ( Int_t i = 0; i < ntracks; ++i )
335 cout << " Track(" << i << ")=" << setw(3) << Track(i)
336 << " Charge(" << i << ")=" << setw(5) << TrackCharge(i);
341 cout << " no track info.";