New LinkDef (cmake)
[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
ccea41d4 88//__________________________________________________________________________
2a7d64a9 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
116//__________________________________________________________________________
a713db22 117AliMUONResponseV0::~AliMUONResponseV0()
118{
9265505b 119/// Destructor
120
885d501b 121 AliDebug(1,"");
a713db22 122 delete fMathieson;
123}
f29ba3e1 124
885d501b 125//______________________________________________________________________________
126void
2a7d64a9 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
143//______________________________________________________________________________
144void
885d501b 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;
885d501b 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);
239 TVector2 hitPoint(locX,locY);
240 AliMpPad pad = seg->PadByPosition(hitPoint,kFALSE);
5fe36481 241 if(pad.IsValid()){
242 Double_t locYCenter = pad.Position().Y();
243 Double_t locXCenter = pad.Position().X();
244 const AliMUONGeometryTransformer* transformer = muon()->GetGeometryTransformer();
245 transformer->Local2Global(detElemId,locXCenter,locYCenter,locZ,globXCenter,globYCenter,globZ);
246 for(Int_t itime = 0; itime<para; itime++)
247 termA *= 10.0;
248
249 for(Int_t itime = 0; itime<Int_t((2*para) + 1); itime++)
250 termB *= (hitY - globYCenter) ;
251
252 hitY = hitY + termA*termB;
253 }// if the pad is a valid one
d1bb9a6f 254 }// if bending plane
255 }// cathode loop
256 }// if para > 0 condn
257 }// if tail effect
258
885d501b 259 // Use that (dx,dy) to specify the area upon which
260 // we will iterate to spread charge into.
261 Double_t x,y,z;
d1bb9a6f 262 Global2Local(detElemId,hitX,hitY,hitZ,x,y,z);
885d501b 263 x = GetAnod(x);
264 TVector2 hitPosition(x,y);
265 AliMpArea area(hitPosition,TVector2(dx,dy));
266
32c9ead9 267 // Get pulse height from energy loss.
885d501b 268 Float_t qtot = IntPH(hit.Eloss());
269
32c9ead9 270 // Get the charge correlation between cathodes.
885d501b 271 Float_t currentCorrel = TMath::Exp(gRandom->Gaus(0.0,ChargeCorrel()/2.0));
a9e2aefa 272
866c3232 273 for ( Int_t cath = AliMp::kCath0; cath <= AliMp::kCath1; ++cath )
885d501b 274 {
275 Float_t qcath = qtot * ( cath == 0 ? currentCorrel : 1.0/currentCorrel);
276
885d501b 277 // Get an iterator to loop over pads, within the given area.
32c9ead9 278 const AliMpVSegmentation* seg =
866c3232 279 AliMpSegmentation::Instance()
280 ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cath));
885d501b 281
32c9ead9 282 AliMpVPadIterator* it = seg->CreateIterator(area);
283
284 if (!it)
285 {
286 AliError(Form("Could not get iterator for detElemId %d",detElemId));
287 return;
288 }
289
290 // Start loop over pads.
291 it->First();
292
293 if ( it->IsDone() )
294 {
295 // Exceptional case : iterator is built, but is invalid from the start.
296 AliMpPad pad = seg->PadByPosition(area.Position(),kFALSE);
297 if ( pad.IsValid() )
885d501b 298 {
32c9ead9 299 AliWarning(Form("Got an invalid iterator bug (area.Position() is within "
300 " DE but the iterator is void) for detElemId %d cath %d",
301 detElemId,cath));
885d501b 302 }
32c9ead9 303 else
885d501b 304 {
32c9ead9 305 AliError(Form("Got an invalid iterator bug for detElemId %d cath %d."
306 "Might be a bad hit ? area.Position()=(%e,%e) "
307 "Dimensions()=(%e,%e)",
308 detElemId,cath,area.Position().X(),area.Position().Y(),
309 area.Dimensions().X(),area.Dimensions().Y()));
885d501b 310 }
311 delete it;
32c9ead9 312 return;
313 }
314
315 while ( !it->IsDone() )
316 {
317 // For each pad given by the iterator, compute the charge of that
318 // pad, according to the Mathieson distribution.
319 AliMpPad pad = it->CurrentItem();
320 TVector2 lowerLeft(hitPosition-pad.Position()-pad.Dimensions());
321 TVector2 upperRight(lowerLeft + pad.Dimensions()*2.0);
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