]>
Commit | Line | Data |
---|---|---|
57817f7c | 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 | /* $Id$ */ | |
16 | ||
b0f5e3fc | 17 | #include <stdio.h> |
8a00af9a | 18 | #include <stdlib.h> |
fd61217e | 19 | #include <iostream.h> |
57817f7c | 20 | #include <iomanip.h> |
b0f5e3fc | 21 | #include <TObjArray.h> |
1ca7869b | 22 | #include <TRandom.h> |
fd61217e | 23 | #include <TMath.h> |
b0f5e3fc | 24 | |
fd61217e | 25 | #include "AliITSmodule.h" |
57817f7c | 26 | #include "AliITSMapA2.h" |
9e8d6423 | 27 | #include "AliITSsegmentationSSD.h" |
28 | #include "AliITSresponseSSD.h" | |
b0f5e3fc | 29 | #include "AliITSdcsSSD.h" |
30 | #include "AliITS.h" | |
31 | #include "AliRun.h" | |
0315d466 | 32 | #include "AliITSgeom.h" |
57817f7c | 33 | #include "AliITSsimulationSSD.h" |
b0f5e3fc | 34 | |
35 | ClassImp(AliITSsimulationSSD); | |
fd61217e | 36 | //////////////////////////////////////////////////////////////////////// |
37 | // Version: 0 | |
38 | // Written by Enrico Fragiacomo | |
39 | // July 2000 | |
40 | // | |
41 | // AliITSsimulationSSD is the simulation of SSDs. | |
42 | ||
57817f7c | 43 | //---------------------------------------------------------------------- |
44 | AliITSsimulationSSD::AliITSsimulationSSD(){ | |
45 | //default Constructor | |
46 | ||
47 | fDCS = 0; | |
48 | fNstrips = GetSegmentation()->Npx(); | |
49 | fPitch = GetSegmentation()->Dpx(0); | |
50 | fDifConst[0] = fDifConst[1] = 0.0; | |
51 | fDriftVel[0] = fDriftVel[1] = 0.0; | |
52 | fMapA2 = 0; | |
53 | } | |
0315d466 | 54 | //---------------------------------------------------------------------- |
b0f5e3fc | 55 | AliITSsimulationSSD::AliITSsimulationSSD(AliITSsegmentation *seg, |
56 | AliITSresponse *resp){ | |
0315d466 | 57 | // Constructor |
b0f5e3fc | 58 | |
57817f7c | 59 | fSegmentation = seg; |
60 | fResponse = resp; | |
0315d466 | 61 | Float_t noise[2] = {0.,0.}; |
62 | fResponse->GetNoiseParam(noise[0],noise[1]); // retrieves noise parameters | |
57817f7c | 63 | fDCS = new AliITSdcsSSD(seg,resp); |
64 | ||
65 | fNstrips = GetSegmentation()->Npx(); | |
66 | fPitch = GetSegmentation()->Dpx(0); | |
67 | SetDriftVelocity(); // use default values in .h file | |
68 | SetIonizeE(); // use default values in .h file | |
69 | SetDiffConst(); // use default values in .h file | |
70 | fMapA2 = new AliITSMapA2(fSegmentation); | |
b0f5e3fc | 71 | } |
0315d466 | 72 | //______________________________________________________________________ |
57817f7c | 73 | AliITSsimulationSSD& AliITSsimulationSSD::operator=( |
74 | const AliITSsimulationSSD &s){ | |
0315d466 | 75 | // Operator = |
fd61217e | 76 | |
57817f7c | 77 | if(this==&s) return *this; |
78 | ||
79 | this->fDCS = new AliITSdcsSSD(*(s.fDCS)); | |
80 | this->fMapA2 = s.fMapA2; | |
81 | this->fNstrips = s.fNstrips; | |
82 | this->fPitch = s.fPitch; | |
83 | this->fIonE = s.fIonE; | |
84 | this->fDifConst[0] = s.fDifConst[0]; | |
85 | this->fDifConst[1] = s.fDifConst[1]; | |
86 | this->fDriftVel[0] = s.fDriftVel[0]; | |
87 | this->fDriftVel[1] = s.fDriftVel[1]; | |
b0f5e3fc | 88 | return *this; |
89 | } | |
57817f7c | 90 | //______________________________________________________________________ |
91 | AliITSsimulationSSD::AliITSsimulationSSD(const AliITSsimulationSSD &source){ | |
0315d466 | 92 | // copy constructor |
fd61217e | 93 | |
0315d466 | 94 | *this = source; |
b0f5e3fc | 95 | } |
0315d466 | 96 | //______________________________________________________________________ |
b0f5e3fc | 97 | AliITSsimulationSSD::~AliITSsimulationSSD() { |
0315d466 | 98 | // destructor |
fd61217e | 99 | delete fMapA2; |
b0f5e3fc | 100 | delete fDCS; |
0315d466 | 101 | } |
57817f7c | 102 | //______________________________________________________________________ |
b0f5e3fc | 103 | void AliITSsimulationSSD::DigitiseModule(AliITSmodule *mod,Int_t module, |
104 | Int_t dummy) { | |
0315d466 | 105 | // Digitizes hits for one SSD module |
106 | ||
107 | Int_t lay, lad, detect; | |
108 | AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS"); | |
109 | AliITSgeom *geom = aliITS->GetITSgeom(); | |
110 | geom->GetModuleId(module,lay, lad, detect); | |
57817f7c | 111 | if ( lay == 6 ) GetSegmentation()->SetLayer(6); |
112 | if ( lay == 5 ) GetSegmentation()->SetLayer(5); | |
0315d466 | 113 | |
114 | TObjArray *hits = mod->GetHits(); | |
57817f7c | 115 | Int_t nhits = hits->GetEntriesFast(); |
0315d466 | 116 | if (!nhits) return; |
fd61217e | 117 | |
0315d466 | 118 | Double_t x0=0.0, y0=0.0, z0=0.0; |
119 | Double_t x1=0.0, y1=0.0, z1=0.0; | |
120 | Double_t de=0.0; | |
57817f7c | 121 | Int_t maxNdigits = 2*fNstrips; |
0315d466 | 122 | Float_t **pList = new Float_t* [maxNdigits]; |
123 | memset(pList,0,sizeof(Float_t*)*maxNdigits); | |
124 | Int_t indexRange[4] = {0,0,0,0}; | |
57817f7c | 125 | static Bool_t first = kTRUE; |
126 | Int_t lasttrack = -2; | |
127 | Int_t idtrack = -2; | |
b0f5e3fc | 128 | |
0315d466 | 129 | for(Int_t i=0; i<nhits; i++) { |
130 | // LineSegmentL returns 0 if the hit is entering | |
131 | // If hits is exiting returns positions of entering and exiting hits | |
132 | // Returns also energy loss | |
133 | ||
134 | if (mod->LineSegmentL(i, x0, x1, y0, y1, z0, z1, de, idtrack)) { | |
135 | HitToDigit(module, x0, y0, z0, x1, y1, z1, de, indexRange, first); | |
fd61217e | 136 | |
0315d466 | 137 | if (lasttrack != idtrack || i==(nhits-1)) { |
138 | GetList(idtrack,pList,indexRange); | |
139 | first=kTRUE; | |
140 | } // end if | |
141 | lasttrack=idtrack; | |
142 | } // end if | |
143 | } // end loop over hits | |
fd61217e | 144 | |
0315d466 | 145 | ApplyNoise(); |
146 | ApplyCoupling(); | |
e8189707 | 147 | |
0315d466 | 148 | ChargeToSignal(pList); |
b0f5e3fc | 149 | |
0315d466 | 150 | fMapA2->ClearMap(); |
b0f5e3fc | 151 | } |
0315d466 | 152 | //---------------------------------------------------------------------- |
fd61217e | 153 | void AliITSsimulationSSD::HitToDigit(Int_t module, Double_t x0, Double_t y0, |
154 | Double_t z0, Double_t x1, Double_t y1, | |
155 | Double_t z1, Double_t de, | |
156 | Int_t *indexRange, Bool_t first) { | |
0315d466 | 157 | // Turns hits in SSD module into one or more digits. |
158 | ||
159 | Float_t tang[2] = {0.0,0.0}; | |
57817f7c | 160 | GetSegmentation()->Angles(tang[0], tang[1]);//stereo<<->tan(stereo)~=stereo |
0315d466 | 161 | Double_t x, y, z; |
162 | Double_t dex=0.0, dey=0.0, dez=0.0; | |
57817f7c | 163 | Double_t pairs; // pair generation energy per step. |
0315d466 | 164 | Double_t sigma[2] = {0.,0.};// standard deviation of the diffusion gaussian |
0315d466 | 165 | Double_t tdrift[2] = {0.,0.}; // time of drift |
0315d466 | 166 | Double_t w; |
167 | Double_t inf[2], sup[2], par0[2]; | |
57817f7c | 168 | |
0315d466 | 169 | // Steps in the module are determined "manually" (i.e. No Geant) |
170 | // NumOfSteps divide path between entering and exiting hits in steps | |
171 | Int_t numOfSteps = NumOfSteps(x1, y1, z1, dex, dey, dez); | |
fd61217e | 172 | |
0315d466 | 173 | // Enery loss is equally distributed among steps |
57817f7c | 174 | de = de/numOfSteps; |
175 | pairs = de/GetIonizeE(); // e-h pairs generated | |
0315d466 | 176 | |
177 | for(Int_t j=0; j<numOfSteps; j++) { // stepping | |
0315d466 | 178 | x = x0 + (j+0.5)*dex; |
179 | y = y0 + (j+0.5)*dey; | |
57817f7c | 180 | if ( y > (GetSegmentation()->Dy()/2+10)*1.0E-4 ) { |
0315d466 | 181 | // check if particle is within the detector |
182 | cout<<"AliITSsimulationSSD::HitToDigit: Warning: hit " | |
183 | "out of detector y0,y,dey,j =" | |
184 | <<y0<<","<<y<<","<<dey<<","<<j<<endl; | |
185 | return; | |
186 | } // end if | |
187 | z = z0 + (j+0.5)*dez; | |
188 | ||
189 | // calculate drift time | |
190 | // y is the minimum path | |
57817f7c | 191 | tdrift[0] = (y+(GetSegmentation()->Dy()*1.0E-4)/2)/GetDriftVelocity(0); |
192 | tdrift[1] = ((GetSegmentation()->Dy()*1.0E-4)/2-y)/GetDriftVelocity(1); | |
0315d466 | 193 | |
194 | for(Int_t k=0; k<2; k++) { // both sides remember: 0=Pside 1=Nside | |
195 | ||
196 | tang[k]=TMath::Tan(tang[k]); | |
197 | ||
198 | // w is the coord. perpendicular to the strips | |
199 | if(k==0) { | |
57817f7c | 200 | w = (x+(GetSegmentation()->Dx()*1.0E-4)/2) - |
201 | (z+(GetSegmentation()->Dz()*1.0E-4)/2)*tang[k]; | |
0315d466 | 202 | }else{ |
57817f7c | 203 | w = (x+(GetSegmentation()->Dx()*1.0E-4)/2) + |
204 | (z-(GetSegmentation()->Dz()*1.0E-4)/2)*tang[k]; | |
0315d466 | 205 | } // end if |
206 | w = w / (fPitch*1.0E-4); // w is converted in units of pitch | |
207 | ||
208 | if((w<(-0.5)) || (w>(fNstrips-0.5))) { | |
209 | // this check rejects hits in regions not covered by strips | |
210 | // 0.5 takes into account boundaries | |
211 | if(k==0) cout<<"AliITSsimulationSSD::HitToDigit: " | |
212 | "Warning: no strip in this region of P side" | |
213 | <<endl; | |
214 | else cout<<"AliITSsimulationSSD::HitToDigit: " | |
215 | "Warning: no strip in this region of N side"<<endl; | |
216 | return; | |
217 | } // end if | |
218 | ||
219 | // sigma is the standard deviation of the diffusion gaussian | |
0315d466 | 220 | if(tdrift[k]<0) return; |
57817f7c | 221 | sigma[k] = TMath::Sqrt(2*GetDiffConst(k)*tdrift[k]); |
0315d466 | 222 | sigma[k] = sigma[k] /(fPitch*1.0E-4); //units of Pitch |
223 | if(sigma[k]==0.0) { | |
224 | cout<<"AliITSsimulationSSD::DigitiseModule: Error: sigma=0" | |
225 | <<endl; | |
226 | exit(0); | |
227 | } // end if | |
228 | ||
229 | par0[k] = pairs; | |
230 | // we integrate the diffusion gaussian from -3sigma to 3sigma | |
231 | inf[k] = w - 3*sigma[k]; // 3 sigma from the gaussian average | |
232 | sup[k] = w + 3*sigma[k]; // 3 sigma from the gaussian average | |
233 | // IntegrateGaussian does the actual | |
234 | // integration of diffusion gaussian | |
235 | IntegrateGaussian(k, par0[k], w, sigma[k], inf[k], sup[k], | |
236 | indexRange, first); | |
237 | } // end for loop over side (0=Pside, 1=Nside) | |
238 | } // end stepping | |
239 | //delete seg; | |
b0f5e3fc | 240 | } |
57817f7c | 241 | //______________________________________________________________________ |
b0f5e3fc | 242 | void AliITSsimulationSSD::ApplyNoise() { |
0315d466 | 243 | // Apply Noise. |
fd61217e | 244 | |
57817f7c | 245 | Double_t signal; |
246 | Double_t noise[2] = {0.,0.}; | |
247 | Float_t a,b; | |
248 | fResponse->GetNoiseParam(a,b); // retrieves noise parameters | |
249 | noise[0] = (Double_t) a; noise[1] = (Double_t) b; | |
0315d466 | 250 | for(Int_t k=0;k<2;k++){ // both sides (0=Pside, 1=Nside) |
57817f7c | 251 | for(Int_t ix=0;ix<fNstrips;ix++){ // loop over strips |
252 | signal = fMapA2->GetSignal(k,ix); // retrieves signal from map | |
0315d466 | 253 | signal += gRandom->Gaus(0,noise[k]);// add noise to signal |
254 | if(signal<0.) signal=0.0; // in case noise is negative... | |
57817f7c | 255 | fMapA2->SetHit(k,ix,signal); // give back signal to map |
0315d466 | 256 | } // loop over strip |
257 | } // loop over k (P or N side) | |
b0f5e3fc | 258 | } |
0315d466 | 259 | //______________________________________________________________________ |
b0f5e3fc | 260 | void AliITSsimulationSSD::ApplyCoupling() { |
0315d466 | 261 | // Apply the effect of electronic coupling between channels |
57817f7c | 262 | Double_t signalLeft=0, signalRight=0; |
0315d466 | 263 | |
264 | for(Int_t ix=0;ix<fNstrips;ix++){ | |
57817f7c | 265 | if(ix>0.)signalLeft = fMapA2->GetSignal(0,ix-1)*fDCS->GetCouplingPL(); |
0315d466 | 266 | else signalLeft = 0.0; |
57817f7c | 267 | if(ix<(fNstrips-1)) signalRight = fMapA2->GetSignal(0,ix+1)* |
0315d466 | 268 | fDCS->GetCouplingPR(); |
269 | else signalRight = 0.0; | |
57817f7c | 270 | fMapA2->AddSignal(0,ix,signalLeft + signalRight); |
fd61217e | 271 | |
57817f7c | 272 | if(ix>0.) signalLeft = fMapA2->GetSignal(1,ix-1)*fDCS->GetCouplingNL(); |
0315d466 | 273 | else signalLeft = 0.0; |
57817f7c | 274 | if(ix<(fNstrips-1)) signalRight = fMapA2->GetSignal(1,ix+1)* |
0315d466 | 275 | fDCS->GetCouplingNR(); |
276 | else signalRight = 0.0; | |
57817f7c | 277 | fMapA2->AddSignal(1,ix,signalLeft + signalRight); |
0315d466 | 278 | } // loop over strips |
b0f5e3fc | 279 | } |
0315d466 | 280 | //______________________________________________________________________ |
fd61217e | 281 | Float_t AliITSsimulationSSD::F(Float_t av, Float_t x, Float_t s) { |
0315d466 | 282 | // Computes the integral of a gaussian using Error Function |
283 | Float_t sqrt2 = TMath::Sqrt(2.0); | |
284 | Float_t sigm2 = sqrt2*s; | |
285 | Float_t integral; | |
fd61217e | 286 | |
0315d466 | 287 | integral = 0.5 * TMath::Erf( (x - av) / sigm2); |
288 | return integral; | |
289 | } | |
290 | //______________________________________________________________________ | |
fd61217e | 291 | void AliITSsimulationSSD::IntegrateGaussian(Int_t k,Double_t par, Double_t w, |
292 | Double_t sigma, | |
293 | Double_t inf, Double_t sup, | |
294 | Int_t *indexRange, Bool_t first) { | |
0315d466 | 295 | // integrate the diffusion gaussian |
296 | // remind: inf and sup are w-3sigma and w+3sigma | |
297 | // we could define them here instead of passing them | |
298 | // this way we are free to introduce asimmetry | |
299 | ||
300 | Double_t a=0.0, b=0.0; | |
57817f7c | 301 | Double_t dXCharge1 = 0.0, dXCharge2 = 0.0; |
0315d466 | 302 | // dXCharge1 and 2 are the charge to two neighbouring strips |
303 | // Watch that we only involve at least two strips | |
304 | // Numbers greater than 2 of strips in a cluster depend on | |
305 | // geometry of the track and delta rays, not charge diffusion! | |
fd61217e | 306 | |
0315d466 | 307 | Double_t strip = TMath::Floor(w); // clostest strip on the left |
308 | ||
309 | if ( TMath::Abs((strip - w)) < 0.5) { | |
310 | // gaussian mean is closer to strip on the left | |
311 | a = inf; // integration starting point | |
312 | if((strip+0.5)<=sup) { | |
313 | // this means that the tail of the gaussian goes beyond | |
314 | // the middle point between strips ---> part of the signal | |
315 | // is given to the strip on the right | |
316 | b = strip + 0.5; // integration stopping point | |
317 | dXCharge1 = F( w, b, sigma) - F(w, a, sigma); | |
318 | dXCharge2 = F( w, sup, sigma) - F(w ,b, sigma); | |
319 | }else { | |
320 | // this means that all the charge is given to the strip on the left | |
321 | b = sup; | |
322 | dXCharge1 = 0.9973; // gaussian integral at 3 sigmas | |
323 | dXCharge2 = 0.0; | |
324 | } // end if | |
325 | ||
326 | dXCharge1 = par * dXCharge1;// normalize by mean of number of carriers | |
327 | dXCharge2 = par * dXCharge2; | |
328 | ||
329 | // for the time being, signal is the charge | |
330 | // in ChargeToSignal signal is converted in ADC channel | |
57817f7c | 331 | fMapA2->AddSignal(k,strip,dXCharge1); |
0315d466 | 332 | if(((Int_t) strip) < (fNstrips-1)) { |
333 | // strip doesn't have to be the last (remind: last=fNstrips-1) | |
334 | // otherwise part of the charge is lost | |
57817f7c | 335 | fMapA2->AddSignal(k,(strip+1),dXCharge2); |
0315d466 | 336 | } // end if |
fd61217e | 337 | |
0315d466 | 338 | if(dXCharge1 > 1.) { |
339 | if (first) { | |
57817f7c | 340 | indexRange[k*2+0] = indexRange[k*2+1]=(Int_t) strip; |
0315d466 | 341 | first=kFALSE; |
342 | } // end if first | |
343 | ||
344 | indexRange[k*2+0]=TMath::Min(indexRange[k*2+0],(Int_t) strip); | |
345 | indexRange[k*2+1]=TMath::Max(indexRange[k*2+1],(Int_t) strip); | |
346 | } // dXCharge > 1 e- | |
347 | ||
348 | }else{ | |
349 | // gaussian mean is closer to strip on the right | |
350 | strip++; // move to strip on the rigth | |
351 | b = sup; // now you know where to stop integrating | |
352 | if((strip-0.5)>=inf) { | |
353 | // tail of diffusion gaussian on the left goes left of | |
354 | // middle point between strips | |
355 | a = strip - 0.5; // integration starting point | |
356 | dXCharge1 = F(w, b, sigma) - F(w, a, sigma); | |
357 | dXCharge2 = F(w, a, sigma) - F(w, inf, sigma); | |
358 | }else { | |
359 | a = inf; | |
360 | dXCharge1 = 0.9973; // gaussian integral at 3 sigmas | |
361 | dXCharge2 = 0.0; | |
362 | } // end if | |
fd61217e | 363 | |
0315d466 | 364 | dXCharge1 = par * dXCharge1; // normalize by means of carriers |
365 | dXCharge2 = par * dXCharge2; | |
366 | ||
367 | // for the time being, signal is the charge | |
368 | // in ChargeToSignal signal is converted in ADC channel | |
57817f7c | 369 | fMapA2->AddSignal(k,strip,dXCharge1); |
0315d466 | 370 | if(((Int_t) strip) > 0) { |
371 | // strip doesn't have to be the first | |
372 | // otherwise part of the charge is lost | |
57817f7c | 373 | fMapA2->AddSignal(k,(strip-1),dXCharge2); |
0315d466 | 374 | } // end if |
fd61217e | 375 | |
0315d466 | 376 | if(dXCharge1 > 1.) { |
377 | if (first) { | |
378 | indexRange[k*2+0]=indexRange[k*2+1]=(Int_t) strip; | |
379 | first=kFALSE; | |
380 | } // end if first | |
381 | ||
382 | indexRange[k*2+0]=TMath::Min(indexRange[k*2+0],(Int_t) strip); | |
383 | indexRange[k*2+1]=TMath::Max(indexRange[k*2+1],(Int_t) strip); | |
384 | } // dXCharge > 1 e- | |
385 | } // end if | |
b0f5e3fc | 386 | } |
0315d466 | 387 | //______________________________________________________________________ |
fd61217e | 388 | Int_t AliITSsimulationSSD::NumOfSteps(Double_t x, Double_t y, Double_t z, |
0315d466 | 389 | Double_t & dex,Double_t & dey,Double_t & dez){ |
390 | // number of steps | |
391 | // it also returns steps for each coord | |
392 | //AliITSsegmentationSSD *seg = new AliITSsegmentationSSD(); | |
fd61217e | 393 | |
0315d466 | 394 | Double_t step = 25E-4; |
395 | //step = (Double_t) seg->GetStepSize(); // step size (cm) | |
396 | Int_t numOfSteps = (Int_t) (TMath::Sqrt(x*x+y*y+z*z)/step); | |
fd61217e | 397 | |
0315d466 | 398 | if (numOfSteps < 1) numOfSteps = 1; // one step, at least |
fd61217e | 399 | |
0315d466 | 400 | // we could condition the stepping depending on the incident angle |
401 | // of the track | |
402 | dex = x/numOfSteps; | |
403 | dey = y/numOfSteps; | |
404 | dez = z/numOfSteps; | |
b0f5e3fc | 405 | |
0315d466 | 406 | return numOfSteps; |
fd61217e | 407 | } |
0315d466 | 408 | //---------------------------------------------------------------------- |
409 | void AliITSsimulationSSD::GetList(Int_t label,Float_t **pList, | |
410 | Int_t *indexRange) { | |
411 | // loop over nonzero digits | |
412 | Int_t ix,globalIndex; | |
413 | Float_t signal=0.; | |
414 | Float_t highest,middle,lowest; | |
fd61217e | 415 | |
0315d466 | 416 | for(Int_t k=0; k<2; k++) { |
417 | for(ix=indexRange[k*2+0];ix<indexRange[k*2+1]+1;ix++){ | |
418 | if(indexRange[k*2+0]<indexRange[k*2+1]) | |
57817f7c | 419 | signal = fMapA2->GetSignal(k,ix); |
420 | ||
0315d466 | 421 | globalIndex = k*fNstrips+ix; // globalIndex starts from 0! |
422 | if(!pList[globalIndex]){ | |
423 | // | |
424 | //Create new list (6 elements-3 signals and 3 tracks+total sig) | |
425 | // | |
426 | pList[globalIndex] = new Float_t [6]; | |
427 | // set list to -1 | |
428 | *pList[globalIndex] = -2.; | |
429 | *(pList[globalIndex]+1) = -2.; | |
430 | *(pList[globalIndex]+2) = -2.; | |
431 | *(pList[globalIndex]+3) = 0.; | |
432 | *(pList[globalIndex]+4) = 0.; | |
433 | *(pList[globalIndex]+5) = 0.; | |
434 | *pList[globalIndex] = (float)label; | |
435 | *(pList[globalIndex]+3) = signal; | |
436 | }else{ | |
437 | // check the signal magnitude | |
438 | highest = *(pList[globalIndex]+3); | |
439 | middle = *(pList[globalIndex]+4); | |
440 | lowest = *(pList[globalIndex]+5); | |
441 | signal -= (highest+middle+lowest); | |
442 | // | |
443 | // compare the new signal with already existing list | |
444 | // | |
445 | if(signal<lowest) continue; // neglect this track | |
446 | if (signal>highest){ | |
447 | *(pList[globalIndex]+5) = middle; | |
448 | *(pList[globalIndex]+4) = highest; | |
449 | *(pList[globalIndex]+3) = signal; | |
450 | *(pList[globalIndex]+2) = *(pList[globalIndex]+1); | |
451 | *(pList[globalIndex]+1) = *pList[globalIndex]; | |
452 | *pList[globalIndex] = label; | |
453 | }else if (signal>middle){ | |
454 | *(pList[globalIndex]+5) = middle; | |
455 | *(pList[globalIndex]+4) = signal; | |
456 | *(pList[globalIndex]+2) = *(pList[globalIndex]+1); | |
457 | *(pList[globalIndex]+1) = label; | |
458 | }else{ | |
459 | *(pList[globalIndex]+5) = signal; | |
460 | *(pList[globalIndex]+2) = label; | |
461 | } // end if | |
462 | } // end if | |
463 | } // end of loop pixels in x | |
464 | } // end of loop over pixels in z | |
fd61217e | 465 | } |
0315d466 | 466 | //---------------------------------------------------------------------- |
fd61217e | 467 | void AliITSsimulationSSD::ChargeToSignal(Float_t **pList) { |
0315d466 | 468 | // charge to signal |
469 | AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS"); | |
470 | Float_t threshold = 0.; | |
471 | Int_t digits[3], tracks[3],hits[3],gi,j1; | |
472 | Float_t charges[3]; | |
473 | Float_t signal,phys; | |
474 | Float_t noise[2] = {0.,0.}; | |
475 | ||
476 | fResponse->GetNoiseParam(noise[0],noise[1]); | |
fd61217e | 477 | |
0315d466 | 478 | for(Int_t k=0;k<2;k++){ // both sides (0=Pside, 1=Nside) |
479 | ||
480 | // Threshold for zero-suppression | |
481 | // It can be defined in AliITSresponseSSD | |
482 | // threshold = (Float_t)fResponse->MinVal(k); | |
483 | // I prefer to think adjusting the threshold "manually", looking | |
484 | // at the scope, and considering noise standard deviation | |
485 | threshold = 4.0*noise[k]; // 4 times noise is a choice | |
486 | for(Int_t ix=0;ix<fNstrips;ix++){ // loop over strips | |
487 | ||
488 | signal = (Float_t) fMapA2->GetSignal(k,ix); | |
0315d466 | 489 | gi =k*fNstrips+ix; // global index |
490 | if (signal > threshold) { | |
491 | digits[0]=k; | |
492 | digits[1]=ix; | |
493 | ||
494 | // convert to ADC signal | |
495 | // conversion factor are rather arbitrary (need tuning) | |
496 | // minimum ionizing particle--> ~30000 pairs--> ADC channel 50 | |
497 | signal = signal*50.0/30000.0; | |
498 | if(signal>1000.) signal = 1000.0;//if exceeding, accumulate | |
499 | // last one | |
500 | digits[2]=(Int_t) signal; | |
0315d466 | 501 | for(j1=0;j1<3;j1++){ |
502 | if (pList[gi]) { | |
503 | tracks[j1] = (Int_t)(*(pList[gi]+j1)); | |
504 | } else { | |
505 | tracks[j1]=-2; //noise | |
506 | } // end if pList | |
507 | charges[j1] = 0; | |
508 | } // end for j1 | |
509 | ||
510 | phys=0; | |
511 | ||
512 | hits[0]=0; | |
513 | hits[1]=0; | |
514 | hits[2]=0; | |
515 | // finally add digit | |
516 | aliITS->AddSimDigit(2,phys,digits,tracks,hits,charges); | |
0315d466 | 517 | } // end if signal > threshold |
518 | if(pList[gi]) delete [] pList[gi]; | |
519 | } // end for ix | |
520 | } // end for k | |
521 | delete [] pList; | |
b0f5e3fc | 522 | } |
57817f7c | 523 | //______________________________________________________________________ |
524 | void AliITSsimulationSSD::Print(ostream *os){ | |
525 | //Standard output format for this class | |
526 | ||
527 | //AliITSsimulation::Print(os); | |
528 | *os << fNstrips <<","<< fPitch <<","<< fIonE <<","; | |
529 | *os << fDifConst[0] <<","<< fDifConst[1] <<","; | |
530 | *os << fDriftVel[0] <<","<< fDriftVel[1]; | |
531 | //*os <<","; fDCS->Print(os); | |
532 | //*os <<","; fMapA2->Print(os); | |
533 | } | |
534 | //______________________________________________________________________ | |
535 | void AliITSsimulationSSD::Read(istream *is){ | |
536 | // Standard output streaming function. | |
537 | ||
538 | //AliITSsimulation::Read(is); | |
539 | *is >> fNstrips >> fPitch >> fIonE; | |
540 | *is >> fDifConst[0] >> fDifConst[1]; | |
541 | *is >> fDriftVel[0] >> fDriftVel[1]; | |
542 | //fDCS->Read(is); | |
543 | //fMapA2->Read(is); | |
544 | } | |
545 | //______________________________________________________________________ | |
546 | ostream &operator<<(ostream &os,AliITSsimulationSSD &source){ | |
547 | // Standard output streaming function. | |
548 | ||
549 | source.Print(&os); | |
550 | return os; | |
551 | } | |
552 | //______________________________________________________________________ | |
553 | istream &operator>>(istream &os,AliITSsimulationSSD &source){ | |
554 | // Standard output streaming function. | |
555 | ||
556 | source.Read(&os); | |
557 | return os; | |
558 | } |