Updates to RAW package. Used during the Computing DC.
[u/mrichter/AliRoot.git] / MUON / AliMUONChamber.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 **************************************************************************/
2682e810 15
88cb7938 16/* $Id$ */
a9e2aefa 17
30178c30 18// --- ROOT includes ---
19#include <TRandom.h>
20#include <TMath.h>
a713db22 21#include "AliRun.h"
22
30178c30 23
681d067b 24// --- MUON includes ---
a713db22 25#include "AliMUON.h"
a9e2aefa 26#include "AliMUONChamber.h"
e118b27e 27#include "AliMUONGeometryModule.h"
a713db22 28#include "AliMUONHit.h"
8c343c7c 29#include "AliLog.h"
a9e2aefa 30
a9e2aefa 31ClassImp(AliMUONChamber)
32
30178c30 33AliMUONChamber::AliMUONChamber()
34 : TObject(),
35 fId(0),
36 fdGas(0.),
37 fdAlu(0.),
38 fZ(0.),
39 fnsec(1),
40 frMin(0.),
41 frMax(0.),
42 fCurrentCorrel(1), // to avoid mistakes if ChargeCorrelInit is not called
43 fSegmentation(0),
a713db22 44 fSegmentation2(0),
30178c30 45 fResponse(0),
a713db22 46 fGeometry(0),
47 fMUON(0)
d81db581 48{
49// Default constructor
d81db581 50}
51
a713db22 52//_______________________________________________________
30178c30 53AliMUONChamber::AliMUONChamber(Int_t id)
54 : TObject(),
55 fId(id),
56 fdGas(0.),
57 fdAlu(0.),
58 fZ(0.),
59 fnsec(1),
60 frMin(0.),
61 frMax(0.),
62 fCurrentCorrel(1), // to avoid mistakes if ChargeCorrelInit is not called
63 fSegmentation(0),
a713db22 64 fSegmentation2(0),
30178c30 65 fResponse(0),
a713db22 66 fGeometry(0),
67 fMUON(0)
a9e2aefa 68{
a713db22 69
70 // muon
71 fMUON = (AliMUON*)gAlice->GetModule("MUON");
72 if (!fMUON) {
73 AliFatal("MUON detector not defined.");
74 return;
75 }
d81db581 76// Construtor with chamber id
a9e2aefa 77 fSegmentation = new TObjArray(2);
cd4df77b 78 fSegmentation->AddAt(0,0);
79 fSegmentation->AddAt(0,1);
a713db22 80
81 // new segmentation
82 fSegmentation2 = new TObjArray(2);
83 fSegmentation2->AddAt(0,0);
84 fSegmentation2->AddAt(0,1);
85
e118b27e 86 fGeometry = new AliMUONGeometryModule(fId);
a713db22 87
30178c30 88}
89
a713db22 90//_______________________________________________________
30178c30 91AliMUONChamber::AliMUONChamber(const AliMUONChamber& rChamber)
92 : TObject(rChamber)
93{
a713db22 94 // Protected copy constructor
30178c30 95
8c343c7c 96 AliFatal("Not implemented.");
a713db22 97 // Dummy copy constructor
a9e2aefa 98}
99
a713db22 100//_______________________________________________________
a9e2aefa 101AliMUONChamber::~AliMUONChamber()
102{
a713db22 103 // Destructor
104 if (fMUON->WhichSegmentation() == 1) {
105 if (fSegmentation) {
106 fSegmentation->Delete();
107 delete fSegmentation;
108 }
109 } else {
110 if (fSegmentation2) {
111 fSegmentation2->Delete();
112 delete fSegmentation2;
113 }
c2c0190f 114 }
c6df4ef2 115 delete fGeometry;
a9e2aefa 116}
117
a713db22 118//_______________________________________________________
30178c30 119AliMUONChamber & AliMUONChamber::operator =(const AliMUONChamber& rhs)
390151b8 120{
a713db22 121 // Protected assignement operator
a9e2aefa 122
30178c30 123 if (this == &rhs) return *this;
124
8c343c7c 125 AliFatal("Not implemented.");
30178c30 126
127 return *this;
128}
a9e2aefa 129
a713db22 130//_______________________________________________________
d1cd2474 131Bool_t AliMUONChamber::IsSensId(Int_t volId) const
132{
a713db22 133 // Returns true if the volume specified by volId is in the list
134 // of sesitive volumes for this chamber
d1cd2474 135
136 return fGeometry->IsSensitiveVolume(volId);
137}
138
a713db22 139//_______________________________________________________
a9e2aefa 140void AliMUONChamber::Init()
141{
a713db22 142 // Initalisation ..
143 //
144 // ... for chamber segmentation
145
146 if (fSegmentation->At(0))
2682e810 147 ((AliSegmentation *) fSegmentation->At(0))->Init(fId);
a9e2aefa 148
a713db22 149 if (fnsec==2) {
150 if (fSegmentation->At(1))
151 ((AliSegmentation *) fSegmentation->At(1))->Init(fId);
152 }
153
154
a9e2aefa 155}
156
a713db22 157//_________________________________________________________________
a9e2aefa 158Int_t AliMUONChamber::SigGenCond(Float_t x, Float_t y, Float_t z)
159{
a713db22 160 // Ask segmentation if signal should be generated
a9e2aefa 161
a713db22 162 if (fnsec==1) {
163 return ((AliSegmentation*) fSegmentation->At(0))
164 ->SigGenCond(x, y, z) ;
165 } else {
166 return (((AliSegmentation*) fSegmentation->At(0))
167 ->SigGenCond(x, y, z)) ||
168 (((AliSegmentation*) fSegmentation->At(1))
169 ->SigGenCond(x, y, z)) ;
170 }
171
172}
a9e2aefa 173
a713db22 174//_________________________________________________________________
a9e2aefa 175void AliMUONChamber::SigGenInit(Float_t x, Float_t y, Float_t z)
176{
a713db22 177 //
178 // Initialisation of segmentation for hit
179 //
180
181
182 if (fnsec==1) {
183 ((AliSegmentation*) fSegmentation->At(0))->SigGenInit(x, y, z) ;
184 } else {
185 ((AliSegmentation*) fSegmentation->At(0))->SigGenInit(x, y, z) ;
186 ((AliSegmentation*) fSegmentation->At(1))->SigGenInit(x, y, z) ;
187 }
188
a9e2aefa 189}
190
a713db22 191//_____________________________________________________
681d067b 192void AliMUONChamber::ChargeCorrelationInit() {
a713db22 193 // Initialisation of charge correlation for current hit
194 // the value is stored, and then used by Disintegration
195 if (fnsec==1)
681d067b 196 fCurrentCorrel =1;
a713db22 197 else
681d067b 198 // exponential is here to avoid eventual problems in 0
16d57990 199 // factor 2 because chargecorrel is q1/q2 and not q1/qtrue
200 fCurrentCorrel = TMath::Exp(gRandom->Gaus(0,fResponse->ChargeCorrel()/2));
681d067b 201}
202
a713db22 203//_______________________________________________________
24fe6002 204void AliMUONChamber::DisIntegration(Float_t eloss, Float_t /*tof*/,
802a864d 205 Float_t xhit, Float_t yhit, Float_t zhit,
a9e2aefa 206 Int_t& nnew,Float_t newclust[6][500])
207{
a713db22 208 //
209 // Generates pad hits (simulated cluster)
210 // using the segmentation and the response model
211 Float_t dx, dy;
212 //
213 // Width of the integration area
214 //
215 dx=fResponse->SigmaIntegration()*fResponse->ChargeSpreadX();
216 dy=fResponse->SigmaIntegration()*fResponse->ChargeSpreadY();
217 //
218 // Get pulse height from energy loss
219 Float_t qtot = fResponse->IntPH(eloss);
220 //
221 // Loop Over Pads
a9e2aefa 222
a713db22 223 Float_t qp;
224 nnew=0;
ef495f13 225
a713db22 226 // Cathode plane loop
227 for (Int_t i=1; i<=fnsec; i++) {
228 Float_t qcath = qtot * (i==1? fCurrentCorrel : 1/fCurrentCorrel);
229 AliSegmentation* segmentation=
230 (AliSegmentation*) fSegmentation->At(i-1);
231 for (segmentation->FirstPad(xhit, yhit, zhit, dx, dy);
232 segmentation->MorePads();
233 segmentation->NextPad())
234 {
235 qp=fResponse->IntXY(segmentation);
236 qp=TMath::Abs(qp);
237 //
238 //
239 if (qp > 1.e-4)
240 {
241 if (nnew >= 500) // Perform a bounds check on nnew since it is assumed
242 // newclust only contains 500 elements.
243 {
244 AliError("Limit of 500 pad responses reached.");
245 return;
246 };
247 //
248 // --- store signal information
249 newclust[0][nnew]=qcath; // total charge
250 newclust[1][nnew]=segmentation->Ix(); // ix-position of pad
251 newclust[2][nnew]=segmentation->Iy(); // iy-position of pad
252 newclust[3][nnew]=qp * qcath; // charge on pad
253 newclust[4][nnew]=segmentation->ISector(); // sector id
254 newclust[5][nnew]=(Float_t) i; // counter
255 nnew++;
ef495f13 256
a713db22 257 }
258 } // Pad loop
259 } // Cathode plane loop
a9e2aefa 260}
261
a713db22 262//_______________________________________________________
263void AliMUONChamber::InitGeo(Float_t /*zpos*/)
264{
265 // sensitive gas gap
266 fdGas= 0.5;
267 // 3% radiation length of aluminum (X0=8.9 cm)
268 fdAlu= 3.0/100*8.9;
269}
270//_______________________________________________________
271//
272// NEW SEGMENTATION
273//_______________________________________________________
274void AliMUONChamber::Init(Int_t flag)
275{
276 // Initalisation ..
277 //
278 // ... for chamber segmentation
a9e2aefa 279
a713db22 280 if (!flag) AliFatal("wrong segmentation type.");
a9e2aefa 281
a713db22 282
283 if (fSegmentation2->At(0))
284 ((AliMUONGeometrySegmentation*) fSegmentation2->At(0))->Init(fId);
285
286 if (fnsec==2) {
287 if (fSegmentation2->At(1))
288 ((AliMUONGeometrySegmentation*) fSegmentation2->At(1))->Init(fId);
289 }
290}
291
292//_________________________________________________________________
293Int_t AliMUONChamber::SigGenCond(AliMUONHit *hit)
294{
295 // Ask segmentation if signal should be generated
296
297 Float_t x = hit->X();
298 Float_t y = hit->Y();
299 Float_t z = hit->Z();
300 Int_t id = hit->DetElemId();
301
302 if (fnsec==1) {
303 return ((AliMUONGeometrySegmentation*)fSegmentation2->At(0))->SigGenCond(id, x, y, z);
304 } else {
305 return (((AliMUONGeometrySegmentation*) fSegmentation2->At(0))
306 ->SigGenCond(id, x, y, z)) ||
307 (((AliMUONGeometrySegmentation*) fSegmentation2->At(1))
308 ->SigGenCond(id, x, y, z)) ;
309 }
310}
311
312//_________________________________________________________________
313void AliMUONChamber::SigGenInit(AliMUONHit *hit)
a9e2aefa 314{
a713db22 315 //
316 // Initialisation of segmentation for hit
317 //
318 Float_t x = hit->X();
319 Float_t y = hit->Y();
320 Float_t z = hit->Z();
321 Int_t id = hit->DetElemId();
322
323 if (fnsec==1) {
324 ((AliMUONGeometrySegmentation*) fSegmentation2->At(0))->SigGenInit(id, x, y, z) ;
325 } else {
326 ((AliMUONGeometrySegmentation*) fSegmentation2->At(0))->SigGenInit(id, x, y, z) ;
327 ((AliMUONGeometrySegmentation*) fSegmentation2->At(1))->SigGenInit(id, x, y, z) ;
328 }
a9e2aefa 329}
330
a713db22 331//_______________________________________________________
332void AliMUONChamber::DisIntegration(AliMUONHit *hit,
333 Int_t& nnew,Float_t newclust[6][500])
334{
335 //
336 // Generates pad hits (simulated cluster)
337 // using the segmentation and the response model
338 Float_t dx, dy;
339
340 Float_t xhit = hit->X();
341 Float_t yhit = hit->Y();
342 Float_t zhit = hit->Z();
343 Int_t id = hit->DetElemId();
344 Float_t eloss = hit->Eloss();
a9e2aefa 345
a713db22 346 //
347 // Width of the integration area
348 //
349 dx=fResponse->SigmaIntegration()*fResponse->ChargeSpreadX();
350 dy=fResponse->SigmaIntegration()*fResponse->ChargeSpreadY();
351 //
352 // Get pulse height from energy loss
353 Float_t qtot = fResponse->IntPH(eloss);
354 //
355 // Loop Over Pads
356
357 Float_t qp;
358 nnew=0;
359
360 // Cathode plane loop
361 for (Int_t i=1; i<=fnsec; i++) {
362 Float_t qcath = qtot * (i==1? fCurrentCorrel : 1/fCurrentCorrel);
363
364 AliMUONGeometrySegmentation* segmentation=
365 (AliMUONGeometrySegmentation*) fSegmentation2->At(i-1);
366
367 for (segmentation->FirstPad(id, xhit, yhit, zhit, dx, dy);
368 segmentation->MorePads(id);
369 segmentation->NextPad(id))
370 {
371 qp=fResponse->IntXY(id, segmentation);
372 qp=TMath::Abs(qp);
373 //
374 //
375 if (qp > 1.e-4)
376 {
377 if (nnew >= 500) // Perform a bounds check on nnew since it is assumed
378 // newclust only contains 500 elements.
379 {
380 AliError("Limit of 500 pad responses reached.");
381 return;
382 };
383 //
384 // --- store signal information
385 newclust[0][nnew]=qcath; // total charge
386 newclust[1][nnew]=segmentation->Ix(); // ix-position of pad
387 newclust[2][nnew]=segmentation->Iy(); // iy-position of pad
388 newclust[3][nnew]=qp * qcath; // charge on pad
389 newclust[4][nnew]=segmentation->ISector(); // sector id
390 newclust[5][nnew]=(Float_t) i; // counter
391 nnew++;
392
393 }
394 } // Pad loop
395 } // Cathode plane loop
396}