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 #include <Riostream.h>
29 #include "AliITSMapA2.h"
30 #include "AliITSRawData.h"
31 #include "AliITSdigitSPD.h"
32 #include "AliITSetfSDD.h"
33 #include "AliITSmodule.h"
34 #include "AliITSpList.h"
35 #include "AliITSresponseSDD.h"
36 #include "AliITSCalibrationSDD.h"
37 #include "AliITSsegmentationSDD.h"
38 #include "AliITSsimulationSDD.h"
42 ClassImp(AliITSsimulationSDD)
43 ////////////////////////////////////////////////////////////////////////
45 // Written by Piergiorgio Cerello //
46 // November 23 1999 //
48 // AliITSsimulationSDD is the simulation of SDDs. //
49 ////////////////////////////////////////////////////////////////////////
51 //______________________________________________________________________
52 Int_t power(Int_t b, Int_t e) {
53 // compute b to the e power, where both b and e are Int_ts.
56 for(i=0; i<e; i++) power *= b;
59 //______________________________________________________________________
60 void FastFourierTransform(AliITSetfSDD *alisddetf,Double_t *real,
61 Double_t *imag,Int_t direction) {
62 // Do a Fast Fourier Transform
64 Int_t samples = alisddetf->GetSamples();
65 Int_t l = (Int_t) ((log((Float_t) samples)/log(2.))+0.5);
68 Int_t m2 = samples/m1;
71 for(j=0; j<samples; j += m1) {
73 for(k=j; k<= j+m-1; k++) {
74 Double_t wsr = alisddetf->GetWeightReal(p);
75 Double_t wsi = alisddetf->GetWeightImag(p);
76 if(direction == -1) wsi = -wsi;
77 Double_t xr = *(real+k+m);
78 Double_t xi = *(imag+k+m);
79 *(real+k+m) = wsr*(*(real+k)-xr) - wsi*(*(imag+k)-xi);
80 *(imag+k+m) = wsr*(*(imag+k)-xi) + wsi*(*(real+k)-xr);
91 for(j=0; j<samples; j++) {
95 for(i1=1; i1<=l; i1++) {
98 p = p + p + j2 - j1 - j1;
101 Double_t xr = *(real+j);
102 Double_t xi = *(imag+j);
103 *(real+j) = *(real+p);
104 *(imag+j) = *(imag+p);
109 if(direction == -1) {
110 for(i=0; i<samples; i++) {
111 *(real+i) /= samples;
112 *(imag+i) /= samples;
114 } // end if direction == -1
117 //______________________________________________________________________
118 AliITSsimulationSDD::AliITSsimulationSDD():
141 fCrosstalkFlag(kFALSE),
146 // Default constructor
148 SetPerpendTracksFlag();
153 //______________________________________________________________________
154 AliITSsimulationSDD::AliITSsimulationSDD(const AliITSsimulationSDD &source) :
155 AliITSsimulation(source),
157 fHitMap2(source.fHitMap2),
158 fHitSigMap2(source.fHitSigMap2),
159 fHitNoiMap2(source.fHitNoiMap2),
160 fStream(source.fStream),
161 fElectronics(source.fElectronics),
164 fOutZR(source.fOutZR),
165 fOutZI(source.fOutZI),
166 fAnodeFire(source.fAnodeFire),
172 fTreeB(source.fTreeB),
173 fParam(source.fParam),
174 fFileName(source.fFileName),
176 fCheckNoise(source.fCheckNoise),
177 fCrosstalkFlag(source.fCrosstalkFlag),
178 fDoFFT(source.fDoFFT),
179 fNofMaps(source.fNofMaps),
180 fMaxNofSamples(source.fMaxNofSamples),
181 fScaleSize(source.fScaleSize){
182 // Copy constructor to satify Coding roules only.
185 //______________________________________________________________________
186 AliITSsimulationSDD& AliITSsimulationSDD::operator=(const AliITSsimulationSDD &src){
187 // Assignment operator to satify Coding roules only.
189 if(this==&src) return *this;
190 Error("AliITSsimulationSDD","Not allowed to make a = with "
191 "AliITSsimulationSDD Using default creater instead");
194 //______________________________________________________________________
195 AliITSsimulation& AliITSsimulationSDD::operator=(const AliITSsimulation &src){
196 // Assignment operator to satify Coding roules only.
198 if(this==&src) return *this;
199 Error("AliITSsimulationSSD","Not allowed to make a = with "
200 "AliITSsimulationSDD Using default creater instead");
204 //______________________________________________________________________
205 AliITSsimulationSDD::AliITSsimulationSDD(AliITSDetTypeSim* dettyp):
206 AliITSsimulation(dettyp),
228 fCrosstalkFlag(kFALSE),
233 // Default Constructor
236 //______________________________________________________________________
237 void AliITSsimulationSDD::Init(){
238 // Standard Constructor
241 SetPerpendTracksFlag();
246 AliITSsegmentationSDD* seg = (AliITSsegmentationSDD*)GetSegmentationModel(1);
248 AliITSresponseSDD* res = (AliITSresponseSDD*)fDetType->GetResponse(1);
249 fpList = new AliITSpList( seg->Npz(),
250 fScaleSize*seg->Npx() );
251 fHitSigMap2 = new AliITSMapA2(seg,fScaleSize,1);
252 fHitNoiMap2 = new AliITSMapA2(seg,fScaleSize,1);
253 fHitMap2 = fHitSigMap2;
255 fNofMaps = seg->Npz();
256 fMaxNofSamples = seg->Npx();
257 fAnodeFire = new Bool_t [fNofMaps];
259 Float_t sddLength = seg->Dx();
260 Float_t sddWidth = seg->Dz();
263 Float_t anodePitch = seg->Dpz(dummy);
264 Double_t timeStep = (Double_t)seg->Dpx(dummy);
265 Float_t driftSpeed = res->DriftSpeed();
267 if(anodePitch*(fNofMaps/2) > sddWidth) {
268 Warning("AliITSsimulationSDD",
269 "Too many anodes %d or too big pitch %f \n",
270 fNofMaps/2,anodePitch);
273 if(timeStep*fMaxNofSamples < sddLength/driftSpeed) {
274 Error("AliITSsimulationSDD",
275 "Time Interval > Allowed Time Interval: exit\n");
279 fElectronics = new AliITSetfSDD(timeStep/fScaleSize,
282 char opt1[20], opt2[20];
283 res->ParamOptions(opt1,opt2);
286 const char *kopt=res->ZeroSuppOption();
292 Bool_t write = res->OutputOption();
293 if(write && strstr(kopt,"2D")) MakeTreeB();
295 fITS = (AliITS*)gAlice->GetModule("ITS");
296 Int_t size = fNofMaps*fMaxNofSamples;
297 fStream = new AliITSInStream(size);
299 fInZR = new Double_t [fScaleSize*fMaxNofSamples];
300 fInZI = new Double_t [fScaleSize*fMaxNofSamples];
301 fOutZR = new Double_t [fScaleSize*fMaxNofSamples];
302 fOutZI = new Double_t [fScaleSize*fMaxNofSamples];
304 //______________________________________________________________________
305 AliITSsimulationSDD::~AliITSsimulationSDD() {
320 if(fTreeB) delete fTreeB;
321 if(fInZR) delete [] fInZR;
322 if(fInZI) delete [] fInZI;
323 if(fOutZR) delete [] fOutZR;
324 if(fOutZI) delete [] fOutZI;
325 if(fAnodeFire) delete [] fAnodeFire;
327 //______________________________________________________________________
328 void AliITSsimulationSDD::InitSimulationModule( Int_t module, Int_t event ) {
329 // create maps to build the lists of tracks for each summable digit
333 memset(fAnodeFire,0,sizeof(Bool_t)*fNofMaps);
335 //______________________________________________________________________
336 void AliITSsimulationSDD::ClearMaps() {
339 fHitSigMap2->ClearMap();
340 fHitNoiMap2->ClearMap();
342 //______________________________________________________________________
343 void AliITSsimulationSDD::SDigitiseModule(AliITSmodule *mod,Int_t md,Int_t ev){
344 // digitize module using the "slow" detector simulator creating
347 TObjArray *fHits = mod->GetHits();
348 Int_t nhits = fHits->GetEntriesFast();
351 InitSimulationModule( md, ev );
352 HitsToAnalogDigits( mod );
353 ChargeToSignal( fModule,kFALSE ); // - Process signal without add noise
354 fHitMap2 = fHitNoiMap2; // - Swap to noise map
355 ChargeToSignal( fModule,kTRUE ); // - Process only noise
356 fHitMap2 = fHitSigMap2; // - Return to signal map
360 //______________________________________________________________________
361 Bool_t AliITSsimulationSDD::AddSDigitsToModule(TClonesArray *pItemArray,
363 // Add Summable digits to module maps.
364 AliITSresponseSDD* res = (AliITSresponseSDD*)fDetType->GetResponse(1);
365 Int_t nItems = pItemArray->GetEntries();
366 Double_t maxadc = res->MaxAdc();
369 // cout << "Adding "<< nItems <<" SDigits to module " << fModule << endl;
370 for( Int_t i=0; i<nItems; i++ ) {
371 AliITSpListItem * pItem = (AliITSpListItem *)(pItemArray->At( i ));
372 if( pItem->GetModule() != fModule ) {
373 Error( "AliITSsimulationSDD","Error reading, SDigits module "
374 "%d != current module %d: exit",
375 pItem->GetModule(), fModule );
379 if(pItem->GetSignal()>0.0 ) sig = kTRUE;
381 fpList->AddItemTo( mask, pItem ); // Add SignalAfterElect + noise
382 AliITSpListItem * pItem2 = fpList->GetpListItem( pItem->GetIndex() );
383 Double_t sigAE = pItem2->GetSignalAfterElect();
384 if( sigAE >= maxadc ) sigAE = maxadc-1; // avoid overflow signal
387 fpList->GetMapIndex( pItem->GetIndex(), ia, it );
388 fHitMap2->SetHit( ia, it, sigAE );
389 fAnodeFire[ia] = kTRUE;
393 //______________________________________________________________________
394 void AliITSsimulationSDD::FinishSDigitiseModule() {
395 // digitize module using the "slow" detector simulator from
396 // the sum of summable digits.
400 //______________________________________________________________________
401 void AliITSsimulationSDD::DigitiseModule(AliITSmodule *mod,Int_t md,Int_t ev){
402 // create maps to build the lists of tracks for each digit
404 TObjArray *fHits = mod->GetHits();
405 Int_t nhits = fHits->GetEntriesFast();
407 InitSimulationModule( md, ev );
409 if( !nhits && fCheckNoise ) {
410 ChargeToSignal( fModule,kTRUE ); // process noise
417 HitsToAnalogDigits( mod );
418 ChargeToSignal( fModule,kTRUE ); // process signal + noise
420 for( Int_t i=0; i<fNofMaps; i++ ) {
421 for( Int_t j=0; j<fMaxNofSamples; j++ ) {
422 Int_t jdx = j*fScaleSize;
423 Int_t index = fpList->GetHitIndex( i, j );
424 AliITSpListItem pItemTmp2( fModule, index, 0. );
425 // put the fScaleSize analog digits in only one
426 for( Int_t ik=0; ik<fScaleSize; ik++ ) {
427 AliITSpListItem *pItemTmp = fpList->GetpListItem( i, jdx+ik );
428 if( pItemTmp == 0 ) continue;
429 pItemTmp2.Add( pItemTmp );
431 fpList->DeleteHit( i, j );
432 fpList->AddItemTo( 0, &pItemTmp2 );
438 //______________________________________________________________________
439 void AliITSsimulationSDD::FinishDigits() {
440 // introduce the electronics effects and do zero-suppression if required
442 ApplyDeadChannels(fModule);
443 if( fCrosstalkFlag ) ApplyCrosstalk(fModule);
445 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
446 const char *kopt = res->GetZeroSuppOption();
447 ZeroSuppression( kopt );
449 //______________________________________________________________________
450 void AliITSsimulationSDD::HitsToAnalogDigits( AliITSmodule *mod ) {
451 // create maps to build the lists of tracks for each digit
453 AliITSsegmentationSDD* seg = (AliITSsegmentationSDD*)GetSegmentationModel(1);
454 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
455 TObjArray *hits = mod->GetHits();
456 Int_t nhits = hits->GetEntriesFast();
458 // Int_t arg[6] = {0,0,0,0,0,0};
460 Int_t nofAnodes = fNofMaps/2;
461 Float_t sddLength = seg->Dx();
462 Float_t sddWidth = seg->Dz();
463 Float_t anodePitch = seg->Dpz(dummy);
464 Float_t timeStep = seg->Dpx(dummy);
465 Float_t driftSpeed = res->GetDriftSpeed();
466 Float_t maxadc = res->GetMaxAdc();
467 Float_t topValue = res->GetDynamicRange();
468 Float_t cHloss = res->GetChargeLoss();
469 Float_t norm = maxadc/topValue;
470 Float_t dfCoeff, s1; res->DiffCoeff(dfCoeff,s1); // Signal 2d Shape
471 Double_t eVpairs = res->GetGeVToCharge()*1.0E9; // 3.6 eV by def.
472 Float_t nsigma = res->GetNSigmaIntegration(); //
473 Int_t nlookups = res->GetGausNLookUp(); //
474 Float_t jitter = res->GetJitterError(); //
476 // Piergiorgio's part (apart for few variables which I made float
477 // when i thought that can be done
478 // Fill detector maps with GEANT hits
479 // loop over hits in the module
481 const Float_t kconv = 1.0e+6; // GeV->KeV
483 Int_t hitDetector; // detector number (lay,lad,hitDetector)
484 Int_t iWing; // which detector wing/side.
485 Int_t detector; // 2*(detector-1)+iWing
486 Int_t ii,kk,ka,kt; // loop indexs
487 Int_t ia,it,index; // sub-pixel integration indexies
488 Int_t iAnode; // anode number.
489 Int_t timeSample; // time buckett.
490 Int_t anodeWindow; // anode direction charge integration width
491 Int_t timeWindow; // time direction charge integration width
492 Int_t jamin,jamax; // anode charge integration window
493 Int_t jtmin,jtmax; // time charge integration window
494 Int_t ndiv; // Anode window division factor.
495 Int_t nsplit; // the number of splits in anode and time windows==1.
496 Int_t nOfSplits; // number of times track length is split into
497 Float_t nOfSplitsF; // Floating point version of nOfSplits.
498 Float_t kkF; // Floating point version of loop index kk.
499 Float_t pathInSDD; // Track length in SDD.
500 Float_t drPath; // average position of track in detector. in microns
501 Float_t drTime; // Drift time
502 Float_t nmul; // drift time window multiplication factor.
503 Float_t avDrft; // x position of path length segment in cm.
504 Float_t avAnode; // Anode for path length segment in Anode number (float)
505 Float_t xAnode; // Floating point anode number.
506 Float_t driftPath; // avDrft in microns.
507 Float_t width; // width of signal at anodes.
508 Double_t depEnergy; // Energy deposited in this GEANT step.
509 Double_t xL[3],dxL[3]; // local hit coordinates and diff.
510 Double_t sigA; // sigma of signal at anode.
511 Double_t sigT; // sigma in time/drift direction for track segment
512 Double_t aStep,aConst; // sub-pixel size and offset anode
513 Double_t tStep,tConst; // sub-pixel size and offset time
514 Double_t amplitude; // signal amplitude for track segment in nanoAmpere
515 Double_t chargeloss; // charge loss for track segment.
516 Double_t anodeAmplitude; // signal amplitude in anode direction
517 Double_t aExpo; // exponent of Gaussian anode direction
518 Double_t timeAmplitude; // signal amplitude in time direction
519 Double_t tExpo; // exponent of Gaussian time direction
520 // Double_t tof; // Time of flight in ns of this step.
522 for(ii=0; ii<nhits; ii++) {
523 if(!mod->LineSegmentL(ii,xL[0],dxL[0],xL[1],dxL[1],xL[2],dxL[2],
524 depEnergy,itrack)) continue;
525 xL[0] += 0.0001*gRandom->Gaus( 0, jitter ); //
527 hitDetector = mod->GetDet();
528 //tof = 1.E+09*(mod->GetHit(ii)->GetTOF()); // tof in ns.
529 //if(tof>sddLength/driftSpeed) continue; // hit happed too late.
531 // scale path to simulate a perpendicular track
532 // continue if the particle did not lose energy
533 // passing through detector
536 Form("fTrack = %d hit=%d module=%d This particle has passed without losing energy!",
537 itrack,ii,mod->GetIndex()));
539 } // end if !depEnergy
541 pathInSDD = TMath::Sqrt(dxL[0]*dxL[0]+dxL[1]*dxL[1]+dxL[2]*dxL[2]);
543 if (fFlag && pathInSDD) { depEnergy *= (0.03/pathInSDD); }
544 drPath = 10000.*(dxL[0]+2.*xL[0])*0.5;
545 if(drPath < 0) drPath = -drPath;
546 drPath = sddLength-drPath;
548 AliDebug(1, // this should be fixed at geometry level
549 Form("negative drift path drPath=%e sddLength=%e dxL[0]=%e xL[0]=%e",
550 drPath,sddLength,dxL[0],xL[0]));
552 } // end if drPath < 0
554 // Compute number of segments to brake step path into
555 drTime = drPath/driftSpeed; // Drift Time
556 sigA = TMath::Sqrt(2.*dfCoeff*drTime+s1*s1);// Sigma along the anodes
557 // calcuate the number of time the path length should be split into.
558 nOfSplits = (Int_t) (1. + 10000.*pathInSDD/sigA);
559 if(fFlag) nOfSplits = 1;
561 // loop over path segments, init. some variables.
562 depEnergy /= nOfSplits;
563 nOfSplitsF = (Float_t) nOfSplits;
564 for(kk=0;kk<nOfSplits;kk++) { // loop over path segments
565 kkF = (Float_t) kk + 0.5;
566 avDrft = xL[0]+dxL[0]*kkF/nOfSplitsF;
567 avAnode = xL[2]+dxL[2]*kkF/nOfSplitsF;
568 driftPath = 10000.*avDrft;
570 iWing = 2; // Assume wing is 2
571 if(driftPath < 0) { // if wing is not 2 it is 1.
573 driftPath = -driftPath;
574 } // end if driftPath < 0
575 driftPath = sddLength-driftPath;
576 detector = 2*(hitDetector-1) + iWing;
578 AliDebug(1, // this should be fixed at geometry level
579 Form("negative drift path driftPath=%e sddLength=%e avDrft=%e dxL[0]=%e xL[0]=%e",
580 driftPath,sddLength,avDrft,dxL[0],xL[0]));
582 } // end if driftPath < 0
585 drTime = driftPath/driftSpeed; // drift time for segment.
586 timeSample = (Int_t) (fScaleSize*drTime/timeStep + 1);
587 // compute time Sample including tof information. The tof only
588 // effects the time of the signal is recoreded and not the
590 // timeSample = (Int_t) (fScaleSize*(drTime+tof)/timeStep + 1);
591 if(timeSample > fScaleSize*fMaxNofSamples) {
592 Warning("HitsToAnalogDigits","Wrong Time Sample: %e",
595 } // end if timeSample > fScaleSize*fMaxNoofSamples
598 xAnode = 10000.*(avAnode)/anodePitch + nofAnodes/2; // +1?
599 if(xAnode*anodePitch > sddWidth || xAnode*anodePitch < 0.)
600 Warning("HitsToAnalogDigits",
601 "Exceedubg sddWidth=%e Z = %e",
602 sddWidth,xAnode*anodePitch);
603 iAnode = (Int_t) (1.+xAnode); // xAnode?
604 if(iAnode < 1 || iAnode > nofAnodes) {
605 Warning("HitToAnalogDigits","Wrong iAnode: 1<%d>%d",
608 } // end if iAnode < 1 || iAnode > nofAnodes
610 // store straight away the particle position in the array
611 // of particles and take idhit=ii only when part is entering (this
612 // requires FillModules() in the macro for analysis) :
614 // Sigma along the anodes for track segment.
615 sigA = TMath::Sqrt(2.*dfCoeff*drTime+s1*s1);
616 sigT = sigA/driftSpeed;
617 // Peak amplitude in nanoAmpere
618 amplitude = fScaleSize*160.*depEnergy/
619 (timeStep*eVpairs*2.*acos(-1.)*sigT*sigA);
620 amplitude *= timeStep/25.; // WARNING!!!!! Amplitude scaling to
621 // account for clock variations
622 // (reference value: 40 MHz)
623 chargeloss = 1.-cHloss*driftPath/1000;
624 amplitude *= chargeloss;
625 width = 2.*nsigma/(nlookups-1);
633 } // end if drTime > 1200.
635 nsplit = 4; // hard-wired //nsplit=4;nsplit = (nsplit+1)/2*2;
636 // Sub-pixel size see computation of aExpo and tExpo.
637 aStep = anodePitch/(nsplit*fScaleSize*sigA);
638 aConst = xAnode*anodePitch/sigA;
639 tStep = timeStep/(nsplit*fScaleSize*sigT);
640 tConst = drTime/sigT;
641 // Define SDD window corresponding to the hit
642 anodeWindow = (Int_t)(fScaleSize*nsigma*sigA/anodePitch+1);
643 timeWindow = (Int_t) (fScaleSize*nsigma*sigT/timeStep+1.);
644 jamin = (iAnode - anodeWindow/ndiv - 1)*fScaleSize*nsplit +1;
645 jamax = (iAnode + anodeWindow/ndiv)*fScaleSize*nsplit;
646 if(jamin <= 0) jamin = 1;
647 if(jamax > fScaleSize*nofAnodes*nsplit)
648 jamax = fScaleSize*nofAnodes*nsplit;
649 // jtmin and jtmax are Hard-wired
650 jtmin = (Int_t)(timeSample-timeWindow*nmul-1)*nsplit+1;
651 jtmax = (Int_t)(timeSample+timeWindow*nmul)*nsplit;
652 if(jtmin <= 0) jtmin = 1;
653 if(jtmax > fScaleSize*fMaxNofSamples*nsplit)
654 jtmax = fScaleSize*fMaxNofSamples*nsplit;
655 // Spread the charge in the anode-time window
656 for(ka=jamin; ka <=jamax; ka++) {
657 ia = (ka-1)/(fScaleSize*nsplit) + 1;
659 Warning("HitsToAnalogDigits","ia < 1: ");
662 if(ia > nofAnodes) ia = nofAnodes;
663 aExpo = (aStep*(ka-0.5)-aConst);
664 if(TMath::Abs(aExpo) > nsigma) anodeAmplitude = 0.;
666 dummy = (Int_t) ((aExpo+nsigma)/width);
667 anodeAmplitude = amplitude*res->GetGausLookUp(dummy);
668 } // end if TMath::Abs(aEspo) > nsigma
669 // index starts from 0
670 index = ((detector+1)%2)*nofAnodes+ia-1;
671 if(anodeAmplitude) for(kt=jtmin; kt<=jtmax; kt++) {
672 it = (kt-1)/nsplit+1; // it starts from 1
674 Warning("HitsToAnalogDigits","it < 1:");
677 if(it>fScaleSize*fMaxNofSamples)
678 it = fScaleSize*fMaxNofSamples;
679 tExpo = (tStep*(kt-0.5)-tConst);
680 if(TMath::Abs(tExpo) > nsigma) timeAmplitude = 0.;
682 dummy = (Int_t) ((tExpo+nsigma)/width);
683 timeAmplitude = anodeAmplitude*
684 res->GetGausLookUp(dummy);
685 } // end if TMath::Abs(tExpo) > nsigma
686 // build the list of Sdigits for this module
689 // arg[2] = itrack; // track number
690 // arg[3] = ii-1; // hit number.
691 timeAmplitude *= norm;
693 // ListOfFiredCells(arg,timeAmplitude,alst,padr);
694 Double_t charge = timeAmplitude;
695 charge += fHitMap2->GetSignal(index,it-1);
696 fHitMap2->SetHit(index, it-1, charge);
697 fpList->AddSignal(index,it-1,itrack,ii-1,
698 mod->GetIndex(),timeAmplitude);
699 fAnodeFire[index] = kTRUE;
700 } // end if anodeAmplitude and loop over time in window
701 } // loop over anodes in window
702 } // end loop over "sub-hits"
703 } // end loop over hits
706 //______________________________________________________________________
707 void AliITSsimulationSDD::ListOfFiredCells(Int_t *arg,Double_t timeAmplitude,
708 TObjArray *alist,TClonesArray *padr){
709 // Returns the list of "fired" cells.
711 Int_t index = arg[0];
713 Int_t idtrack = arg[2];
714 Int_t idhit = arg[3];
715 Int_t counter = arg[4];
716 Int_t countadr = arg[5];
717 Double_t charge = timeAmplitude;
718 charge += fHitMap2->GetSignal(index,ik-1);
719 fHitMap2->SetHit(index, ik-1, charge);
722 Int_t it = (Int_t)((ik-1)/fScaleSize);
725 digits[2] = (Int_t)timeAmplitude;
727 if (idtrack >= 0) phys = (Float_t)timeAmplitude;
730 Double_t cellcharge = 0.;
731 AliITSTransientDigit* pdigit;
732 // build the list of fired cells and update the info
733 if (!fHitMap1->TestHit(index, it)) {
734 new((*padr)[countadr++]) TVector(3);
735 TVector &trinfo=*((TVector*) (*padr)[countadr-1]);
736 trinfo(0) = (Float_t)idtrack;
737 trinfo(1) = (Float_t)idhit;
738 trinfo(2) = (Float_t)timeAmplitude;
740 alist->AddAtAndExpand(new AliITSTransientDigit(phys,digits),counter);
741 fHitMap1->SetHit(index, it, counter);
743 pdigit=(AliITSTransientDigit*)alist->At(alist->GetLast());
745 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
746 trlist->Add(&trinfo);
748 pdigit = (AliITSTransientDigit*) fHitMap1->GetHit(index, it);
749 for(Int_t kk=0;kk<fScaleSize;kk++) {
750 cellcharge += fHitMap2->GetSignal(index,fScaleSize*it+kk);
753 (*pdigit).fSignal = (Int_t)cellcharge;
754 (*pdigit).fPhysics += phys;
755 // update list of tracks
756 TObjArray* trlist = (TObjArray*)pdigit->TrackList();
757 Int_t lastentry = trlist->GetLast();
758 TVector *ptrkp = (TVector*)trlist->At(lastentry);
759 TVector &trinfo = *ptrkp;
760 Int_t lasttrack = Int_t(trinfo(0));
761 Float_t lastcharge=(trinfo(2));
762 if (lasttrack==idtrack ) {
763 lastcharge += (Float_t)timeAmplitude;
764 trlist->RemoveAt(lastentry);
765 trinfo(0) = lasttrack;
767 trinfo(2) = lastcharge;
768 trlist->AddAt(&trinfo,lastentry);
770 new((*padr)[countadr++]) TVector(3);
771 TVector &trinfo=*((TVector*) (*padr)[countadr-1]);
772 trinfo(0) = (Float_t)idtrack;
773 trinfo(1) = (Float_t)idhit;
774 trinfo(2) = (Float_t)timeAmplitude;
775 trlist->Add(&trinfo);
776 } // end if lasttrack==idtrack
779 // check the track list - debugging
780 Int_t trk[20], htrk[20];
782 Int_t nptracks = trlist->GetEntriesFast();
785 for (tr=0;tr<nptracks;tr++) {
786 TVector *pptrkp = (TVector*)trlist->At(tr);
787 TVector &pptrk = *pptrkp;
788 trk[tr] = Int_t(pptrk(0));
789 htrk[tr] = Int_t(pptrk(1));
790 chtrk[tr] = (pptrk(2));
791 cout << "nptracks "<<nptracks << endl;
794 } // end if AliDebugLevel()
797 // update counter and countadr for next call.
802 //____________________________________________
803 void AliITSsimulationSDD::AddDigit( Int_t i, Int_t j, Int_t signal ) {
805 Int_t size = AliITSdigitSPD::GetNTracks();
807 Int_t * tracks = new Int_t[size];
808 Int_t * hits = new Int_t[size];
810 Float_t * charges = new Float_t[size];
816 AliITSpListItem *pItem = fpList->GetpListItem( i, j );
819 for( Int_t l=0; l<size; l++ ) {
825 Int_t idtrack = pItem->GetTrack( 0 );
826 if( idtrack >= 0 ) phys = pItem->GetSignal();
829 for( Int_t l=0; l<size; l++ ) if(l<pItem->GetMaxKept()) {
830 tracks[l] = pItem->GetTrack( l );
831 hits[l] = pItem->GetHit( l );
832 charges[l] = pItem->GetSignal( l );
840 fITS->AddSimDigit( 1, phys, digits, tracks, hits, charges );
845 //______________________________________________________________________
846 void AliITSsimulationSDD::ChargeToSignal(Int_t mod,Bool_t bAddNoise) {
847 // add baseline, noise, electronics and ADC saturation effects
849 char opt1[20], opt2[20];
850 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(mod);
851 res->GetParamOptions(opt1,opt2);
857 Float_t maxadc = res->GetMaxAdc();
859 for (i=0;i<fNofMaps;i++) {
860 if( !fAnodeFire[i] ) continue;
861 baseline = res->GetBaseline(i);
862 noise = res->GetNoise(i);
864 for(k=0; k<fScaleSize*fMaxNofSamples; k++) {
865 fInZR[k] = fHitMap2->GetSignal(i,k);
867 contrib = (baseline + noise*gRandom->Gaus());
871 for(k=0; k<fMaxNofSamples; k++) {
872 Double_t newcont = 0.;
873 Double_t maxcont = 0.;
874 for(kk=0;kk<fScaleSize;kk++) {
875 newcont = fInZR[fScaleSize*k+kk];
876 if(newcont > maxcont) maxcont = newcont;
879 if (newcont >= maxadc) newcont = maxadc -1;
880 if(newcont >= baseline){
881 Warning("","newcont=%d>=baseline=%d",newcont,baseline);
884 fHitMap2->SetHit(i,k,newcont);
886 } // end for i loop over anodes
890 for (i=0;i<fNofMaps;i++) {
891 if( !fAnodeFire[i] ) continue;
892 baseline = res->GetBaseline(i);
893 noise = res->GetNoise(i);
894 for(k=0; k<fScaleSize*fMaxNofSamples; k++) {
895 fInZR[k] = fHitMap2->GetSignal(i,k);
897 contrib = (baseline + noise*gRandom->Gaus());
902 FastFourierTransform(fElectronics,&fInZR[0],&fInZI[0],1);
903 for(k=0; k<fScaleSize*fMaxNofSamples; k++) {
904 Double_t rw = fElectronics->GetTraFunReal(k);
905 Double_t iw = fElectronics->GetTraFunImag(k);
906 fOutZR[k] = fInZR[k]*rw - fInZI[k]*iw;
907 fOutZI[k] = fInZR[k]*iw + fInZI[k]*rw;
909 FastFourierTransform(fElectronics,&fOutZR[0],&fOutZI[0],-1);
910 for(k=0; k<fMaxNofSamples; k++) {
911 Double_t newcont1 = 0.;
912 Double_t maxcont1 = 0.;
913 for(kk=0;kk<fScaleSize;kk++) {
914 newcont1 = fOutZR[fScaleSize*k+kk];
915 if(newcont1 > maxcont1) maxcont1 = newcont1;
918 if (newcont1 >= maxadc) newcont1 = maxadc -1;
919 fHitMap2->SetHit(i,k,newcont1);
921 } // end for i loop over anodes
924 //____________________________________________________________________
925 void AliITSsimulationSDD::ApplyDeadChannels(Int_t mod) {
926 // Set dead channel signal to zero
927 AliITSCalibrationSDD * calibr = (AliITSCalibrationSDD *)GetCalibrationModel(mod);
928 AliITSsegmentationSDD* seg = (AliITSsegmentationSDD*)GetSegmentationModel(1);
930 if( calibr->IsDead() ||
931 ( calibr->GetDeadChips() == 0 &&
932 calibr->GetDeadChannels() == 0 ) ) return;
934 // static AliITS *iTS = (AliITS*)gAlice->GetModule( "ITS" );
936 Int_t fMaxNofSamples = seg->Npx();
937 // AliITSgeom *geom = iTS->GetITSgeom();
938 // Int_t firstSDDMod = geom->GetStartDet( 1 );
940 for( Int_t j=0; j<2; j++ ) {
941 // Int_t mod = (fModule-firstSDDMod)*2 + j;
942 for( Int_t u=0; u<calibr->Chips(); u++ )
943 for( Int_t v=0; v<calibr->Channels(); v++ ) {
944 Float_t gain = calibr->Gain(j, u, v );
945 for( Int_t k=0; k<fMaxNofSamples; k++ ) {
946 Int_t i = j*calibr->Chips()*calibr->Channels() +
947 u*calibr->Channels() +
949 Double_t signal = gain * fHitMap2->GetSignal( i, k );
950 fHitMap2->SetHit( i, k, signal ); ///
955 //______________________________________________________________________
956 void AliITSsimulationSDD::ApplyCrosstalk(Int_t mod) {
957 // function add the crosstalk effect to signal
958 // temporal function, should be checked...!!!
959 AliITSsegmentationSDD* seg = (AliITSsegmentationSDD*)GetSegmentationModel(1);
961 Int_t fNofMaps = seg->Npz();
962 Int_t fMaxNofSamples = seg->Npx();
964 // create and inizialice crosstalk map
965 Float_t* ctk = new Float_t[fNofMaps*fMaxNofSamples+1];
967 Error( "ApplyCrosstalk", "no memory for temporal map: exit \n" );
970 memset( ctk, 0, sizeof(Float_t)*(fNofMaps*fMaxNofSamples+1) );
971 AliITSCalibrationSDD* calibr = (AliITSCalibrationSDD*)GetCalibrationModel(mod);
972 for( Int_t z=0; z<fNofMaps; z++ ) {
973 Double_t baseline = calibr->GetBaseline(z);
979 for( Int_t l=0; l<fMaxNofSamples; l++ ) {
980 Float_t fadc = (Float_t)fHitMap2->GetSignal( z, l );
981 if( fadc > baseline ) {
982 if( on == kFALSE && l<fMaxNofSamples-4 ) {
983 Float_t fadc1 = (Float_t)fHitMap2->GetSignal( z, l+1 );
984 if( fadc1 < fadc ) continue;
991 else { // end fadc > baseline
995 // make smooth derivative
996 Float_t* dev = new Float_t[fMaxNofSamples+1];
997 memset( dev, 0, sizeof(Float_t)*(fMaxNofSamples+1) );
999 Error( "ApplyCrosstalk",
1000 "no memory for temporal array: exit \n" );
1003 for( Int_t i=tstart; i<tstop; i++ ) {
1004 if( i > 2 && i < fMaxNofSamples-2 )
1005 dev[i] = -0.2*fHitMap2->GetSignal( z,i-2 )
1006 -0.1*fHitMap2->GetSignal( z,i-1 )
1007 +0.1*fHitMap2->GetSignal( z,i+1 )
1008 +0.2*fHitMap2->GetSignal( z,i+2 );
1011 // add crosstalk contribution to neibourg anodes
1012 for( Int_t i=tstart; i<tstop; i++ ) {
1013 Int_t anode = z - 1;
1014 Int_t i1 = (Int_t)((i-tstart)*.61+tstart+0.5); //
1015 Float_t ctktmp = -dev[i1] * 0.25;
1017 ctk[anode*fMaxNofSamples+i] += ctktmp;
1020 if( anode < fNofMaps ) {
1021 ctk[anode*fMaxNofSamples+i] += ctktmp;
1026 } // if( nTsteps > 2 )
1028 } // if( on == kTRUE )
1033 for( Int_t a=0; a<fNofMaps; a++ )
1034 for( Int_t t=0; t<fMaxNofSamples; t++ ) {
1035 Float_t signal = fHitMap2->GetSignal(a,t)+ctk[a*fMaxNofSamples+t];
1036 fHitMap2->SetHit( a, t, signal );
1042 //______________________________________________________________________
1043 void AliITSsimulationSDD::CompressionParam(Int_t i,Int_t &db,Int_t &tl,
1045 // Returns the compression alogirthm parameters
1050 //______________________________________________________________________
1051 void AliITSsimulationSDD::CompressionParam(Int_t i,Int_t &db,Int_t &tl) const{
1052 // returns the compression alogirthm parameters
1058 //______________________________________________________________________
1059 void AliITSsimulationSDD::SetCompressParam(){
1060 // Sets the compression alogirthm parameters
1061 AliITSCalibrationSDD* calibr = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1062 for(Int_t ian = 0; ian<fNofMaps;ian++){
1063 fD[ian] = (Int_t)(calibr->GetBaseline(ian));
1064 fT1[ian] = (Int_t)(2.*calibr->GetNoiseAfterElectronics(ian)+0.5);
1065 fT2[ian] = 0; // used by 2D clustering - not defined yet
1066 fTol[ian] = 0; // used by 2D clustering - not defined yet
1069 //______________________________________________________________________
1070 Int_t AliITSsimulationSDD::Convert10to8(Int_t signal) const {
1071 // To the 10 to 8 bit lossive compression.
1072 // code from Davide C. and Albert W.
1074 if (signal < 128) return signal;
1075 if (signal < 256) return (128+((signal-128)>>1));
1076 if (signal < 512) return (192+((signal-256)>>3));
1077 if (signal < 1024) return (224+((signal-512)>>4));
1081 //______________________________________________________________________
1082 AliITSMap* AliITSsimulationSDD::HitMap(Int_t i){
1083 //Return the correct map.
1085 return ((i==0)? fHitMap1 : fHitMap2);
1088 //______________________________________________________________________
1089 void AliITSsimulationSDD::ZeroSuppression(const char *option) {
1090 // perform the zero suppresion
1092 if (strstr(option,"2D")) {
1093 //Init2D(); // activate if param change module by module
1095 } else if (strstr(option,"1D")) {
1096 //Init1D(); // activate if param change module by module
1098 } else StoreAllDigits();
1100 //______________________________________________________________________
1101 void AliITSsimulationSDD::Init2D(){
1102 // read in and prepare arrays: fD, fT1, fT2
1103 // savemu[nanodes], savesigma[nanodes]
1104 // read baseline and noise from file - either a .root file and in this
1105 // case data should be organised in a tree with one entry for each
1106 // module => reading should be done accordingly
1107 // or a classic file and do smth. like this ( code from Davide C. and
1109 // Read 2D zero-suppression parameters for SDD
1111 if (!strstr(fParam.Data(),"file")) return;
1113 Int_t na,pos,tempTh;
1115 Float_t *savemu = new Float_t [fNofMaps];
1116 Float_t *savesigma = new Float_t [fNofMaps];
1117 char input[100],basel[100],par[100];
1120 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1122 res->Thresholds(tmp1,tmp2);
1123 Int_t minval = static_cast<Int_t>(tmp1);
1125 res->Filenames(input,basel,par);
1128 filtmp = gSystem->ExpandPathName(fFileName.Data());
1129 FILE *param = fopen(filtmp,"r");
1133 while(fscanf(param,"%d %f %f",&pos, &mu, &sigma) != EOF) {
1135 Error("Init2D","Anode number not in increasing order!",filtmp);
1137 } // end if pos != na+1
1139 savesigma[na] = sigma;
1140 if ((2.*sigma) < mu) {
1141 fD[na] = (Int_t)floor(mu - 2.0*sigma + 0.5);
1144 tempTh = (Int_t)floor(mu+2.25*sigma+0.5) - minval;
1145 if (tempTh < 0) tempTh=0;
1147 tempTh = (Int_t)floor(mu+3.0*sigma+0.5) - minval;
1148 if (tempTh < 0) tempTh=0;
1153 Error("Init2D","THE FILE %s DOES NOT EXIST !",filtmp);
1160 delete [] savesigma;
1162 //______________________________________________________________________
1163 void AliITSsimulationSDD::Compress2D(){
1164 // simple ITS cluster finder -- online zero-suppression conditions
1168 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1170 res->Thresholds(tmp1,tmp2);
1171 Int_t minval = static_cast<Int_t>(tmp1);
1172 Bool_t write = res->OutputOption();
1173 Bool_t do10to8 = res->Do10to8();
1174 Int_t nz, nl, nh, low, i, j;
1176 for (i=0; i<fNofMaps; i++) {
1177 CompressionParam(i,db,tl,th);
1182 for (j=0; j<fMaxNofSamples; j++) {
1183 Int_t signal=(Int_t)(fHitMap2->GetSignal(i,j));
1184 signal -= db; // if baseline eq. is done here
1185 if (signal <= 0) {nz++; continue;}
1186 if ((signal - tl) < minval) low++;
1187 if ((signal - th) >= minval) {
1190 FindCluster(i,j,signal,minval,cond);
1192 ((TMath::Abs(fHitMap2->GetSignal(i,j-1))-th)>=minval)){
1193 if(do10to8) signal = Convert10to8(signal);
1194 AddDigit(i,j,signal);
1195 } // end if cond&&j&&()
1196 } else if ((signal - tl) >= minval) nl++;
1197 } // end for j loop time samples
1198 if (write) TreeB()->Fill(nz,nl,nh,low,i+1);
1199 } //end for i loop anodes
1203 sprintf(hname,"TNtuple%d_%d",fModule,fEvent);
1204 TreeB()->Write(hname);
1209 //______________________________________________________________________
1210 void AliITSsimulationSDD::FindCluster(Int_t i,Int_t j,Int_t signal,
1211 Int_t minval,Bool_t &cond){
1212 // Find clusters according to the online 2D zero-suppression algorithm
1213 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1214 AliITSsegmentationSDD* seg = (AliITSsegmentationSDD*)GetSegmentationModel(1);
1216 Bool_t do10to8 = res->Do10to8();
1217 Bool_t high = kFALSE;
1219 fHitMap2->FlagHit(i,j);
1221 // check the online zero-suppression conditions
1223 const Int_t kMaxNeighbours = 4;
1226 Int_t xList[kMaxNeighbours], yList[kMaxNeighbours];
1227 seg->Neighbours(i,j,&nn,xList,yList);
1229 for (in=0; in<nn; in++) {
1232 if (fHitMap2->TestHit(ix,iy)==kUnused) {
1233 CompressionParam(ix,dbx,tlx,thx);
1234 Int_t qn = (Int_t)(fHitMap2->GetSignal(ix,iy));
1235 qn -= dbx; // if baseline eq. is done here
1236 if ((qn-tlx) < minval) {
1237 fHitMap2->FlagHit(ix,iy);
1240 if ((qn - thx) >= minval) high=kTRUE;
1242 if(do10to8) signal = Convert10to8(signal);
1243 AddDigit(i,j,signal);
1245 if(do10to8) qns = Convert10to8(qn);
1247 if (!high) AddDigit(ix,iy,qns);
1249 if(!high) fHitMap2->FlagHit(ix,iy);
1250 } // end if qn-tlx < minval
1252 } // end for in loop over neighbours
1254 //______________________________________________________________________
1255 void AliITSsimulationSDD::Init1D(){
1256 // this is just a copy-paste of input taken from 2D algo
1257 // Torino people should give input
1258 // Read 1D zero-suppression parameters for SDD
1260 if (!strstr(fParam.Data(),"file")) return;
1262 Int_t na,pos,tempTh;
1264 Float_t *savemu = new Float_t [fNofMaps];
1265 Float_t *savesigma = new Float_t [fNofMaps];
1266 char input[100],basel[100],par[100];
1269 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1271 res->Thresholds(tmp1,tmp2);
1272 Int_t minval = static_cast<Int_t>(tmp1);
1274 res->Filenames(input,basel,par);
1277 // set first the disable and tol param
1280 filtmp = gSystem->ExpandPathName(fFileName.Data());
1281 FILE *param = fopen(filtmp,"r");
1285 fscanf(param,"%d %d %d %d ", &fT2[0], &fT2[1], &fTol[0], &fTol[1]);
1286 while(fscanf(param,"%d %f %f",&pos, &mu, &sigma) != EOF) {
1288 Error("Init1D","Anode number not in increasing order!",filtmp);
1290 } // end if pos != na+1
1292 savesigma[na]=sigma;
1293 if ((2.*sigma) < mu) {
1294 fD[na] = (Int_t)floor(mu - 2.0*sigma + 0.5);
1297 tempTh = (Int_t)floor(mu+2.25*sigma+0.5) - minval;
1298 if (tempTh < 0) tempTh=0;
1303 Error("Init1D","THE FILE %s DOES NOT EXIST !",filtmp);
1310 delete [] savesigma;
1312 //______________________________________________________________________
1313 void AliITSsimulationSDD::Compress1D(){
1314 // 1D zero-suppression algorithm (from Gianluca A.)
1315 Int_t dis,tol,thres,decr,diff;
1316 UChar_t *str=fStream->Stream();
1318 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1320 Bool_t do10to8=res->Do10to8();
1324 for (k=0; k<2; k++) {
1327 for (i=0; i<fNofMaps/2; i++) {
1328 Bool_t firstSignal=kTRUE;
1329 Int_t idx=i+k*fNofMaps/2;
1330 if( !fAnodeFire[idx] ) continue;
1331 CompressionParam(idx,decr,thres);
1333 for (j=0; j<fMaxNofSamples; j++) {
1334 Int_t signal=(Int_t)(fHitMap2->GetSignal(idx,j));
1335 signal -= decr; // if baseline eq.
1336 if(do10to8) signal = Convert10to8(signal);
1337 if (signal <= thres) {
1341 // write diff in the buffer for HuffT
1342 str[counter]=(UChar_t)diff;
1345 } // end if signal <= thres
1347 if (diff > 127) diff=127;
1348 if (diff < -128) diff=-128;
1350 // tol has changed to 8 possible cases ? - one can write
1351 // this if(TMath::Abs(diff)<tol) ... else ...
1352 if(TMath::Abs(diff)<tol) diff=0;
1353 // or keep it as it was before
1354 AddDigit(idx,j,last+diff);
1356 AddDigit(idx,j,signal);
1357 } // end if singal < dis
1359 // write diff in the buffer used to compute Huffman tables
1360 if (firstSignal) str[counter]=(UChar_t)signal;
1361 else str[counter]=(UChar_t)diff;
1365 } // end for j loop time samples
1366 } // end for i loop anodes one half of detector
1370 fStream->CheckCount(counter);
1372 // open file and write out the stream of diff's
1373 static Bool_t open=kTRUE;
1374 static TFile *outFile;
1375 Bool_t write = res->OutputOption();
1376 TDirectory *savedir = gDirectory;
1380 SetFileName("stream.root");
1381 cout<<"filename "<<fFileName<<endl;
1382 outFile=new TFile(fFileName,"recreate");
1383 cout<<"I have opened "<<fFileName<<" file "<<endl;
1390 fStream->ClearStream();
1392 // back to galice.root file
1393 if(savedir) savedir->cd();
1395 //______________________________________________________________________
1396 void AliITSsimulationSDD::StoreAllDigits(){
1397 // if non-zero-suppressed data
1398 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1400 Bool_t do10to8 = res->Do10to8();
1401 Int_t i, j, digits[3];
1403 for (i=0; i<fNofMaps; i++) {
1404 for (j=0; j<fMaxNofSamples; j++) {
1405 Int_t signal=(Int_t)(fHitMap2->GetSignal(i,j));
1406 if(do10to8) signal = Convert10to8(signal);
1410 fITS->AddRealDigit(1,digits);
1414 //______________________________________________________________________
1415 void AliITSsimulationSDD::CreateHistograms(Int_t scale){
1416 // Creates histograms of maps for debugging
1419 fHis=new TObjArray(fNofMaps);
1420 for (i=0;i<fNofMaps;i++) {
1421 TString sddName("sdd_");
1423 sprintf(candNum,"%d",i+1);
1424 sddName.Append(candNum);
1425 fHis->AddAt(new TH1F(sddName.Data(),"SDD maps",scale*fMaxNofSamples,
1426 0.,(Float_t) scale*fMaxNofSamples), i);
1429 //______________________________________________________________________
1430 void AliITSsimulationSDD::FillHistograms(){
1431 // fill 1D histograms from map
1435 for( Int_t i=0; i<fNofMaps; i++) {
1436 TH1F *hist =(TH1F *)fHis->UncheckedAt(i);
1437 Int_t nsamples = hist->GetNbinsX();
1438 for( Int_t j=0; j<nsamples; j++) {
1439 Double_t signal=fHitMap2->GetSignal(i,j);
1440 hist->Fill((Float_t)j,signal);
1444 //______________________________________________________________________
1445 void AliITSsimulationSDD::ResetHistograms(){
1446 // Reset histograms for this detector
1449 for (i=0;i<fNofMaps;i++ ) {
1450 if (fHis->At(i)) ((TH1F*)fHis->At(i))->Reset();
1453 //______________________________________________________________________
1454 TH1F *AliITSsimulationSDD::GetAnode(Int_t wing, Int_t anode) {
1455 // Fills a histogram from a give anode.
1457 if (!fHis) return 0;
1459 if(wing <=0 || wing > 2) {
1460 Warning("GetAnode","Wrong wing number: %d",wing);
1462 } // end if wing <=0 || wing >2
1463 if(anode <=0 || anode > fNofMaps/2) {
1464 Warning("GetAnode","Wrong anode number: %d",anode);
1466 } // end if ampde <=0 || andoe > fNofMaps/2
1468 Int_t index = (wing-1)*fNofMaps/2 + anode-1;
1469 return (TH1F*)(fHis->At(index));
1471 //______________________________________________________________________
1472 void AliITSsimulationSDD::WriteToFile(TFile *hfile) {
1473 // Writes the histograms to a file
1479 for(i=0; i<fNofMaps; i++) fHis->At(i)->Write(); //fAdcs[i]->Write();
1482 //______________________________________________________________________
1483 Float_t AliITSsimulationSDD::GetNoise() {
1484 // Returns the noise value
1485 //Bool_t do10to8=GetResp()->Do10to8();
1486 //noise will always be in the liniar part of the signal
1488 Int_t threshold = fT1[0];
1489 char opt1[20], opt2[20];
1490 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1492 res->GetParamOptions(opt1,opt2);
1494 Double_t noise,baseline;
1495 //GetBaseline(fModule);
1497 TCanvas *c2 = (TCanvas*)gROOT->GetListOfCanvases()->FindObject("c2");
1498 if(c2) delete c2->GetPrimitive("noisehist");
1499 if(c2) delete c2->GetPrimitive("anode");
1500 else c2=new TCanvas("c2");
1502 c2->SetFillColor(0);
1504 TH1F *noisehist = new TH1F("noisehist","noise",100,0.,(float)2*threshold);
1505 TH1F *anode = new TH1F("anode","Anode Projection",fMaxNofSamples,0.,
1506 (float)fMaxNofSamples);
1508 for (i=0;i<fNofMaps;i++) {
1509 CompressionParam(i,decr,threshold);
1510 baseline = res->GetBaseline(i);
1511 noise = res->GetNoise(i);
1513 for (k=0;k<fMaxNofSamples;k++) {
1514 Float_t signal=(Float_t)fHitMap2->GetSignal(i,k);
1515 //if (signal <= (float)threshold) noisehist->Fill(signal-baseline);
1516 if (signal <= (float)(threshold+decr)) noisehist->Fill(signal);
1517 anode->Fill((float)k,signal);
1522 TF1 *gnoise = new TF1("gnoise","gaus",0.,threshold);
1523 noisehist->Fit("gnoise","RQ");
1526 Float_t mnoise = gnoise->GetParameter(1);
1527 cout << "mnoise : " << mnoise << endl;
1528 Float_t rnoise = gnoise->GetParameter(2);
1529 cout << "rnoise : " << rnoise << endl;
1533 //______________________________________________________________________
1534 void AliITSsimulationSDD::WriteSDigits(){
1535 // Fills the Summable digits Tree
1536 static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
1538 for( Int_t i=0; i<fNofMaps; i++ ) {
1539 if( !fAnodeFire[i] ) continue;
1540 for( Int_t j=0; j<fMaxNofSamples; j++ ) {
1541 Double_t sig = fHitMap2->GetSignal( i, j );
1543 Int_t jdx = j*fScaleSize;
1544 Int_t index = fpList->GetHitIndex( i, j );
1545 AliITSpListItem pItemTmp2( fModule, index, 0. );
1546 // put the fScaleSize analog digits in only one
1547 for( Int_t ik=0; ik<fScaleSize; ik++ ) {
1548 AliITSpListItem *pItemTmp = fpList->GetpListItem(i,jdx+ik);
1549 if( pItemTmp == 0 ) continue;
1550 pItemTmp2.Add( pItemTmp );
1552 pItemTmp2.AddSignalAfterElect( fModule, index, sig );
1553 pItemTmp2.AddNoise(fModule,index,fHitNoiMap2->GetSignal(i,j));
1554 aliITS->AddSumDigit( pItemTmp2 );
1555 } // end if (sig > 0.2)
1560 //______________________________________________________________________
1561 void AliITSsimulationSDD::PrintStatus() const {
1562 // Print SDD simulation Parameters
1564 cout << "**************************************************" << endl;
1565 cout << " Silicon Drift Detector Simulation Parameters " << endl;
1566 cout << "**************************************************" << endl;
1567 cout << "Flag for Perpendicular tracks: " << (Int_t) fFlag << endl;
1568 cout << "Flag for noise checking: " << (Int_t) fCheckNoise << endl;
1569 cout << "Flag to switch off electronics: " << (Int_t) fDoFFT << endl;
1570 cout << "Number pf Anodes used: " << fNofMaps << endl;
1571 cout << "Number of Time Samples: " << fMaxNofSamples << endl;
1572 cout << "Scale size factor: " << fScaleSize << endl;
1573 cout << "**************************************************" << endl;