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 // --- ROOT includes ---
24 // --- MUON includes ---
26 #include "AliMUONChamber.h"
27 #include "AliMUONGeometryModule.h"
28 #include "AliMUONHit.h"
31 ClassImp(AliMUONChamber)
33 AliMUONChamber::AliMUONChamber()
42 fCurrentCorrel(1), // to avoid mistakes if ChargeCorrelInit is not called
49 // Default constructor
52 //_______________________________________________________
53 AliMUONChamber::AliMUONChamber(Int_t id)
62 fCurrentCorrel(1), // to avoid mistakes if ChargeCorrelInit is not called
71 fMUON = (AliMUON*)gAlice->GetModule("MUON");
73 AliFatal("MUON detector not defined.");
76 // Construtor with chamber id
77 fSegmentation = new TObjArray(2);
78 fSegmentation->AddAt(0,0);
79 fSegmentation->AddAt(0,1);
82 fSegmentation2 = new TObjArray(2);
83 fSegmentation2->AddAt(0,0);
84 fSegmentation2->AddAt(0,1);
86 fGeometry = new AliMUONGeometryModule(fId);
90 //_______________________________________________________
91 AliMUONChamber::AliMUONChamber(const AliMUONChamber& rChamber)
94 // Protected copy constructor
96 AliFatal("Not implemented.");
97 // Dummy copy constructor
100 //_______________________________________________________
101 AliMUONChamber::~AliMUONChamber()
104 if (fMUON->WhichSegmentation() == 1) {
106 fSegmentation->Delete();
107 delete fSegmentation;
110 if (fSegmentation2) {
111 fSegmentation2->Delete();
112 delete fSegmentation2;
118 //_______________________________________________________
119 AliMUONChamber & AliMUONChamber::operator =(const AliMUONChamber& rhs)
121 // Protected assignement operator
123 if (this == &rhs) return *this;
125 AliFatal("Not implemented.");
130 //_______________________________________________________
131 Bool_t AliMUONChamber::IsSensId(Int_t volId) const
133 // Returns true if the volume specified by volId is in the list
134 // of sesitive volumes for this chamber
136 return fGeometry->IsSensitiveVolume(volId);
139 //_______________________________________________________
140 void AliMUONChamber::Init()
144 // ... for chamber segmentation
146 if (fSegmentation->At(0))
147 ((AliSegmentation *) fSegmentation->At(0))->Init(fId);
150 if (fSegmentation->At(1))
151 ((AliSegmentation *) fSegmentation->At(1))->Init(fId);
157 //_________________________________________________________________
158 Int_t AliMUONChamber::SigGenCond(Float_t x, Float_t y, Float_t z)
160 // Ask segmentation if signal should be generated
163 return ((AliSegmentation*) fSegmentation->At(0))
164 ->SigGenCond(x, y, z) ;
166 return (((AliSegmentation*) fSegmentation->At(0))
167 ->SigGenCond(x, y, z)) ||
168 (((AliSegmentation*) fSegmentation->At(1))
169 ->SigGenCond(x, y, z)) ;
174 //_________________________________________________________________
175 void AliMUONChamber::SigGenInit(Float_t x, Float_t y, Float_t z)
178 // Initialisation of segmentation for hit
183 ((AliSegmentation*) fSegmentation->At(0))->SigGenInit(x, y, z) ;
185 ((AliSegmentation*) fSegmentation->At(0))->SigGenInit(x, y, z) ;
186 ((AliSegmentation*) fSegmentation->At(1))->SigGenInit(x, y, z) ;
191 //_____________________________________________________
192 void AliMUONChamber::ChargeCorrelationInit() {
193 // Initialisation of charge correlation for current hit
194 // the value is stored, and then used by Disintegration
198 // exponential is here to avoid eventual problems in 0
199 // factor 2 because chargecorrel is q1/q2 and not q1/qtrue
200 fCurrentCorrel = TMath::Exp(gRandom->Gaus(0,fResponse->ChargeCorrel()/2));
203 //_______________________________________________________
204 void AliMUONChamber::DisIntegration(Float_t eloss, Float_t /*tof*/,
205 Float_t xhit, Float_t yhit, Float_t zhit,
206 Int_t& nnew,Float_t newclust[6][500])
209 // Generates pad hits (simulated cluster)
210 // using the segmentation and the response model
213 // Width of the integration area
215 dx=fResponse->SigmaIntegration()*fResponse->ChargeSpreadX();
216 dy=fResponse->SigmaIntegration()*fResponse->ChargeSpreadY();
218 // Get pulse height from energy loss
219 Float_t qtot = fResponse->IntPH(eloss);
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())
235 qp=fResponse->IntXY(segmentation);
241 if (nnew >= 500) // Perform a bounds check on nnew since it is assumed
242 // newclust only contains 500 elements.
244 AliError("Limit of 500 pad responses reached.");
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
259 } // Cathode plane loop
262 //_______________________________________________________
263 void AliMUONChamber::InitGeo(Float_t /*zpos*/)
267 // 3% radiation length of aluminum (X0=8.9 cm)
270 //_______________________________________________________
273 //_______________________________________________________
274 void AliMUONChamber::Init(Int_t flag)
278 // ... for chamber segmentation
280 if (!flag) AliFatal("wrong segmentation type.");
283 if (fSegmentation2->At(0))
284 ((AliMUONGeometrySegmentation*) fSegmentation2->At(0))->Init(fId);
287 if (fSegmentation2->At(1))
288 ((AliMUONGeometrySegmentation*) fSegmentation2->At(1))->Init(fId);
292 //_________________________________________________________________
293 Int_t AliMUONChamber::SigGenCond(AliMUONHit *hit)
295 // Ask segmentation if signal should be generated
297 Float_t x = hit->X();
298 Float_t y = hit->Y();
299 Float_t z = hit->Z();
300 Int_t id = hit->DetElemId();
303 return ((AliMUONGeometrySegmentation*)fSegmentation2->At(0))->SigGenCond(id, x, y, z);
305 return (((AliMUONGeometrySegmentation*) fSegmentation2->At(0))
306 ->SigGenCond(id, x, y, z)) ||
307 (((AliMUONGeometrySegmentation*) fSegmentation2->At(1))
308 ->SigGenCond(id, x, y, z)) ;
312 //_________________________________________________________________
313 void AliMUONChamber::SigGenInit(AliMUONHit *hit)
316 // Initialisation of segmentation for hit
318 Float_t x = hit->X();
319 Float_t y = hit->Y();
320 Float_t z = hit->Z();
321 Int_t id = hit->DetElemId();
324 ((AliMUONGeometrySegmentation*) fSegmentation2->At(0))->SigGenInit(id, x, y, z) ;
326 ((AliMUONGeometrySegmentation*) fSegmentation2->At(0))->SigGenInit(id, x, y, z) ;
327 ((AliMUONGeometrySegmentation*) fSegmentation2->At(1))->SigGenInit(id, x, y, z) ;
331 //_______________________________________________________
332 void AliMUONChamber::DisIntegration(AliMUONHit *hit,
333 Int_t& nnew,Float_t newclust[6][500])
336 // Generates pad hits (simulated cluster)
337 // using the segmentation and the response model
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();
347 // Width of the integration area
349 dx=fResponse->SigmaIntegration()*fResponse->ChargeSpreadX();
350 dy=fResponse->SigmaIntegration()*fResponse->ChargeSpreadY();
352 // Get pulse height from energy loss
353 Float_t qtot = fResponse->IntPH(eloss);
360 // Cathode plane loop
361 for (Int_t i=1; i<=fnsec; i++) {
362 Float_t qcath = qtot * (i==1? fCurrentCorrel : 1/fCurrentCorrel);
364 AliMUONGeometrySegmentation* segmentation=
365 (AliMUONGeometrySegmentation*) fSegmentation2->At(i-1);
367 for (segmentation->FirstPad(id, xhit, yhit, zhit, dx, dy);
368 segmentation->MorePads(id);
369 segmentation->NextPad(id))
371 qp=fResponse->IntXY(id, segmentation);
377 if (nnew >= 500) // Perform a bounds check on nnew since it is assumed
378 // newclust only contains 500 elements.
380 AliError("Limit of 500 pad responses reached.");
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
395 } // Cathode plane loop