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>
30 #include "AliITSMapA2.h"
31 #include "AliITSRawData.h"
32 #include "AliITSdigitSPD.h"
33 #include "AliITSetfSDD.h"
34 #include "AliITSmodule.h"
35 #include "AliITSpList.h"
36 #include "AliITSresponseSDD.h"
37 #include "AliITSCalibrationSDD.h"
38 #include "AliITSsegmentationSDD.h"
39 #include "AliITSsimulationSDD.h"
43 ClassImp(AliITSsimulationSDD)
44 ////////////////////////////////////////////////////////////////////////
46 // Written by Piergiorgio Cerello //
47 // November 23 1999 //
49 // AliITSsimulationSDD is the simulation of SDDs. //
50 ////////////////////////////////////////////////////////////////////////
52 //______________________________________________________________________
53 Int_t power(Int_t b, Int_t e) {
54 // compute b to the e power, where both b and e are Int_ts.
57 for(i=0; i<e; i++) power *= b;
60 //______________________________________________________________________
61 void FastFourierTransform(AliITSetfSDD *alisddetf,Double_t *real,
62 Double_t *imag,Int_t direction) {
63 // Do a Fast Fourier Transform
65 Int_t samples = alisddetf->GetSamples();
66 Int_t l = (Int_t) ((log((Float_t) samples)/log(2.))+0.5);
69 Int_t m2 = samples/m1;
72 for(j=0; j<samples; j += m1) {
74 for(k=j; k<= j+m-1; k++) {
75 Double_t wsr = alisddetf->GetWeightReal(p);
76 Double_t wsi = alisddetf->GetWeightImag(p);
77 if(direction == -1) wsi = -wsi;
78 Double_t xr = *(real+k+m);
79 Double_t xi = *(imag+k+m);
80 *(real+k+m) = wsr*(*(real+k)-xr) - wsi*(*(imag+k)-xi);
81 *(imag+k+m) = wsr*(*(imag+k)-xi) + wsi*(*(real+k)-xr);
92 for(j=0; j<samples; j++) {
96 for(i1=1; i1<=l; i1++) {
99 p = p + p + j2 - j1 - j1;
102 Double_t xr = *(real+j);
103 Double_t xi = *(imag+j);
104 *(real+j) = *(real+p);
105 *(imag+j) = *(imag+p);
110 if(direction == -1) {
111 for(i=0; i<samples; i++) {
112 *(real+i) /= samples;
113 *(imag+i) /= samples;
115 } // end if direction == -1
118 //______________________________________________________________________
119 AliITSsimulationSDD::AliITSsimulationSDD():
142 fCrosstalkFlag(kFALSE),
147 // Default constructor
149 SetPerpendTracksFlag();
154 //______________________________________________________________________
155 AliITSsimulationSDD::AliITSsimulationSDD(const AliITSsimulationSDD &source) :
156 AliITSsimulation(source),
158 fHitMap2(source.fHitMap2),
159 fHitSigMap2(source.fHitSigMap2),
160 fHitNoiMap2(source.fHitNoiMap2),
161 fStream(source.fStream),
162 fElectronics(source.fElectronics),
165 fOutZR(source.fOutZR),
166 fOutZI(source.fOutZI),
167 fAnodeFire(source.fAnodeFire),
173 fTreeB(source.fTreeB),
174 fParam(source.fParam),
175 fFileName(source.fFileName),
177 fCheckNoise(source.fCheckNoise),
178 fCrosstalkFlag(source.fCrosstalkFlag),
179 fDoFFT(source.fDoFFT),
180 fNofMaps(source.fNofMaps),
181 fMaxNofSamples(source.fMaxNofSamples),
182 fScaleSize(source.fScaleSize){
183 // Copy constructor to satify Coding roules only.
186 //______________________________________________________________________
187 AliITSsimulationSDD& AliITSsimulationSDD::operator=(const AliITSsimulationSDD &src){
188 // Assignment operator to satify Coding roules only.
190 if(this==&src) return *this;
191 Error("AliITSsimulationSDD","Not allowed to make a = with "
192 "AliITSsimulationSDD Using default creater instead");
195 //______________________________________________________________________
196 AliITSsimulation& AliITSsimulationSDD::operator=(const AliITSsimulation &src){
197 // Assignment operator to satify Coding roules only.
199 if(this==&src) return *this;
200 Error("AliITSsimulationSSD","Not allowed to make a = with "
201 "AliITSsimulationSDD Using default creater instead");
205 //______________________________________________________________________
206 AliITSsimulationSDD::AliITSsimulationSDD(AliITSDetTypeSim* dettyp):
207 AliITSsimulation(dettyp),
229 fCrosstalkFlag(kFALSE),
234 // Default Constructor
237 //______________________________________________________________________
238 void AliITSsimulationSDD::Init(){
239 // Standard Constructor
242 SetPerpendTracksFlag();
247 AliITSsegmentationSDD* seg = (AliITSsegmentationSDD*)GetSegmentationModel(1);
249 AliITSresponseSDD* res = (AliITSresponseSDD*)fDetType->GetResponse(1);
250 fpList = new AliITSpList( seg->Npz(),
251 fScaleSize*seg->Npx() );
252 fHitSigMap2 = new AliITSMapA2(seg,fScaleSize,1);
253 fHitNoiMap2 = new AliITSMapA2(seg,fScaleSize,1);
254 fHitMap2 = fHitSigMap2;
256 fNofMaps = seg->Npz();
257 fMaxNofSamples = seg->Npx();
258 fAnodeFire = new Bool_t [fNofMaps];
260 Float_t sddWidth = seg->Dz();
262 Float_t anodePitch = seg->Dpz(dummy);
263 Double_t timeStep = (Double_t)seg->Dpx(dummy);
265 if(anodePitch*(fNofMaps/2) > sddWidth) {
266 Warning("AliITSsimulationSDD",
267 "Too many anodes %d or too big pitch %f \n",
268 fNofMaps/2,anodePitch);
272 fElectronics = new AliITSetfSDD(timeStep/fScaleSize,
275 char opt1[20], opt2[20];
276 res->ParamOptions(opt1,opt2);
279 const char *kopt=res->ZeroSuppOption();
285 Bool_t write = res->OutputOption();
286 if(write && strstr(kopt,"2D")) MakeTreeB();
288 fITS = (AliITS*)gAlice->GetModule("ITS");
289 Int_t size = fNofMaps*fMaxNofSamples;
290 fStream = new AliITSInStream(size);
292 fInZR = new Double_t [fScaleSize*fMaxNofSamples];
293 fInZI = new Double_t [fScaleSize*fMaxNofSamples];
294 fOutZR = new Double_t [fScaleSize*fMaxNofSamples];
295 fOutZI = new Double_t [fScaleSize*fMaxNofSamples];
297 //______________________________________________________________________
298 AliITSsimulationSDD::~AliITSsimulationSDD() {
313 if(fTreeB) delete fTreeB;
314 if(fInZR) delete [] fInZR;
315 if(fInZI) delete [] fInZI;
316 if(fOutZR) delete [] fOutZR;
317 if(fOutZI) delete [] fOutZI;
318 if(fAnodeFire) delete [] fAnodeFire;
320 //______________________________________________________________________
321 void AliITSsimulationSDD::InitSimulationModule( Int_t module, Int_t event ) {
322 // create maps to build the lists of tracks for each summable digit
326 memset(fAnodeFire,0,sizeof(Bool_t)*fNofMaps);
328 //______________________________________________________________________
329 void AliITSsimulationSDD::ClearMaps() {
332 fHitSigMap2->ClearMap();
333 fHitNoiMap2->ClearMap();
335 //______________________________________________________________________
336 void AliITSsimulationSDD::SDigitiseModule(AliITSmodule *mod,Int_t md,Int_t ev){
337 // digitize module using the "slow" detector simulator creating
340 TObjArray *fHits = mod->GetHits();
341 Int_t nhits = fHits->GetEntriesFast();
344 InitSimulationModule( md, ev );
345 HitsToAnalogDigits( mod );
346 ChargeToSignal( fModule,kFALSE ); // - Process signal without add noise
347 fHitMap2 = fHitNoiMap2; // - Swap to noise map
348 ChargeToSignal( fModule,kTRUE ); // - Process only noise
349 fHitMap2 = fHitSigMap2; // - Return to signal map
353 //______________________________________________________________________
354 Bool_t AliITSsimulationSDD::AddSDigitsToModule(TClonesArray *pItemArray,
356 // Add Summable digits to module maps.
357 AliITSresponseSDD* res = (AliITSresponseSDD*)fDetType->GetResponse(1);
358 Int_t nItems = pItemArray->GetEntries();
359 Double_t maxadc = res->MaxAdc();
362 // cout << "Adding "<< nItems <<" SDigits to module " << fModule << endl;
363 for( Int_t i=0; i<nItems; i++ ) {
364 AliITSpListItem * pItem = (AliITSpListItem *)(pItemArray->At( i ));
365 if( pItem->GetModule() != fModule ) {
366 Error( "AliITSsimulationSDD","Error reading, SDigits module "
367 "%d != current module %d: exit",
368 pItem->GetModule(), fModule );
372 if(pItem->GetSignal()>0.0 ) sig = kTRUE;
374 fpList->AddItemTo( mask, pItem ); // Add SignalAfterElect + noise
375 AliITSpListItem * pItem2 = fpList->GetpListItem( pItem->GetIndex() );
376 Double_t sigAE = pItem2->GetSignalAfterElect();
377 if( sigAE >= maxadc ) sigAE = maxadc-1; // avoid overflow signal
380 fpList->GetMapIndex( pItem->GetIndex(), ia, it );
381 fHitMap2->SetHit( ia, it, sigAE );
382 fAnodeFire[ia] = kTRUE;
386 //______________________________________________________________________
387 void AliITSsimulationSDD::FinishSDigitiseModule() {
388 // digitize module using the "slow" detector simulator from
389 // the sum of summable digits.
393 //______________________________________________________________________
394 void AliITSsimulationSDD::DigitiseModule(AliITSmodule *mod,Int_t md,Int_t ev){
395 // create maps to build the lists of tracks for each digit
397 TObjArray *fHits = mod->GetHits();
398 Int_t nhits = fHits->GetEntriesFast();
400 InitSimulationModule( md, ev );
402 if( !nhits && fCheckNoise ) {
403 ChargeToSignal( fModule,kTRUE ); // process noise
410 HitsToAnalogDigits( mod );
411 ChargeToSignal( fModule,kTRUE ); // process signal + noise
413 for( Int_t i=0; i<fNofMaps; i++ ) {
414 for( Int_t j=0; j<fMaxNofSamples; j++ ) {
415 Int_t jdx = j*fScaleSize;
416 Int_t index = fpList->GetHitIndex( i, j );
417 AliITSpListItem pItemTmp2( fModule, index, 0. );
418 // put the fScaleSize analog digits in only one
419 for( Int_t ik=0; ik<fScaleSize; ik++ ) {
420 AliITSpListItem *pItemTmp = fpList->GetpListItem( i, jdx+ik );
421 if( pItemTmp == 0 ) continue;
422 pItemTmp2.Add( pItemTmp );
424 fpList->DeleteHit( i, j );
425 fpList->AddItemTo( 0, &pItemTmp2 );
431 //______________________________________________________________________
432 void AliITSsimulationSDD::FinishDigits() {
433 // introduce the electronics effects and do zero-suppression if required
435 ApplyDeadChannels(fModule);
436 if( fCrosstalkFlag ) ApplyCrosstalk(fModule);
438 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
439 const char *kopt = res->GetZeroSuppOption();
440 ZeroSuppression( kopt );
442 //______________________________________________________________________
443 void AliITSsimulationSDD::HitsToAnalogDigits( AliITSmodule *mod ) {
444 // create maps to build the lists of tracks for each digit
446 AliITSsegmentationSDD* seg = (AliITSsegmentationSDD*)GetSegmentationModel(1);
447 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
448 TObjArray *hits = mod->GetHits();
449 Int_t nhits = hits->GetEntriesFast();
451 // Int_t arg[6] = {0,0,0,0,0,0};
453 Int_t nofAnodes = fNofMaps/2;
454 Double_t sddLength = seg->Dx();
455 Double_t sddWidth = seg->Dz();
456 Double_t anodePitch = seg->Dpz(dummy);
457 Double_t timeStep = seg->Dpx(dummy);
458 Double_t driftSpeed ; // drift velocity (anode dependent)
459 //Float_t maxadc = res->GetMaxAdc();
460 //Float_t topValue = res->GetDynamicRange();
461 Double_t norm = res->GetMaxAdc()/res->GetDynamicRange(); // maxadc/topValue;
462 Double_t cHloss = res->GetChargeLoss();
463 Float_t dfCoeff, s1; res->DiffCoeff(dfCoeff,s1); // Signal 2d Shape
464 Double_t eVpairs = res->GetGeVToCharge()*1.0E9; // 3.6 eV by def.
465 Double_t nsigma = res->GetNSigmaIntegration(); //
466 Int_t nlookups = res->GetGausNLookUp(); //
467 Float_t jitter = res->GetJitterError(); //
469 // Piergiorgio's part (apart for few variables which I made float
470 // when i thought that can be done
471 // Fill detector maps with GEANT hits
472 // loop over hits in the module
474 const Float_t kconv = 1.0e+6; // GeV->KeV
476 Int_t hitDetector; // detector number (lay,lad,hitDetector)
477 Int_t iWing; // which detector wing/side.
478 Int_t detector; // 2*(detector-1)+iWing
479 Int_t ii,kk,ka,kt; // loop indexs
480 Int_t ia,it,index; // sub-pixel integration indexies
481 Int_t iAnode; // anode number.
482 Int_t timeSample; // time buckett.
483 Int_t anodeWindow; // anode direction charge integration width
484 Int_t timeWindow; // time direction charge integration width
485 Int_t jamin,jamax; // anode charge integration window
486 Int_t jtmin,jtmax; // time charge integration window
487 Int_t ndiv; // Anode window division factor.
488 Int_t nsplit; // the number of splits in anode and time windows==1.
489 Int_t nOfSplits; // number of times track length is split into
490 Float_t nOfSplitsF; // Floating point version of nOfSplits.
491 Float_t kkF; // Floating point version of loop index kk.
492 Double_t pathInSDD; // Track length in SDD.
493 Double_t drPath; // average position of track in detector. in microns
494 Double_t drTime; // Drift time
495 Double_t nmul; // drift time window multiplication factor.
496 Double_t avDrft; // x position of path length segment in cm.
497 Double_t avAnode; // Anode for path length segment in Anode number (float)
498 Double_t xAnode; // Floating point anode number.
499 Double_t driftPath; // avDrft in microns.
500 Double_t width; // width of signal at anodes.
501 Double_t depEnergy; // Energy deposited in this GEANT step.
502 Double_t xL[3],dxL[3]; // local hit coordinates and diff.
503 Double_t sigA; // sigma of signal at anode.
504 Double_t sigT; // sigma in time/drift direction for track segment
505 Double_t aStep,aConst; // sub-pixel size and offset anode
506 Double_t tStep,tConst; // sub-pixel size and offset time
507 Double_t amplitude; // signal amplitude for track segment in nanoAmpere
508 Double_t chargeloss; // charge loss for track segment.
509 Double_t anodeAmplitude; // signal amplitude in anode direction
510 Double_t aExpo; // exponent of Gaussian anode direction
511 Double_t timeAmplitude; // signal amplitude in time direction
512 Double_t tExpo; // exponent of Gaussian time direction
513 // Double_t tof; // Time of flight in ns of this step.
515 for(ii=0; ii<nhits; ii++) {
516 if(!mod->LineSegmentL(ii,xL[0],dxL[0],xL[1],dxL[1],xL[2],dxL[2],
517 depEnergy,itrack)) continue;
518 xL[0] += 0.0001*gRandom->Gaus( 0, jitter ); //
519 xAnode=10000.*(xL[2]+0.5*dxL[2])/anodePitch + nofAnodes/2;;
520 driftSpeed = res->GetDriftSpeedAtAnode(xAnode);
521 if(timeStep*fMaxNofSamples < sddLength/driftSpeed) {
522 Warning("AliITSsimulationSDD",
523 "Time Interval > Allowed Time Interval\n");
526 hitDetector = mod->GetDet();
527 //tof = 1.E+09*(mod->GetHit(ii)->GetTOF()); // tof in ns.
528 //if(tof>sddLength/driftSpeed) continue; // hit happed too late.
530 // scale path to simulate a perpendicular track
531 // continue if the particle did not lose energy
532 // passing through detector
535 Form("fTrack = %d hit=%d module=%d This particle has passed without losing energy!",
536 itrack,ii,mod->GetIndex()));
538 } // end if !depEnergy
540 pathInSDD = TMath::Sqrt(dxL[0]*dxL[0]+dxL[1]*dxL[1]+dxL[2]*dxL[2]);
542 if (fFlag && pathInSDD) { depEnergy *= (0.03/pathInSDD); }
543 drPath = 10000.*(dxL[0]+2.*xL[0])*0.5;
544 if(drPath < 0) drPath = -drPath;
545 drPath = sddLength-drPath;
547 AliDebug(1, // this should be fixed at geometry level
548 Form("negative drift path drPath=%e sddLength=%e dxL[0]=%e xL[0]=%e",
549 drPath,sddLength,dxL[0],xL[0]));
551 } // end if drPath < 0
553 // Compute number of segments to brake step path into
554 drTime = drPath/driftSpeed; // Drift Time
555 sigA = TMath::Sqrt(2.*dfCoeff*drTime+s1*s1);// Sigma along the anodes
556 // calcuate the number of time the path length should be split into.
557 nOfSplits = (Int_t) (1. + 10000.*pathInSDD/sigA);
558 if(fFlag) nOfSplits = 1;
560 // loop over path segments, init. some variables.
561 depEnergy /= nOfSplits;
562 nOfSplitsF = (Float_t) nOfSplits;
563 for(kk=0;kk<nOfSplits;kk++) { // loop over path segments
564 kkF = (Float_t) kk + 0.5;
565 avDrft = xL[0]+dxL[0]*kkF/nOfSplitsF;
566 avAnode = xL[2]+dxL[2]*kkF/nOfSplitsF;
567 driftPath = 10000.*avDrft;
569 iWing = 2; // Assume wing is 2
570 if(driftPath < 0) { // if wing is not 2 it is 1.
572 driftPath = -driftPath;
573 } // end if driftPath < 0
574 driftPath = sddLength-driftPath;
575 detector = 2*(hitDetector-1) + iWing;
577 AliDebug(1, // this should be fixed at geometry level
578 Form("negative drift path driftPath=%e sddLength=%e avDrft=%e dxL[0]=%e xL[0]=%e",
579 driftPath,sddLength,avDrft,dxL[0],xL[0]));
581 } // end if driftPath < 0
584 drTime = driftPath/driftSpeed; // drift time for segment.
585 timeSample = (Int_t) (fScaleSize*drTime/timeStep + 1);
586 // compute time Sample including tof information. The tof only
587 // effects the time of the signal is recoreded and not the
589 // timeSample = (Int_t) (fScaleSize*(drTime+tof)/timeStep + 1);
590 if(timeSample > fScaleSize*fMaxNofSamples) {
591 Warning("HitsToAnalogDigits","Wrong Time Sample: %e",
594 } // end if timeSample > fScaleSize*fMaxNoofSamples
597 xAnode = 10000.*(avAnode)/anodePitch + nofAnodes/2; // +1?
598 if(xAnode*anodePitch > sddWidth || xAnode*anodePitch < 0.)
599 Warning("HitsToAnalogDigits",
600 "Exceedubg sddWidth=%e Z = %e",
601 sddWidth,xAnode*anodePitch);
602 iAnode = (Int_t) (1.+xAnode); // xAnode?
603 if(iAnode < 1 || iAnode > nofAnodes) {
604 Warning("HitToAnalogDigits","Wrong iAnode: 1<%d>%d (xanode=%e)",
605 iAnode,nofAnodes, xAnode);
607 } // end if iAnode < 1 || iAnode > nofAnodes
609 // store straight away the particle position in the array
610 // of particles and take idhit=ii only when part is entering (this
611 // requires FillModules() in the macro for analysis) :
613 // Sigma along the anodes for track segment.
614 sigA = TMath::Sqrt(2.*dfCoeff*drTime+s1*s1);
615 sigT = sigA/driftSpeed;
616 // Peak amplitude in nanoAmpere
617 amplitude = fScaleSize*160.*depEnergy/
618 (timeStep*eVpairs*2.*acos(-1.)*sigT*sigA);
619 amplitude *= timeStep/25.; // WARNING!!!!! Amplitude scaling to
620 // account for clock variations
621 // (reference value: 40 MHz)
622 chargeloss = 1.-cHloss*driftPath/1000;
623 amplitude *= chargeloss;
624 width = 2.*nsigma/(nlookups-1);
632 } // end if drTime > 1200.
634 nsplit = 4; // hard-wired //nsplit=4;nsplit = (nsplit+1)/2*2;
635 // Sub-pixel size see computation of aExpo and tExpo.
636 aStep = anodePitch/(nsplit*fScaleSize*sigA);
637 aConst = xAnode*anodePitch/sigA;
638 tStep = timeStep/(nsplit*fScaleSize*sigT);
639 tConst = drTime/sigT;
640 // Define SDD window corresponding to the hit
641 anodeWindow = (Int_t)(fScaleSize*nsigma*sigA/anodePitch+1);
642 timeWindow = (Int_t) (fScaleSize*nsigma*sigT/timeStep+1.);
643 jamin = (iAnode - anodeWindow/ndiv - 1)*fScaleSize*nsplit +1;
644 jamax = (iAnode + anodeWindow/ndiv)*fScaleSize*nsplit;
645 if(jamin <= 0) jamin = 1;
646 if(jamax > fScaleSize*nofAnodes*nsplit)
647 jamax = fScaleSize*nofAnodes*nsplit;
648 // jtmin and jtmax are Hard-wired
649 jtmin = (Int_t)(timeSample-timeWindow*nmul-1)*nsplit+1;
650 jtmax = (Int_t)(timeSample+timeWindow*nmul)*nsplit;
651 if(jtmin <= 0) jtmin = 1;
652 if(jtmax > fScaleSize*fMaxNofSamples*nsplit)
653 jtmax = fScaleSize*fMaxNofSamples*nsplit;
654 // Spread the charge in the anode-time window
655 for(ka=jamin; ka <=jamax; ka++) {
656 ia = (ka-1)/(fScaleSize*nsplit) + 1;
658 Warning("HitsToAnalogDigits","ia < 1: ");
661 if(ia > nofAnodes) ia = nofAnodes;
662 aExpo = (aStep*(ka-0.5)-aConst);
663 if(TMath::Abs(aExpo) > nsigma) anodeAmplitude = 0.;
665 dummy = (Int_t) ((aExpo+nsigma)/width);
666 anodeAmplitude = amplitude*res->GetGausLookUp(dummy);
667 } // end if TMath::Abs(aEspo) > nsigma
668 // index starts from 0
669 index = ((detector+1)%2)*nofAnodes+ia-1;
670 if(anodeAmplitude) for(kt=jtmin; kt<=jtmax; kt++) {
671 it = (kt-1)/nsplit+1; // it starts from 1
673 Warning("HitsToAnalogDigits","it < 1:");
676 if(it>fScaleSize*fMaxNofSamples)
677 it = fScaleSize*fMaxNofSamples;
678 tExpo = (tStep*(kt-0.5)-tConst);
679 if(TMath::Abs(tExpo) > nsigma) timeAmplitude = 0.;
681 dummy = (Int_t) ((tExpo+nsigma)/width);
682 timeAmplitude = anodeAmplitude*
683 res->GetGausLookUp(dummy);
684 } // end if TMath::Abs(tExpo) > nsigma
685 // build the list of Sdigits for this module
688 // arg[2] = itrack; // track number
689 // arg[3] = ii-1; // hit number.
690 timeAmplitude *= norm;
692 // ListOfFiredCells(arg,timeAmplitude,alst,padr);
693 Double_t charge = timeAmplitude;
694 charge += fHitMap2->GetSignal(index,it-1);
695 fHitMap2->SetHit(index, it-1, charge);
696 fpList->AddSignal(index,it-1,itrack,ii-1,
697 mod->GetIndex(),timeAmplitude);
698 fAnodeFire[index] = kTRUE;
699 } // end if anodeAmplitude and loop over time in window
700 } // loop over anodes in window
701 } // end loop over "sub-hits"
702 } // end loop over hits
705 //______________________________________________________________________
706 void AliITSsimulationSDD::ListOfFiredCells(Int_t *arg,Double_t timeAmplitude,
707 TObjArray *alist,TClonesArray *padr){
708 // Returns the list of "fired" cells.
710 Int_t index = arg[0];
712 Int_t idtrack = arg[2];
713 Int_t idhit = arg[3];
714 Int_t counter = arg[4];
715 Int_t countadr = arg[5];
716 Double_t charge = timeAmplitude;
717 charge += fHitMap2->GetSignal(index,ik-1);
718 fHitMap2->SetHit(index, ik-1, charge);
721 Int_t it = (Int_t)((ik-1)/fScaleSize);
724 digits[2] = (Int_t)timeAmplitude;
726 if (idtrack >= 0) phys = (Float_t)timeAmplitude;
729 Double_t cellcharge = 0.;
730 AliITSTransientDigit* pdigit;
731 // build the list of fired cells and update the info
732 if (!fHitMap1->TestHit(index, it)) {
733 new((*padr)[countadr++]) TVector(3);
734 TVector &trinfo=*((TVector*) (*padr)[countadr-1]);
735 trinfo(0) = (Float_t)idtrack;
736 trinfo(1) = (Float_t)idhit;
737 trinfo(2) = (Float_t)timeAmplitude;
739 alist->AddAtAndExpand(new AliITSTransientDigit(phys,digits),counter);
740 fHitMap1->SetHit(index, it, counter);
742 pdigit=(AliITSTransientDigit*)alist->At(alist->GetLast());
744 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
745 trlist->Add(&trinfo);
747 pdigit = (AliITSTransientDigit*) fHitMap1->GetHit(index, it);
748 for(Int_t kk=0;kk<fScaleSize;kk++) {
749 cellcharge += fHitMap2->GetSignal(index,fScaleSize*it+kk);
752 (*pdigit).fSignal = (Int_t)cellcharge;
753 (*pdigit).fPhysics += phys;
754 // update list of tracks
755 TObjArray* trlist = (TObjArray*)pdigit->TrackList();
756 Int_t lastentry = trlist->GetLast();
757 TVector *ptrkp = (TVector*)trlist->At(lastentry);
758 TVector &trinfo = *ptrkp;
759 Int_t lasttrack = Int_t(trinfo(0));
760 Float_t lastcharge=(trinfo(2));
761 if (lasttrack==idtrack ) {
762 lastcharge += (Float_t)timeAmplitude;
763 trlist->RemoveAt(lastentry);
764 trinfo(0) = lasttrack;
766 trinfo(2) = lastcharge;
767 trlist->AddAt(&trinfo,lastentry);
769 new((*padr)[countadr++]) TVector(3);
770 TVector &trinfo=*((TVector*) (*padr)[countadr-1]);
771 trinfo(0) = (Float_t)idtrack;
772 trinfo(1) = (Float_t)idhit;
773 trinfo(2) = (Float_t)timeAmplitude;
774 trlist->Add(&trinfo);
775 } // end if lasttrack==idtrack
778 // check the track list - debugging
779 Int_t trk[20], htrk[20];
781 Int_t nptracks = trlist->GetEntriesFast();
784 for (tr=0;tr<nptracks;tr++) {
785 TVector *pptrkp = (TVector*)trlist->At(tr);
786 TVector &pptrk = *pptrkp;
787 trk[tr] = Int_t(pptrk(0));
788 htrk[tr] = Int_t(pptrk(1));
789 chtrk[tr] = (pptrk(2));
790 cout << "nptracks "<<nptracks << endl;
793 } // end if AliDebugLevel()
796 // update counter and countadr for next call.
801 //____________________________________________
802 void AliITSsimulationSDD::AddDigit( Int_t i, Int_t j, Int_t signal ) {
804 Int_t size = AliITSdigit::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
1091 if (strstr(option,"2D")) {
1092 //Init2D(); // activate if param change module by module
1094 } else if (strstr(option,"1D")) {
1095 //Init1D(); // activate if param change module by module
1097 } else StoreAllDigits();
1099 //______________________________________________________________________
1100 void AliITSsimulationSDD::Init2D(){
1101 // read in and prepare arrays: fD, fT1, fT2
1102 // savemu[nanodes], savesigma[nanodes]
1103 // read baseline and noise from file - either a .root file and in this
1104 // case data should be organised in a tree with one entry for each
1105 // module => reading should be done accordingly
1106 // or a classic file and do smth. like this ( code from Davide C. and
1108 // Read 2D zero-suppression parameters for SDD
1110 if (!strstr(fParam.Data(),"file")) return;
1112 Int_t na,pos,tempTh;
1114 Float_t *savemu = new Float_t [fNofMaps];
1115 Float_t *savesigma = new Float_t [fNofMaps];
1116 char input[100],basel[100],par[100];
1119 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1121 res->Thresholds(tmp1,tmp2);
1122 Int_t minval = static_cast<Int_t>(tmp1);
1124 res->Filenames(input,basel,par);
1127 filtmp = gSystem->ExpandPathName(fFileName.Data());
1128 FILE *param = fopen(filtmp,"r");
1132 while(fscanf(param,"%d %f %f",&pos, &mu, &sigma) != EOF) {
1134 Error("Init2D","Anode number not in increasing order!",filtmp);
1136 } // end if pos != na+1
1138 savesigma[na] = sigma;
1139 if ((2.*sigma) < mu) {
1140 fD[na] = (Int_t)floor(mu - 2.0*sigma + 0.5);
1143 tempTh = (Int_t)floor(mu+2.25*sigma+0.5) - minval;
1144 if (tempTh < 0) tempTh=0;
1146 tempTh = (Int_t)floor(mu+3.0*sigma+0.5) - minval;
1147 if (tempTh < 0) tempTh=0;
1152 Error("Init2D","THE FILE %s DOES NOT EXIST !",filtmp);
1159 delete [] savesigma;
1161 //______________________________________________________________________
1162 void AliITSsimulationSDD::Compress2D(){
1163 // simple ITS cluster finder -- online zero-suppression conditions
1167 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1169 res->Thresholds(tmp1,tmp2);
1170 Int_t minval = static_cast<Int_t>(tmp1);
1171 Bool_t write = res->OutputOption();
1172 Bool_t do10to8 = res->Do10to8();
1173 Int_t nz, nl, nh, low, i, j;
1175 for (i=0; i<fNofMaps; i++) {
1176 CompressionParam(i,db,tl,th);
1181 for (j=0; j<fMaxNofSamples; j++) {
1182 Int_t signal=(Int_t)(fHitMap2->GetSignal(i,j));
1183 signal -= db; // if baseline eq. is done here
1184 if (signal <= 0) {nz++; continue;}
1185 if ((signal - tl) < minval) low++;
1186 if ((signal - th) >= minval) {
1189 FindCluster(i,j,signal,minval,cond);
1191 ((TMath::Abs(fHitMap2->GetSignal(i,j-1))-th)>=minval)){
1192 if(do10to8) signal = Convert10to8(signal);
1193 AddDigit(i,j,signal);
1194 } // end if cond&&j&&()
1195 } else if ((signal - tl) >= minval) nl++;
1196 } // end for j loop time samples
1197 if (write) TreeB()->Fill(nz,nl,nh,low,i+1);
1198 } //end for i loop anodes
1202 sprintf(hname,"TNtuple%d_%d",fModule,fEvent);
1203 TreeB()->Write(hname);
1208 //______________________________________________________________________
1209 void AliITSsimulationSDD::FindCluster(Int_t i,Int_t j,Int_t signal,
1210 Int_t minval,Bool_t &cond){
1211 // Find clusters according to the online 2D zero-suppression algorithm
1212 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1213 AliITSsegmentationSDD* seg = (AliITSsegmentationSDD*)GetSegmentationModel(1);
1215 Bool_t do10to8 = res->Do10to8();
1216 Bool_t high = kFALSE;
1218 fHitMap2->FlagHit(i,j);
1220 // check the online zero-suppression conditions
1222 const Int_t kMaxNeighbours = 4;
1225 Int_t xList[kMaxNeighbours], yList[kMaxNeighbours];
1226 seg->Neighbours(i,j,&nn,xList,yList);
1228 for (in=0; in<nn; in++) {
1231 if (fHitMap2->TestHit(ix,iy)==kUnused) {
1232 CompressionParam(ix,dbx,tlx,thx);
1233 Int_t qn = (Int_t)(fHitMap2->GetSignal(ix,iy));
1234 qn -= dbx; // if baseline eq. is done here
1235 if ((qn-tlx) < minval) {
1236 fHitMap2->FlagHit(ix,iy);
1239 if ((qn - thx) >= minval) high=kTRUE;
1241 if(do10to8) signal = Convert10to8(signal);
1242 AddDigit(i,j,signal);
1244 if(do10to8) qns = Convert10to8(qn);
1246 if (!high) AddDigit(ix,iy,qns);
1248 if(!high) fHitMap2->FlagHit(ix,iy);
1249 } // end if qn-tlx < minval
1251 } // end for in loop over neighbours
1253 //______________________________________________________________________
1254 void AliITSsimulationSDD::Init1D(){
1255 // this is just a copy-paste of input taken from 2D algo
1256 // Torino people should give input
1257 // Read 1D zero-suppression parameters for SDD
1259 if (!strstr(fParam.Data(),"file")) return;
1261 Int_t na,pos,tempTh;
1263 Float_t *savemu = new Float_t [fNofMaps];
1264 Float_t *savesigma = new Float_t [fNofMaps];
1265 char input[100],basel[100],par[100];
1268 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1270 res->Thresholds(tmp1,tmp2);
1271 Int_t minval = static_cast<Int_t>(tmp1);
1273 res->Filenames(input,basel,par);
1276 // set first the disable and tol param
1279 filtmp = gSystem->ExpandPathName(fFileName.Data());
1280 FILE *param = fopen(filtmp,"r");
1284 fscanf(param,"%d %d %d %d ", &fT2[0], &fT2[1], &fTol[0], &fTol[1]);
1285 while(fscanf(param,"%d %f %f",&pos, &mu, &sigma) != EOF) {
1287 Error("Init1D","Anode number not in increasing order!",filtmp);
1289 } // end if pos != na+1
1291 savesigma[na]=sigma;
1292 if ((2.*sigma) < mu) {
1293 fD[na] = (Int_t)floor(mu - 2.0*sigma + 0.5);
1296 tempTh = (Int_t)floor(mu+2.25*sigma+0.5) - minval;
1297 if (tempTh < 0) tempTh=0;
1302 Error("Init1D","THE FILE %s DOES NOT EXIST !",filtmp);
1309 delete [] savesigma;
1311 //______________________________________________________________________
1312 void AliITSsimulationSDD::Compress1D(){
1313 // 1D zero-suppression algorithm (from Gianluca A.)
1314 Int_t dis,tol,thres,decr,diff;
1315 UChar_t *str=fStream->Stream();
1317 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1319 Bool_t do10to8=res->Do10to8();
1323 for (k=0; k<2; k++) {
1326 for (i=0; i<fNofMaps/2; i++) {
1327 Bool_t firstSignal=kTRUE;
1328 Int_t idx=i+k*fNofMaps/2;
1329 if( !fAnodeFire[idx] ) continue;
1330 CompressionParam(idx,decr,thres);
1332 for (j=0; j<fMaxNofSamples; j++) {
1333 Int_t signal=(Int_t)(fHitMap2->GetSignal(idx,j));
1334 signal -= decr; // if baseline eq.
1335 if(do10to8) signal = Convert10to8(signal);
1336 if (signal <= thres) {
1340 // write diff in the buffer for HuffT
1341 str[counter]=(UChar_t)diff;
1344 } // end if signal <= thres
1346 if (diff > 127) diff=127;
1347 if (diff < -128) diff=-128;
1349 // tol has changed to 8 possible cases ? - one can write
1350 // this if(TMath::Abs(diff)<tol) ... else ...
1351 if(TMath::Abs(diff)<tol) diff=0;
1352 // or keep it as it was before
1353 AddDigit(idx,j,last+diff);
1355 AddDigit(idx,j,signal);
1356 } // end if singal < dis
1358 // write diff in the buffer used to compute Huffman tables
1359 if (firstSignal) str[counter]=(UChar_t)signal;
1360 else str[counter]=(UChar_t)diff;
1364 } // end for j loop time samples
1365 } // end for i loop anodes one half of detector
1369 fStream->CheckCount(counter);
1371 // open file and write out the stream of diff's
1372 static Bool_t open=kTRUE;
1373 static TFile *outFile;
1374 Bool_t write = res->OutputOption();
1375 TDirectory *savedir = gDirectory;
1379 SetFileName("stream.root");
1380 cout<<"filename "<<fFileName<<endl;
1381 outFile=new TFile(fFileName,"recreate");
1382 cout<<"I have opened "<<fFileName<<" file "<<endl;
1389 fStream->ClearStream();
1391 // back to galice.root file
1392 if(savedir) savedir->cd();
1394 //______________________________________________________________________
1395 void AliITSsimulationSDD::StoreAllDigits(){
1396 // if non-zero-suppressed data
1397 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1399 Bool_t do10to8 = res->Do10to8();
1400 Int_t i, j, digits[3];
1402 for (i=0; i<fNofMaps; i++) {
1403 for (j=0; j<fMaxNofSamples; j++) {
1404 Int_t signal=(Int_t)(fHitMap2->GetSignal(i,j));
1405 if(do10to8) signal = Convert10to8(signal);
1409 fITS->AddRealDigit(1,digits);
1413 //______________________________________________________________________
1414 void AliITSsimulationSDD::CreateHistograms(Int_t scale){
1415 // Creates histograms of maps for debugging
1418 fHis=new TObjArray(fNofMaps);
1419 for (i=0;i<fNofMaps;i++) {
1420 TString sddName("sdd_");
1422 sprintf(candNum,"%d",i+1);
1423 sddName.Append(candNum);
1424 fHis->AddAt(new TH1F(sddName.Data(),"SDD maps",scale*fMaxNofSamples,
1425 0.,(Float_t) scale*fMaxNofSamples), i);
1428 //______________________________________________________________________
1429 void AliITSsimulationSDD::FillHistograms(){
1430 // fill 1D histograms from map
1434 for( Int_t i=0; i<fNofMaps; i++) {
1435 TH1F *hist =(TH1F *)fHis->UncheckedAt(i);
1436 Int_t nsamples = hist->GetNbinsX();
1437 for( Int_t j=0; j<nsamples; j++) {
1438 Double_t signal=fHitMap2->GetSignal(i,j);
1439 hist->Fill((Float_t)j,signal);
1443 //______________________________________________________________________
1444 void AliITSsimulationSDD::ResetHistograms(){
1445 // Reset histograms for this detector
1448 for (i=0;i<fNofMaps;i++ ) {
1449 if (fHis->At(i)) ((TH1F*)fHis->At(i))->Reset();
1452 //______________________________________________________________________
1453 TH1F *AliITSsimulationSDD::GetAnode(Int_t wing, Int_t anode) {
1454 // Fills a histogram from a give anode.
1456 if (!fHis) return 0;
1458 if(wing <=0 || wing > 2) {
1459 Warning("GetAnode","Wrong wing number: %d",wing);
1461 } // end if wing <=0 || wing >2
1462 if(anode <=0 || anode > fNofMaps/2) {
1463 Warning("GetAnode","Wrong anode number: %d",anode);
1465 } // end if ampde <=0 || andoe > fNofMaps/2
1467 Int_t index = (wing-1)*fNofMaps/2 + anode-1;
1468 return (TH1F*)(fHis->At(index));
1470 //______________________________________________________________________
1471 void AliITSsimulationSDD::WriteToFile(TFile *hfile) {
1472 // Writes the histograms to a file
1478 for(i=0; i<fNofMaps; i++) fHis->At(i)->Write(); //fAdcs[i]->Write();
1481 //______________________________________________________________________
1482 Float_t AliITSsimulationSDD::GetNoise() {
1483 // Returns the noise value
1484 //Bool_t do10to8=GetResp()->Do10to8();
1485 //noise will always be in the liniar part of the signal
1487 Int_t threshold = fT1[0];
1488 char opt1[20], opt2[20];
1489 AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule);
1491 res->GetParamOptions(opt1,opt2);
1493 Double_t noise,baseline;
1494 //GetBaseline(fModule);
1496 TCanvas *c2 = (TCanvas*)gROOT->GetListOfCanvases()->FindObject("c2");
1497 if(c2) delete c2->GetPrimitive("noisehist");
1498 if(c2) delete c2->GetPrimitive("anode");
1499 else c2=new TCanvas("c2");
1501 c2->SetFillColor(0);
1503 TH1F *noisehist = new TH1F("noisehist","noise",100,0.,(float)2*threshold);
1504 TH1F *anode = new TH1F("anode","Anode Projection",fMaxNofSamples,0.,
1505 (float)fMaxNofSamples);
1507 for (i=0;i<fNofMaps;i++) {
1508 CompressionParam(i,decr,threshold);
1509 baseline = res->GetBaseline(i);
1510 noise = res->GetNoise(i);
1512 for (k=0;k<fMaxNofSamples;k++) {
1513 Float_t signal=(Float_t)fHitMap2->GetSignal(i,k);
1514 //if (signal <= (float)threshold) noisehist->Fill(signal-baseline);
1515 if (signal <= (float)(threshold+decr)) noisehist->Fill(signal);
1516 anode->Fill((float)k,signal);
1521 TF1 *gnoise = new TF1("gnoise","gaus",0.,threshold);
1522 noisehist->Fit("gnoise","RQ");
1525 Float_t mnoise = gnoise->GetParameter(1);
1526 cout << "mnoise : " << mnoise << endl;
1527 Float_t rnoise = gnoise->GetParameter(2);
1528 cout << "rnoise : " << rnoise << endl;
1532 //______________________________________________________________________
1533 void AliITSsimulationSDD::WriteSDigits(){
1534 // Fills the Summable digits Tree
1535 static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
1537 for( Int_t i=0; i<fNofMaps; i++ ) {
1538 if( !fAnodeFire[i] ) continue;
1539 for( Int_t j=0; j<fMaxNofSamples; j++ ) {
1540 Double_t sig = fHitMap2->GetSignal( i, j );
1542 Int_t jdx = j*fScaleSize;
1543 Int_t index = fpList->GetHitIndex( i, j );
1544 AliITSpListItem pItemTmp2( fModule, index, 0. );
1545 // put the fScaleSize analog digits in only one
1546 for( Int_t ik=0; ik<fScaleSize; ik++ ) {
1547 AliITSpListItem *pItemTmp = fpList->GetpListItem(i,jdx+ik);
1548 if( pItemTmp == 0 ) continue;
1549 pItemTmp2.Add( pItemTmp );
1551 pItemTmp2.AddSignalAfterElect( fModule, index, sig );
1552 pItemTmp2.AddNoise(fModule,index,fHitNoiMap2->GetSignal(i,j));
1553 aliITS->AddSumDigit( pItemTmp2 );
1554 } // end if (sig > 0.2)
1559 //______________________________________________________________________
1560 void AliITSsimulationSDD::PrintStatus() const {
1561 // Print SDD simulation Parameters
1563 cout << "**************************************************" << endl;
1564 cout << " Silicon Drift Detector Simulation Parameters " << endl;
1565 cout << "**************************************************" << endl;
1566 cout << "Flag for Perpendicular tracks: " << (Int_t) fFlag << endl;
1567 cout << "Flag for noise checking: " << (Int_t) fCheckNoise << endl;
1568 cout << "Flag to switch off electronics: " << (Int_t) fDoFFT << endl;
1569 cout << "Number pf Anodes used: " << fNofMaps << endl;
1570 cout << "Number of Time Samples: " << fMaxNofSamples << endl;
1571 cout << "Scale size factor: " << fScaleSize << endl;
1572 cout << "**************************************************" << endl;