]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONResponseV0.cxx
In MUONRecoCheck.C:
[u/mrichter/AliRoot.git] / MUON / AliMUONResponseV0.cxx
CommitLineData
a9e2aefa 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
88cb7938 16/* $Id$ */
a9e2aefa 17
3d1463c8 18//-----------------------------------------------------------------------------
d19b6003 19// Class AliMUONResponseV0
20// --------------------------
9265505b 21// Implementation of
22// Mathieson response
3d1463c8 23//-----------------------------------------------------------------------------
a9e2aefa 24
30178c30 25#include "AliMUONResponseV0.h"
885d501b 26#include "AliMUON.h"
27#include "AliMUONConstants.h"
28#include "AliMUONDigit.h"
885d501b 29#include "AliMUONGeometryTransformer.h"
30#include "AliMUONHit.h"
9265505b 31
885d501b 32#include "AliMpArea.h"
33#include "AliMpDEManager.h"
885d501b 34#include "AliMpVPadIterator.h"
9265505b 35#include "AliMpSegmentation.h"
885d501b 36#include "AliMpVSegmentation.h"
866c3232 37#include "AliMpCathodType.h"
9265505b 38
885d501b 39#include "AliRun.h"
9265505b 40#include "AliLog.h"
41
885d501b 42#include "Riostream.h"
43#include "TVector2.h"
44#include <TMath.h>
45#include <TRandom.h>
8c343c7c 46
9265505b 47/// \cond CLASSIMP
d5bfadcc 48ClassImp(AliMUONResponseV0)
9265505b 49/// \endcond
d5bfadcc 50
885d501b 51AliMUON* muon()
52{
53 return static_cast<AliMUON*>(gAlice->GetModule("MUON"));
54}
55
56void Global2Local(Int_t detElemId, Double_t xg, Double_t yg, Double_t zg,
57 Double_t& xl, Double_t& yl, Double_t& zl)
58{
9265505b 59 /// ideally should be :
60 /// Double_t x,y,z;
61 /// AliMUONGeometry::Global2Local(detElemId,xg,yg,zg,x,y,z);
62 /// but while waiting for this geometry singleton, let's go through
63 /// AliMUON still.
885d501b 64
65 const AliMUONGeometryTransformer* transformer = muon()->GetGeometryTransformer();
66 transformer->Global2Local(detElemId,xg,yg,zg,xl,yl,zl);
67}
68
30178c30 69//__________________________________________________________________________
70AliMUONResponseV0::AliMUONResponseV0()
885d501b 71 : AliMUONResponse(),
72 fChargeSlope(0.0),
73 fChargeSpreadX(0.0),
74 fChargeSpreadY(0.0),
75 fSigmaIntegration(0.0),
76 fMaxAdc(0),
ccea41d4 77 fSaturation(0),
885d501b 78 fZeroSuppression(0),
79 fChargeCorrel(0.0),
80 fMathieson(new AliMUONMathieson),
d1bb9a6f 81 fChargeThreshold(1e-4),
82 fIsTailEffect(kFALSE)
30178c30 83{
9265505b 84 /// Normal constructor
885d501b 85 AliDebug(1,Form("Default ctor"));
30178c30 86}
f29ba3e1 87
2a7d64a9 88//__________________________________________________________________________
89AliMUONResponseV0::AliMUONResponseV0(const AliMUONResponseV0& other)
90: AliMUONResponse(),
91fChargeSlope(0.0),
92fChargeSpreadX(0.0),
93fChargeSpreadY(0.0),
94fSigmaIntegration(0.0),
95fMaxAdc(0),
96fSaturation(0),
97fZeroSuppression(0),
98fChargeCorrel(0.0),
99fMathieson(0),
d1bb9a6f 100fChargeThreshold(1e-4),
101fIsTailEffect(kFALSE)
2a7d64a9 102{
103 /// copy ctor
104 other.CopyTo(*this);
105}
106
107//__________________________________________________________________________
108AliMUONResponseV0&
109AliMUONResponseV0::operator=(const AliMUONResponseV0& other)
110{
111 /// Assignment operator
112 other.CopyTo(*this);
113 return *this;
114}
115
ccea41d4 116//__________________________________________________________________________
a713db22 117AliMUONResponseV0::~AliMUONResponseV0()
118{
9265505b 119/// Destructor
120
885d501b 121 AliDebug(1,"");
a713db22 122 delete fMathieson;
123}
f29ba3e1 124
2a7d64a9 125//______________________________________________________________________________
126void
127AliMUONResponseV0::CopyTo(AliMUONResponseV0& other) const
128{
129 /// Copy *this to other
130 other.fChargeSlope=fChargeSlope;
131 other.fChargeSpreadX=fChargeSpreadX;
132 other.fChargeSpreadY=fChargeSpreadY;
133 other.fSigmaIntegration=fSigmaIntegration;
134 other.fMaxAdc=fMaxAdc;
135 other.fSaturation=fSaturation;
136 other.fZeroSuppression=fZeroSuppression;
137 other.fChargeCorrel=fChargeCorrel;
138 delete other.fMathieson;
139 other.fMathieson = new AliMUONMathieson(*fMathieson);
140 other.fChargeThreshold=fChargeThreshold;
141}
142
885d501b 143//______________________________________________________________________________
144void
145AliMUONResponseV0::Print(Option_t*) const
146{
9265505b 147/// Printing
d19b6003 148
885d501b 149 cout << " ChargeSlope=" << fChargeSlope
150 << " ChargeSpreadX,Y=" << fChargeSpreadX
151 << fChargeSpreadY
152 << " ChargeCorrelation=" << fChargeCorrel
153 << endl;
f29ba3e1 154}
155
d5bfadcc 156 //__________________________________________________________________________
157void AliMUONResponseV0::SetSqrtKx3AndDeriveKx2Kx4(Float_t SqrtKx3)
158{
9265505b 159 /// Set to "SqrtKx3" the Mathieson parameter K3 ("fSqrtKx3")
160 /// in the X direction, perpendicular to the wires,
161 /// and derive the Mathieson parameters K2 ("fKx2") and K4 ("fKx4")
162 /// in the same direction
a713db22 163 fMathieson->SetSqrtKx3AndDeriveKx2Kx4(SqrtKx3);
d5bfadcc 164}
165
166 //__________________________________________________________________________
167void AliMUONResponseV0::SetSqrtKy3AndDeriveKy2Ky4(Float_t SqrtKy3)
168{
9265505b 169 /// Set to "SqrtKy3" the Mathieson parameter K3 ("fSqrtKy3")
170 /// in the Y direction, along the wires,
171 /// and derive the Mathieson parameters K2 ("fKy2") and K4 ("fKy4")
172 /// in the same direction
a713db22 173 fMathieson->SetSqrtKy3AndDeriveKy2Ky4(SqrtKy3);
d5bfadcc 174}
a713db22 175 //__________________________________________________________________________
85fec35d 176Float_t AliMUONResponseV0::IntPH(Float_t eloss) const
a9e2aefa 177{
9265505b 178 /// Calculate charge from given ionization energy loss
a9e2aefa 179 Int_t nel;
4ac9d21e 180 nel= Int_t(eloss*1.e9/27.4);
a9e2aefa 181 Float_t charge=0;
182 if (nel == 0) nel=1;
183 for (Int_t i=1;i<=nel;i++) {
01997fa2 184 Float_t arg=0.;
185 while(!arg) arg = gRandom->Rndm();
186 charge -= fChargeSlope*TMath::Log(arg);
a9e2aefa 187 }
188 return charge;
189}
a713db22 190
885d501b 191//_____________________________________________________________________________
192Float_t
193AliMUONResponseV0::GetAnod(Float_t x) const
194{
9265505b 195 /// Return wire coordinate closest to x.
196
885d501b 197 Int_t n = Int_t(x/Pitch());
198 Float_t wire = (x>0) ? n+0.5 : n-0.5;
199 return Pitch()*wire;
200}
a9e2aefa 201
885d501b 202//______________________________________________________________________________
203void
204AliMUONResponseV0::DisIntegrate(const AliMUONHit& hit, TList& digits)
205{
9265505b 206 /// Go from 1 hit to a list of digits.
207 /// The energy deposition of that hit is first converted into charge
208 /// (in IntPH() method), and then this charge is dispatched on several
209 /// pads, according to the Mathieson distribution.
885d501b 210
211 digits.Clear();
212
213 Int_t detElemId = hit.DetElemId();
d1bb9a6f 214 Double_t hitX = hit.X() ;
215 Double_t hitY = hit.Y() ;
216 Double_t hitZ = hit.Z() ;
217
885d501b 218 // Width of the integration area
885d501b 219 Double_t dx = SigmaIntegration()*ChargeSpreadX();
220 Double_t dy = SigmaIntegration()*ChargeSpreadY();
221
d1bb9a6f 222 //Modify to take the tailing effect.
223 if(fIsTailEffect){
224 Double_t locX,locY,locZ,globXCenter,globYCenter,globZ;
5fe36481 225 Int_t para = 5; // This parameter is a natural number(excluding zero), higher the value less is the tailing effect
d1bb9a6f 226 Double_t termA = 1.0;
227 Double_t termB = 1.0;
228 if(para>0){
229 for ( Int_t cath = AliMp::kCath0; cath <= AliMp::kCath1; ++cath )
230 {
231 // Get an iterator to loop over pads, within the given area.
232 const AliMpVSegmentation* seg =
233 AliMpSegmentation::Instance()
234 ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cath));
235 AliMp::PlaneType plane = seg->PlaneType();
236
237 if(plane == AliMp::kBendingPlane) {
238 Global2Local(detElemId,hitX,hitY,hitZ,locX,locY,locZ);
6e97fbb8 239 AliMpPad pad = seg->PadByPosition(locX,locY,kFALSE);
5fe36481 240 if(pad.IsValid()){
6e97fbb8 241 Double_t locYCenter = pad.GetPositionY();
242 Double_t locXCenter = pad.GetPositionX();
5fe36481 243 const AliMUONGeometryTransformer* transformer = muon()->GetGeometryTransformer();
244 transformer->Local2Global(detElemId,locXCenter,locYCenter,locZ,globXCenter,globYCenter,globZ);
245 for(Int_t itime = 0; itime<para; itime++)
246 termA *= 10.0;
247
248 for(Int_t itime = 0; itime<Int_t((2*para) + 1); itime++)
249 termB *= (hitY - globYCenter) ;
250
251 hitY = hitY + termA*termB;
252 }// if the pad is a valid one
d1bb9a6f 253 }// if bending plane
254 }// cathode loop
255 }// if para > 0 condn
256 }// if tail effect
257
885d501b 258 // Use that (dx,dy) to specify the area upon which
259 // we will iterate to spread charge into.
260 Double_t x,y,z;
d1bb9a6f 261 Global2Local(detElemId,hitX,hitY,hitZ,x,y,z);
885d501b 262 x = GetAnod(x);
6e97fbb8 263 AliMpArea area(x,y,dx,dy);
885d501b 264
32c9ead9 265 // Get pulse height from energy loss.
885d501b 266 Float_t qtot = IntPH(hit.Eloss());
267
32c9ead9 268 // Get the charge correlation between cathodes.
885d501b 269 Float_t currentCorrel = TMath::Exp(gRandom->Gaus(0.0,ChargeCorrel()/2.0));
a9e2aefa 270
866c3232 271 for ( Int_t cath = AliMp::kCath0; cath <= AliMp::kCath1; ++cath )
885d501b 272 {
273 Float_t qcath = qtot * ( cath == 0 ? currentCorrel : 1.0/currentCorrel);
274
885d501b 275 // Get an iterator to loop over pads, within the given area.
32c9ead9 276 const AliMpVSegmentation* seg =
866c3232 277 AliMpSegmentation::Instance()
278 ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cath));
885d501b 279
32c9ead9 280 AliMpVPadIterator* it = seg->CreateIterator(area);
281
282 if (!it)
283 {
284 AliError(Form("Could not get iterator for detElemId %d",detElemId));
285 return;
286 }
287
288 // Start loop over pads.
289 it->First();
290
291 if ( it->IsDone() )
292 {
293 // Exceptional case : iterator is built, but is invalid from the start.
6e97fbb8 294 AliMpPad pad = seg->PadByPosition(area.GetPositionX(),area.GetPositionY(),
295 kFALSE);
32c9ead9 296 if ( pad.IsValid() )
885d501b 297 {
32c9ead9 298 AliWarning(Form("Got an invalid iterator bug (area.Position() is within "
299 " DE but the iterator is void) for detElemId %d cath %d",
300 detElemId,cath));
885d501b 301 }
32c9ead9 302 else
885d501b 303 {
32c9ead9 304 AliError(Form("Got an invalid iterator bug for detElemId %d cath %d."
305 "Might be a bad hit ? area.Position()=(%e,%e) "
306 "Dimensions()=(%e,%e)",
6e97fbb8 307 detElemId,cath,area.GetPositionX(),area.GetPositionY(),
308 area.GetDimensionX(),area.GetDimensionY()));
885d501b 309 }
310 delete it;
32c9ead9 311 return;
312 }
313
314 while ( !it->IsDone() )
315 {
316 // For each pad given by the iterator, compute the charge of that
317 // pad, according to the Mathieson distribution.
318 AliMpPad pad = it->CurrentItem();
6e97fbb8 319 TVector2 lowerLeft(TVector2(x,y)-TVector2(pad.GetPositionX(),pad.GetPositionY())-
320 TVector2(pad.GetDimensionX(),pad.GetDimensionY()));
321 TVector2 upperRight(lowerLeft + TVector2(pad.GetDimensionX(),pad.GetDimensionY())*2.0);
32c9ead9 322 Float_t qp = TMath::Abs(fMathieson->IntXY(lowerLeft.X(),lowerLeft.Y(),
323 upperRight.X(),upperRight.Y()));
324
325 Int_t icharge = Int_t(qp*qcath);
326
327 if ( qp > fChargeThreshold )
328 {
329 // If we're above threshold, then we create a digit,
330 // and fill it with relevant information, including electronics.
168e9c4d 331 AliMUONDigit* d = new AliMUONDigit(detElemId,pad.GetManuId(),
332 pad.GetManuChannel(),cath);
333 d->SetPadXY(pad.GetIx(),pad.GetIy());
2a7d64a9 334 d->SetCharge(icharge);
32c9ead9 335 digits.Add(d);
336 }
337 it->Next();
338 }
339 delete it;
885d501b 340 }
341}
a9e2aefa 342
343
344