Line data Source code
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 18 : ClassImp(AliMUONVDigit)
68 : /// \endcond
69 :
70 : //_____________________________________________________________________________
71 : AliMUONVDigit::AliMUONVDigit(Int_t detElemId, Int_t eCardId,
72 : Int_t eCardChannel, Int_t cathode)
73 244171 : : TObject()
74 732513 : {
75 : /// Normal constructor for trigger digits
76 244171 : SetUniqueID(BuildUniqueID(detElemId,eCardId,eCardChannel,cathode));
77 244171 : }
78 :
79 : //_____________________________________________________________________________
80 : AliMUONVDigit::AliMUONVDigit()
81 4094 : : TObject()
82 12282 : {
83 : /// Default ctor
84 4094 : }
85 :
86 : //_____________________________________________________________________________
87 : AliMUONVDigit::~AliMUONVDigit()
88 0 : {
89 : /// dtor
90 745742 : }
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 0 : const AliMUONVDigit* d = static_cast<const AliMUONVDigit*>(object);
101 :
102 0 : return ( DetElemId() == d->DetElemId() &&
103 0 : Cathode() == d->Cathode() &&
104 0 : ManuId() == d->ManuId() &&
105 0 : 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 0 : const AliMUONVDigit* d = static_cast<const AliMUONVDigit*>(object);
116 :
117 0 : if ( DetElemId() > d->DetElemId() )
118 : {
119 0 : return 1;
120 : }
121 0 : else if ( DetElemId() < d->DetElemId() )
122 : {
123 0 : return -1;
124 : }
125 : else
126 : {
127 0 : if ( Charge() > d->Charge() )
128 : {
129 0 : return 1;
130 : }
131 0 : else if ( Charge() < d->Charge() )
132 : {
133 0 : return -1;
134 : }
135 : else
136 : {
137 0 : if ( ManuId() > d->ManuId() )
138 : {
139 0 : return 1;
140 : }
141 0 : else if ( ManuId() < d->ManuId() )
142 : {
143 0 : return -1;
144 : }
145 : else
146 : {
147 0 : if ( ManuChannel() > d->ManuChannel() )
148 : {
149 0 : return 1;
150 : }
151 0 : else if ( ManuChannel() < d->ManuChannel() )
152 : {
153 0 : return -1;
154 : }
155 : }
156 : }
157 : }
158 0 : return 0;
159 0 : }
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 734499 : return ( ( detElemId ) | ( manuId << 12 ) | ( manuChannel << 24 )
168 244833 : | ( 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 1637222 : return uniqueID & 0xFFF;
177 : }
178 :
179 : //_____________________________________________________________________________
180 : Int_t
181 : AliMUONVDigit::ManuChannel(UInt_t uniqueID)
182 : {
183 : /// Return manuChannel part of the uniqueID
184 1029234 : 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 1029234 : 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 1314788 : 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 0 : detElemId = DetElemId(uniqueID);
211 0 : manuId = ManuId(uniqueID);
212 0 : manuChannel = ManuChannel(uniqueID);
213 0 : cathode = Cathode(uniqueID);
214 0 : }
215 :
216 : //_____________________________________________________________________________
217 : const char*
218 : AliMUONVDigit::GetName() const
219 : {
220 : /// Return the name of this digit, composed of its id parts.
221 0 : return Form("DE%04d-%04d-%02d-%d",
222 0 : 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 0 : TString options(opt);
242 0 : options.ToLower();
243 :
244 0 : if ( options.Contains("zs") )
245 : {
246 0 : if ( IsCalibrated() && Charge() <= 0 )
247 : {
248 0 : return;
249 : }
250 :
251 0 : if ( !IsCalibrated() && ADC() <= 0 )
252 : {
253 0 : return;
254 : }
255 : }
256 :
257 0 : cout << Form("<%s>: ID %12u DE %4d Cath %d (Ix,Iy)=(%3d,%3d) (Manu,Channel)=(%4d,%2d)"
258 : ", Charge=%7.2f",
259 0 : ClassName(),GetUniqueID(),
260 0 : DetElemId(),Cathode(),PadX(),PadY(),ManuId(),ManuChannel(),Charge());
261 :
262 :
263 0 : if ( IsSaturated() )
264 : {
265 0 : cout << "(S)";
266 : }
267 : else
268 : {
269 0 : cout << " ";
270 : }
271 :
272 0 : if ( IsCalibrated() )
273 : {
274 0 : cout << "(C)";
275 : }
276 : else
277 : {
278 0 : cout << " ";
279 : }
280 :
281 0 : if ( IsChargeInFC() )
282 : {
283 0 : cout << "[fC]";
284 : }
285 : else
286 : {
287 0 : cout << " ";
288 : }
289 :
290 0 : if ( IsUsed() )
291 : {
292 0 : cout << "(U)";
293 : }
294 : else
295 : {
296 0 : cout << " ";
297 : }
298 :
299 0 : if ( IsNoiseOnly() )
300 : {
301 0 : cout << "(+)";
302 : }
303 : else
304 : {
305 0 : cout << " ";
306 : }
307 :
308 0 : if ( IsConverted() )
309 : {
310 0 : cout << "(X)";
311 : }
312 : else
313 : {
314 0 : cout << " ";
315 : }
316 :
317 0 : cout << Form(" ADC=%4d",ADC());
318 :
319 0 : if ( IsCalibrated() )
320 : {
321 : // StatusMap is not set before calibration has occured (e.g.
322 : // SDigits cannot have it meaningfully filled)
323 0 : cout << Form(" StatusMap=%04x",StatusMap());
324 : }
325 :
326 0 : if ( options.Contains("tracks") && HasMCInformation() )
327 : {
328 0 : cout << " Hit " << setw(3) << Hit();
329 0 : Int_t ntracks = Ntracks();
330 0 : if (ntracks)
331 : {
332 0 : cout << " Tracks : " << setw(2) << ntracks;
333 0 : for ( Int_t i = 0; i < ntracks; ++i )
334 : {
335 0 : cout << " Track(" << i << ")=" << setw(3) << Track(i)
336 0 : << " Charge(" << i << ")=" << setw(5) << TrackCharge(i);
337 : }
338 0 : }
339 : else
340 : {
341 0 : cout << " no track info.";
342 : }
343 0 : }
344 0 : cout << endl;
345 0 : }
|