From f6b6d58eb61ce9204a5ac3be880a8ee50112d01b Mon Sep 17 00:00:00 2001 From: masera Date: Wed, 13 Feb 2008 10:50:40 +0000 Subject: [PATCH] Anode numbering adapted to hardware channel numbering + Code cleanup of segmentation classes + Bug fix in the gaussian smearing of charge signal in AliITSsimulationSDD + new calibration of the SDD time offset (F. Prino) --- ITS/AliITSClusterFinderSDD.cxx | 11 +- ITS/AliITSClusterFinderV2SDD.cxx | 228 ++++++------ ITS/AliITSresponseSDD.cxx | 2 +- ITS/AliITSsegmentation.cxx | 11 + ITS/AliITSsegmentation.h | 22 +- ITS/AliITSsegmentationSDD.cxx | 266 +++++++------- ITS/AliITSsegmentationSDD.h | 23 +- ITS/AliITSsegmentationSPD.cxx | 7 +- ITS/AliITSsegmentationSPD.h | 4 +- ITS/AliITSsegmentationSSD.cxx | 5 +- ITS/AliITSsimulationSDD.cxx | 367 ++++++++++---------- ITS/Calib/RespSDD/Run0_999999999_v0_s0.root | Bin 3449 -> 3449 bytes 12 files changed, 453 insertions(+), 493 deletions(-) diff --git a/ITS/AliITSClusterFinderSDD.cxx b/ITS/AliITSClusterFinderSDD.cxx index de10ca30076..5895ac976f4 100644 --- a/ITS/AliITSClusterFinderSDD.cxx +++ b/ITS/AliITSClusterFinderSDD.cxx @@ -108,7 +108,6 @@ void AliITSClusterFinderSDD::Find1DClusters(){ Int_t dummy = 0; Double_t fTimeStep = GetSeg()->Dpx(dummy); Double_t fSddLength = GetSeg()->Dx(); - Double_t anodePitch = GetSeg()->Dpz(dummy); AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(fModule); AliITSresponseSDD* res = (AliITSresponseSDD*)((AliITSCalibrationSDD*)GetResp(fModule))->GetResponse(); const char *option=res->ZeroSuppOption(); @@ -223,9 +222,8 @@ void AliITSClusterFinderSDD::Find1DClusters(){ //ns } // end if } // end for its - - Double_t clusteranodePath = (clusterAnode - fNofAnodes/2)* - anodePitch; + Float_t theAnode=clusterAnode+j*fNofAnodes; + Double_t clusteranodePath = GetSeg()->GetLocalZFromAnode(theAnode); Double_t clusterDriftPath = (Double_t)cal->GetDriftPath(clusterTime,clusteranodePath); clusterDriftPath = fSddLength-clusterDriftPath; if(clusterCharge <= 0.) break; @@ -261,7 +259,6 @@ void AliITSClusterFinderSDD::Find1DClustersE(){ Int_t dummy=0; Double_t fTimeStep = GetSeg()->Dpx( dummy ); Double_t fSddLength = GetSeg()->Dx(); - Double_t anodePitch = GetSeg()->Dpz( dummy ); AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(fModule); Map()->ClearMap(); Map()->SetThresholdArr( fCutAmplitude ); @@ -326,8 +323,8 @@ void AliITSClusterFinderSDD::Find1DClustersE(){ time /= (charge/fTimeStep); // ns // time = lmax*fTimeStep; // ns if( time > fTimeCorr ) time -= fTimeCorr; // ns - Double_t anodePath =(anode-fNofAnodes/2)*anodePitch; - + Float_t theAnode=anode+j*fNofAnodes; + Double_t anodePath =GetSeg()->GetLocalZFromAnode(theAnode); Double_t driftPath = (Double_t)cal->GetDriftPath(time,anode); driftPath = fSddLength-driftPath; AliITSRawClusterSDD clust(j+1,anode,time,charge, diff --git a/ITS/AliITSClusterFinderV2SDD.cxx b/ITS/AliITSClusterFinderV2SDD.cxx index 630c3bb6d4c..72e874e3666 100644 --- a/ITS/AliITSClusterFinderV2SDD.cxx +++ b/ITS/AliITSClusterFinderV2SDD.cxx @@ -61,7 +61,7 @@ void AliITSClusterFinderV2SDD::FindClustersSDD(TClonesArray *digits) { Int_t nzBins = nAnodes+2; Int_t nTimeBins = GetSeg()->Npx(); Int_t nxBins = nTimeBins+2; - const Int_t kMaxBin=nzBins*(nxBins+2); + const Int_t kMaxBin=nzBins*nxBins; AliBin *bins[2]; bins[0]=new AliBin[kMaxBin]; @@ -130,20 +130,20 @@ FindClustersSDD(AliBin* bins[2], Int_t nMaxBin, Int_t nzBins, for (k=0; k1 || dj>1) continue; - if (bins[s][idx[k]].GetQ() > bins[s][idx[l]].GetQ()) { - msk[l]=msk[k]; - idx[l]*=-1; - } else { - msk[k]=msk[l]; - idx[k]*=-1; - break; - } + if (idx[l] < 0) continue; //this peak is already removed + Int_t ki=idx[k]/nzBins, kj=idx[k] - ki*nzBins; + Int_t li=idx[l]/nzBins, lj=idx[l] - li*nzBins; + Int_t di=TMath::Abs(ki - li); + Int_t dj=TMath::Abs(kj - lj); + if (di>1 || dj>1) continue; + if (bins[s][idx[k]].GetQ() > bins[s][idx[l]].GetQ()) { + msk[l]=msk[k]; + idx[l]*=-1; + } else { + msk[k]=msk[l]; + idx[k]*=-1; + break; + } } } @@ -152,112 +152,102 @@ FindClustersSDD(AliBin* bins[2], Int_t nMaxBin, Int_t nzBins, } for (k=0; kGetQ())/5.,3.); - - for (Int_t di=-2; di<=2;di++){ - for (Int_t dj=-3;dj<=3;dj++){ - Int_t index = idx[k]+di+dj*nzBins; - if (index<0) continue; - if (index>=nMaxBin) continue; - AliBin *b=&bins[s][index]; - Int_t nAnode=index%nzBins-1; - Int_t adcSignal=b->GetQ(); - if(adcSignal>cal->GetThresholdAnode(nAnode)){ - if (di>maxi) maxi=di; - if (dimaxj) maxj=dj; - if (djUncheckedAt(b->GetIndex()); - for (Int_t itrack=0;itrack<10;itrack++){ - Int_t track = (d->GetTracks())[itrack]; - if (track>=0) { - AddLabel(milab, track); - } - } - } - } - } - } - - - Float_t y=c.GetY(),z=c.GetZ(), q=c.GetQ(); - y/=q; z/=q; - - - const Double_t kMicronTocm = 1.0e-4; - Float_t timeBinCenter = y-0.5; - Float_t zAnode=z-0.5; - Float_t zdet = (zAnode*GetSeg()->Dpz(0)-GetSeg()->Dz()/2.)*kMicronTocm; - Float_t driftTime = timeBinCenter*GetSeg()->Dpx(0) - cal->GetTimeOffset(); - Float_t xdet = cal->GetDriftPath(driftTime,zAnode); - xdet=(xdet-GetSeg()->Dx())*kMicronTocm; - if (s) xdet=-xdet; - + if (idx[k] < 0) continue; //removed peak + AliITSRecPoint c; + MakeCluster(idx[k], nzBins, bins[s], msk[k], c); + //mi change + Int_t milab[10]; + for (Int_t ilab=0;ilab<10;ilab++){ + milab[ilab]=-2; + } + Int_t maxi=0,mini=0,maxj=0,minj=0; + //AliBin *bmax=&bins[s][idx[k]]; + //Float_t max = TMath::Max(TMath::Abs(bmax->GetQ())/5.,3.); + + for (Int_t di=-2; di<=2;di++){ + for (Int_t dj=-3;dj<=3;dj++){ + Int_t index = idx[k]+di+dj*nzBins; + if (index<0) continue; + if (index>=nMaxBin) continue; + AliBin *b=&bins[s][index]; + Int_t nAnode=index%nzBins-1; + Int_t adcSignal=b->GetQ(); + if(adcSignal>cal->GetThresholdAnode(nAnode)){ + if (di>maxi) maxi=di; + if (dimaxj) maxj=dj; + if (djUncheckedAt(b->GetIndex()); + for (Int_t itrack=0;itrack<10;itrack++){ + Int_t track = (d->GetTracks())[itrack]; + if (track>=0) { + AddLabel(milab, track); + } + } + } + } + } + } + + + Float_t y=c.GetY(),z=c.GetZ(), q=c.GetQ(); + y/=q; z/=q; + Float_t zAnode=z-0.5; // to have anode in range 0.-255. and centered on the mid of the pitch + Float_t timebin=y-0.5; // to have time bin in range 0.-255. amd centered on the mid of the bin + if(s==1) zAnode += GetSeg()->NpzHalf(); // right side has anodes from 256. to 511. + Float_t zdet = GetSeg()->GetLocalZFromAnode(zAnode); + Float_t driftTime = GetSeg()->GetDriftTimeFromTb(timebin) - cal->GetTimeOffset(); + Float_t driftPathMicron = cal->GetDriftPath(driftTime,zAnode); + const Double_t kMicronTocm = 1.0e-4; + Float_t xdet=(driftPathMicron-GetSeg()->Dx())*kMicronTocm; // xdet is negative + if (s==0) xdet=-xdet; // left side has positive local x - CorrectPosition(zdet,xdet); - - Double_t loc[3]={xdet,0.,zdet},trk[3]={0.,0.,0.}; - mT2L->MasterToLocal(loc,trk); - y=trk[1]; - z=trk[2]; - - q/=cal->GetADC2keV(); //to have MPV 1 MIP = 86.4 KeV - Float_t hit[5] = {y, z, 0.0030*0.0030, 0.0020*0.0020, q}; - Int_t info[3] = {maxj-minj+1, maxi-mini+1, fNlayer[fModule]}; - if (digits) { - // AliBin *b=&bins[s][idx[k]]; - // AliITSdigitSDD* d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex()); - { - //Int_t lab[3]; - //lab[0]=(d->GetTracks())[0]; - //lab[1]=(d->GetTracks())[1]; - //lab[2]=(d->GetTracks())[2]; - //CheckLabels(lab); - CheckLabels2(milab); - } - } - milab[3]=fNdet[fModule]; - - AliITSRecPoint cc(milab,hit,info); - cc.SetType(npeaks); - - if(clusters) new (cl[ncl]) AliITSRecPoint(cc); - else { - fDetTypeRec->AddRecPoint(cc); - } - ncl++; + CorrectPosition(zdet,xdet); + + Double_t loc[3]={xdet,0.,zdet},trk[3]={0.,0.,0.}; + mT2L->MasterToLocal(loc,trk); + y=trk[1]; + z=trk[2]; + + q/=cal->GetADC2keV(); //to have MPV 1 MIP = 86.4 KeV + Float_t hit[5] = {y, z, 0.0030*0.0030, 0.0020*0.0020, q}; + Int_t info[3] = {maxj-minj+1, maxi-mini+1, fNlayer[fModule]}; + if (digits) { + // AliBin *b=&bins[s][idx[k]]; + // AliITSdigitSDD* d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex()); + { + //Int_t lab[3]; + //lab[0]=(d->GetTracks())[0]; + //lab[1]=(d->GetTracks())[1]; + //lab[2]=(d->GetTracks())[2]; + //CheckLabels(lab); + CheckLabels2(milab); + } + } + milab[3]=fNdet[fModule]; + + AliITSRecPoint cc(milab,hit,info); + cc.SetType(npeaks); + if(clusters) new (cl[ncl]) AliITSRecPoint(cc); + else { + fDetTypeRec->AddRecPoint(cc); + } + ncl++; } } } - - - +//______________________________________________________________________ void AliITSClusterFinderV2SDD::RawdataToClusters(AliRawReader* rawReader,TClonesArray** clusters){ //------------------------------------------------------------ // This function creates ITS clusters from raw data //------------------------------------------------------------ rawReader->Reset(); AliITSRawStreamSDD inputSDD(rawReader); - /* - AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(240); - printf("gain anode 10=%f\n",cal->GetDriftSpeedAtAnode(10)); - printf("drift speed anode 10=%f\n",cal->GetChannelGain(10)); - */ AliITSDDLModuleMapSDD *ddlmap=(AliITSDDLModuleMapSDD*)fDetTypeRec->GetDDLModuleMapSDD(); inputSDD.SetDDLModuleMap(ddlmap); FindClustersSDD(&inputSDD,clusters); @@ -275,7 +265,7 @@ void AliITSClusterFinderV2SDD::FindClustersSDD(AliITSRawStream* input, Int_t nzBins = nAnodes+2; Int_t nTimeBins = GetSeg()->Npx(); Int_t nxBins = nTimeBins+2; - const Int_t kMaxBin=nzBins*(nxBins+2); + const Int_t kMaxBin=nzBins*nxBins; AliBin *bins[2]; AliBin *ddlbins[kHybridsPerDDL]; // 12 modules (=24 hybrids) of 1 DDL read "in parallel" for(Int_t iHyb=0;iHybWings()*cal->Chips()*cal->Channels(); + Int_t bina =(Int_t) GetSeg()->GetAnodeFromLocal(y,z); + if(bina>knbina) AliError("Wrong bin number along anodes!"); + static const Int_t knbint = cal->GetMapTimeNBin(); - static const Int_t knbina = cal->Chips()*cal->Channels(); const Double_t kMicronTocm = 1.0e-4; - Float_t stepa = (GetSeg()->Dpz(0))*kMicronTocm; //anode pitch in cm - Float_t stept = (GetSeg()->Dx()/cal->GetMapTimeNBin()/2.)/10.; - + Float_t stept = GetSeg()->Dx()*kMicronTocm/cal->GetMapTimeNBin(); Int_t bint = TMath::Abs((Int_t)(y/stept)); - if(y>=0) bint+=(Int_t)(knbint/2.); - if(bint>knbint) AliError("Wrong bin number!"); - - Int_t bina = TMath::Abs((Int_t)(z/stepa)); - if(z>=0) bina+=(Int_t)(knbina/2.); - if(bina>knbina) AliError("Wrong bin number!"); + if(bint>knbint) AliError("Wrong bin number along drift direction!"); Float_t devz = cal->GetMapACell(bina,bint)*kMicronTocm; Float_t devx = cal->GetMapTCell(bina,bint)*kMicronTocm; diff --git a/ITS/AliITSresponseSDD.cxx b/ITS/AliITSresponseSDD.cxx index 70b4b6dccc4..e7b963a3774 100644 --- a/ITS/AliITSresponseSDD.cxx +++ b/ITS/AliITSresponseSDD.cxx @@ -37,7 +37,7 @@ const TString AliITSresponseSDD::fgkParam1Default = "same"; const TString AliITSresponseSDD::fgkParam2Default = "same"; const TString AliITSresponseSDD::fgkOptionDefault = "1D"; const Float_t AliITSresponseSDD::fgkDriftSpeedDefault = 7.3; -const Float_t AliITSresponseSDD::fgkTimeOffsetDefault = 54.57; +const Float_t AliITSresponseSDD::fgkTimeOffsetDefault = 54.07; const Float_t AliITSresponseSDD::fgkADC2keVDefault = 5.243; const Float_t AliITSresponseSDD::fgkNsigmasDefault = 3.; const Int_t AliITSresponseSDD::fgkNcompsDefault = 121; diff --git a/ITS/AliITSsegmentation.cxx b/ITS/AliITSsegmentation.cxx index 10abd1c4555..44d71cb0697 100644 --- a/ITS/AliITSsegmentation.cxx +++ b/ITS/AliITSsegmentation.cxx @@ -23,6 +23,17 @@ fCorr(0){ // Default constructor } +//_____________________________________________________________ +AliITSsegmentation::AliITSsegmentation(AliITSgeom* geom): +fDx(0), +fDz(0), +fDy(0), +fGeom(0), +fCorr(0){ + // Default constructor + fGeom=geom; +} + //_____________________________________________________________ AliITSsegmentation::~AliITSsegmentation(){ diff --git a/ITS/AliITSsegmentation.h b/ITS/AliITSsegmentation.h index b3be113f236..76eadb9e995 100644 --- a/ITS/AliITSsegmentation.h +++ b/ITS/AliITSsegmentation.h @@ -2,9 +2,10 @@ #define ALIITSSEGMENTATION_H #include +#include "AliLog.h" +#include "AliITSgeom.h" class TF1; -class AliITSgeom; //---------------------------------------------- // // ITS segmentation virtual base class @@ -13,6 +14,7 @@ class AliITSsegmentation : public TObject { public: AliITSsegmentation(); + AliITSsegmentation(AliITSgeom *geom); AliITSsegmentation(const AliITSsegmentation& source); virtual ~AliITSsegmentation(); AliITSsegmentation& operator=(const AliITSsegmentation &source); @@ -33,12 +35,22 @@ public TObject { virtual void GetPadIxz(Float_t,Float_t,Int_t &,Int_t &) const = 0; // Transform from cell to real coordinates virtual void GetPadCxz(Int_t,Int_t,Float_t &,Float_t &) const = 0; + // Transform from real global to local coordinates - virtual void GetLocal(Int_t,Float_t *,Float_t *) const - {MayNotUse("GetLocal");} + void GetLocal(Int_t module,Float_t *g ,Float_t *l) const { + if(!fGeom) { + AliFatal("Pointer to ITS geometry class (AliITSgeom) is null\n"); + return; + } + fGeom->GtoL(module,g,l); + } // Transform from real local to global coordinates - virtual void GetGlobal(Int_t,Float_t *,Float_t *) const - {MayNotUse("GetGlobal");} + void GetGlobal(Int_t module,Float_t *l ,Float_t *g) const { + if(!fGeom) { + AliFatal("Pointer to ITS geometry class (AliITSgeom) is null\n"); + } + fGeom->LtoG(module,l,g); + } // Local transformation of real local coordinates - virtual void GetPadTxz(Float_t &,Float_t &) const = 0; // Transformation from Geant cm detector center local coordinates diff --git a/ITS/AliITSsegmentationSDD.cxx b/ITS/AliITSsegmentationSDD.cxx index 1ea2beaf800..456dd0ddc6f 100644 --- a/ITS/AliITSsegmentationSDD.cxx +++ b/ITS/AliITSsegmentationSDD.cxx @@ -16,15 +16,33 @@ #include #include "AliITSsegmentationSDD.h" -// #include "AliITS.h" -#include "AliITSgeom.h" #include "AliITSgeomSDD.h" #include "AliITSresponseSDD.h" -////////////////////////////////////////////////////// -// Segmentation class for // -// drift detectors // -// // -////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Segmentation class for drift detectors // +// // +// microcables microcables // +// /\ /\ // +// || || // +// || || // +// || || // +// 0 256 0 // +// 0 |----------------------|---------------------| 511 // +// | time-bins | time-bins | // +// | a | a | // +// | n | n | // +// X <_|_o____________________|___________________o_|__ // +// | d | d | // +// | e LEFT SIDE | RIGHT SIDE e | // +// | s CHANNEL 0 | CHANNEL 1 s | // +// | Xlocal > 0 | Xlocal < 0 | // +// 255 |----------------------|---------------------| 256 // +// | // +// | // +// V // +// Z // +///////////////////////////////////////////////////////////////////////////// const Float_t AliITSsegmentationSDD::fgkDxDefault = 35085.; const Float_t AliITSsegmentationSDD::fgkDzDefault = 75264.; @@ -33,10 +51,12 @@ const Float_t AliITSsegmentationSDD::fgkPitchDefault = 294.; const Float_t AliITSsegmentationSDD::fgkClockDefault = 40.; const Int_t AliITSsegmentationSDD::fgkHalfNanodesDefault = 256; const Int_t AliITSsegmentationSDD::fgkNsamplesDefault = 256; - +const Float_t AliITSsegmentationSDD::fgkCm2Micron = 10000.; +const Float_t AliITSsegmentationSDD::fgkMicron2Cm = 1.0E-04; ClassImp(AliITSsegmentationSDD) //---------------------------------------------------------------------- AliITSsegmentationSDD::AliITSsegmentationSDD(AliITSgeom* geom): +AliITSsegmentation(geom), fNsamples(0), fNanodes(0), fPitch(0), @@ -44,13 +64,11 @@ fTimeStep(0), fDriftSpeed(0), fSetDriftSpeed(0){ // constructor - fGeom=geom; fDriftSpeed=AliITSresponseSDD::DefaultDriftSpeed(); fCorr=0; SetDetSize(fgkDxDefault,fgkDzDefault,fgkDyDefault); SetPadSize(fgkPitchDefault,fgkClockDefault); SetNPads(fgkHalfNanodesDefault,fgkNsamplesDefault); - } //______________________________________________________________________ AliITSsegmentationSDD::AliITSsegmentationSDD() : AliITSsegmentation(), @@ -65,7 +83,6 @@ fSetDriftSpeed(0){ SetDetSize(fgkDxDefault,fgkDzDefault,fgkDyDefault); SetPadSize(fgkPitchDefault,fgkClockDefault); SetNPads(fgkHalfNanodesDefault,fgkNsamplesDefault); - } //______________________________________________________________________ @@ -106,15 +123,14 @@ void AliITSsegmentationSDD::Init(){ // Standard initilisation routine if(!fGeom) { - Fatal("Init","the pointer to the ITS geometry class (AliITSgeom) is null\n"); + AliFatal("Pointer to ITS geometry class (AliITSgeom) is null\n"); return; } AliITSgeomSDD *gsdd = (AliITSgeomSDD *) (fGeom->GetShape(3,1,1)); - const Float_t kconv=10000.; - fDz = 2.*kconv*gsdd->GetDz(); - fDx = kconv*gsdd->GetDx(); - fDy = 2.*kconv*gsdd->GetDy(); + fDz = 2.*fgkCm2Micron*gsdd->GetDz(); + fDx = fgkCm2Micron*gsdd->GetDx(); + fDy = 2.*fgkCm2Micron*gsdd->GetDy(); } //---------------------------------------------------------------------- @@ -137,52 +153,73 @@ Neighbours(Int_t iX, Int_t iZ, Int_t* Nlist, Int_t Xlist[8], Int_t Zlist[8]) con Zlist[2]=Zlist[3]=iZ; } //---------------------------------------------------------------------- +Float_t AliITSsegmentationSDD::GetAnodeFromLocal(Float_t xloc,Float_t zloc) const { + // returns anode coordinate (as float) starting from local coordinates + Float_t xAnode=zloc*fgkCm2Micron/fPitch; + if(xloc>0){ // left side (anodes 0-255, anode 0 at zloc<0) + xAnode+=(Float_t)fNanodes/4; + }else{ // right side (anodes 256-511, anode 0 at zloc>0) + xAnode=3*fNanodes/4-xAnode; + } + return xAnode; +} + +//---------------------------------------------------------------------- +Float_t AliITSsegmentationSDD::GetLocalZFromAnode(Int_t nAnode) const{ + // returns local Z coordinate from anode number (integer) + Float_t zAnode=(Float_t)nAnode+0.5; + return GetLocalZFromAnode(zAnode); +} + +//---------------------------------------------------------------------- +Float_t AliITSsegmentationSDD::GetLocalZFromAnode(Float_t zAnode) const{ + // returns local Z coordinate from anode number (float) + Float_t zloc=0.; + if(zAnodeum + // expects x, z in cm - x *= kconv; // Convert to microns - z *= kconv; // Convert to microns - Int_t na = fNanodes/2; - Float_t driftpath=fDx-TMath::Abs(x); - timebin=(Int_t)(driftpath/fDriftSpeed/fTimeStep); - anode=(Int_t)(z/fPitch + na/2); - if (x > 0) anode += na; - - timebin+=1; - anode+=1; - if(!fSetDriftSpeed){ - timebin=-999; - Warning("GetPadIxz","Drift speed not set: timebin is dummy"); - } + Float_t driftpath=fDx-TMath::Abs(x*fgkCm2Micron); + timebin=(Int_t)(driftpath/fDriftSpeed/fTimeStep); + anode=(Int_t)GetAnodeFromLocal(x,z); + if(!fSetDriftSpeed){ + timebin=-999; + AliWarning("Drift speed not set: timebin is dummy"); + } } //---------------------------------------------------------------------- void AliITSsegmentationSDD::GetPadCxz(Int_t timebin,Int_t anode, Float_t &x ,Float_t &z) const{ - // Transform from cell to real local coordinates - // returns x, z in cm + // Transform from cell to real local coordinates + // returns x, z in cm // the +0.5 means that an # and time bin # should start from 0 !!! - const Float_t kconv=10000; // um->cm // the +0.5 means that an # and time bin # should start from 0 !!! - Int_t na = fNanodes/2; - Float_t driftpath=(timebin+0.5)*fTimeStep*fDriftSpeed; - if (anode >= na) x=(fDx-driftpath)/kconv; - else x = -(fDx-driftpath)/kconv; - if (anode >= na) anode-=na; - z=((anode+0.5)*fPitch-fDz/2)/kconv; - if(!fSetDriftSpeed){ - x=-9999.; - Warning("GetPadCxz","Drift speed not set: x coord. is dummy"); - } - + Float_t driftpath=GetDriftTimeFromTb(timebin)*fDriftSpeed; + if (anode < fNanodes/2){ // left side, positive x + x=(fDx-driftpath)*fgkMicron2Cm; + }else{ // right side, negative x + x = -(fDx-driftpath)*fgkMicron2Cm; + } + z=GetLocalZFromAnode(anode); + if(!fSetDriftSpeed){ + x=-9999.; + AliWarning("Drift speed not set: x coord. is dummy"); + } } //---------------------------------------------------------------------- void AliITSsegmentationSDD::GetPadTxz(Float_t &x,Float_t &z) const{ @@ -190,37 +227,16 @@ void AliITSsegmentationSDD::GetPadTxz(Float_t &x,Float_t &z) const{ // expects x, z in cm - const Float_t kconv=10000; // cm->um - - Float_t x0=x; - Int_t na = fNanodes/2; - Float_t driftpath=fDx-TMath::Abs(kconv*x); + Float_t xloc=x; + Float_t zloc=z; + Float_t driftpath=fDx-TMath::Abs(fgkCm2Micron*xloc); x=driftpath/fDriftSpeed/fTimeStep; - z=kconv*z/fPitch + (float)na/2; - if (x0 < 0) x = -x; + if (xloc < 0) x = -x; + z=GetAnodeFromLocal(xloc,zloc); if(!fSetDriftSpeed){ x=-9999.; - Warning("GetPadTxz","Drift speed not set: x coord. is dummy"); - } -} -//---------------------------------------------------------------------- -void AliITSsegmentationSDD::GetLocal(Int_t module,Float_t *g ,Float_t *l) const { - // returns local coordinates from global - if(!fGeom) { - Fatal("GetLocal","the pointer to the ITS geometry class (AliITSgeom) is null\n"); - return; - } - fGeom->GtoL(module,g,l); -} -//---------------------------------------------------------------------- -void AliITSsegmentationSDD::GetGlobal(Int_t module,Float_t *l ,Float_t *g) const { - // return global coordinates from local - if(!fGeom) { - Fatal("GetGlobal","the pointer to the ITS geometry class (AliITSgeom) is null\n"); + AliWarning("Drift speed not set: x coord. is dummy"); } - - fGeom->LtoG(module,l,g); - } //---------------------------------------------------------------------- void AliITSsegmentationSDD::Print(Option_t *opt) const { @@ -278,48 +294,25 @@ Bool_t AliITSsegmentationSDD::LocalToDet(Float_t x,Float_t z, // Int_t iz detector z anode coordinate. Has the range 0<=izDeriftSpeed()=7.3mic/ns, Dpz()=512. For other values a only the -// specific numbers will change not their layout.} -// -// 0 191 0 -// 0 |----------------------|---------------------| 256 -// | a time-bins | time-bins a | -// | n | n | -// | o |___________________o_|__> X -// | d | d | -// | e | e | -// | s | s | -// 255 |----------------------|---------------------| 511 -// | -// V -// Z - Float_t dx,dz,tb; - const Float_t kconv = 1.0E-04; // converts microns to cm. + + Float_t dx,dz; ix = -1; // default values iz = -1; // default values - dx = -kconv*Dx(); // lower left edge in cm. - dz = -0.5*kconv*Dz(); // lower left edge in cm. + dx = -fgkMicron2Cm*Dx(); // lower left edge in cm. + dz = -0.5*fgkMicron2Cm*Dz(); // lower left edge in cm. if(x-dx) { - Warning("LocalToDet","input argument %f out of range (%f, %f)",x,dx,-dx); + AliWarning(Form("Input argument %f out of range (%f, %f)",x,dx,-dx)); return kFALSE; // outside of defined volume. } if(z-dz) { - Warning("LocalToDet","input argument %f out of range (%f, %f)",z,dz,-dz); + AliWarning(Form("Input argument %f out of range (%f, %f)",z,dz,-dz)); return kFALSE; // outside of defined volume. } - tb = fDriftSpeed*fTimeStep*kconv; // compute size of time bin. - if(x>0) dx = -(dx + x)/tb; // distance from + side in time bin units - else dx = (x - dx)/tb; // distance from - side in time bin units - dz = (z - dz)/(kconv*fPitch); // distance in z in anode pitch units - ix = (Int_t) dx; // time bin - iz = (Int_t) dz; // anode - if(x>0) iz += Npz()/2; // if x>0 then + side anodes values. + GetPadIxz(x,z,ix,iz); if(!fSetDriftSpeed){ - tb=-999; - Warning("LocalToDet","Drift speed not set: timebin is dummy"); + ix=-999; + AliWarning("Drift speed not set: timebin is dummy"); return kFALSE; } return kTRUE; // Found ix and iz, return. @@ -339,48 +332,21 @@ void AliITSsegmentationSDD::DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) // center of the sensitive volulme. // If ix and or iz is outside of the segmentation range a value of -Dx() // or -0.5*Dz() is returned. -// This segmentation geometry can be discribed as the following: -// {assumes 2*Dx()=7.0cm Dz()=7.5264cm, Dpx()=25ns, -// res->DeriftSpeed()=7.3mic/ns, Dpz()=512. For other values a only the -// specific numbers will change not their layout.} -// -// 0 191 0 -// 0 |----------------------|---------------------| 256 -// | a time-bins | time-bins a | -// | n | n | -// | o |___________________o_|__> X -// | d | d | -// | e | e | -// | s | s | -// 255 |----------------------|---------------------| 511 -// | -// V -// Z - Int_t i,j; - Float_t tb; - const Float_t kconv = 1.0E-04; // converts microns to cm. - if(iz>=Npz()/2) x = kconv*Dx(); // default value for +x side. - else x = -kconv*Dx(); // default value for -x side. - z = -0.5*kconv*Dz(); // default value. - if(ix<0 || ix>=Npx()) { - Warning("DetToLocal","input argument %d out of range (0, %d)",ix,Npx()); - return; // outside of detector - } - if(iz<0 || iz>=Npz()) { - Warning("DetToLocal","input argument %d out of range (0, %d)",iz,Npz()); - return; // outside of detctor - } - tb = fDriftSpeed*fTimeStep*kconv; // compute size of time bin. - if(iz>=Npz()/2) tb *= -1.0; // for +x side decrement frmo Dx(). - for(i=0;i=Npz()/2) iz -=Npz()/2;// If +x side don't count anodes from -x side. - for(j=0;j=Npx()) { + AliWarning(Form("Input argument %d out of range (0, %d)",ix,Npx())); + return; // outside of detector + } + if(iz<0 || iz>=Npz()) { + AliWarning(Form("Input argument %d out of range (0, %d)",iz,Npz())); + return; // outside of detctor + } + GetPadCxz(ix,iz,x,z); + if(!fSetDriftSpeed){ + x=-9999.; + AliWarning("Drift speed not set: x coord. is dummy"); + } + return; // Found x and z, return. } diff --git a/ITS/AliITSsegmentationSDD.h b/ITS/AliITSsegmentationSDD.h index 7af90799a00..44089d6d55a 100644 --- a/ITS/AliITSsegmentationSDD.h +++ b/ITS/AliITSsegmentationSDD.h @@ -41,11 +41,8 @@ public AliITSsegmentation { // Transform from real local to cell coordinates virtual void GetPadIxz(Float_t x ,Float_t z ,Int_t &ix,Int_t &iz) const; // Transform from cell to real local coordinates - virtual void GetPadCxz(Int_t ix,Int_t iz,Float_t &x ,Float_t &z ) const; - // Transform from real global to local coordinates - virtual void GetLocal(Int_t module,Float_t *g ,Float_t *l) const; - // Transform from real local to global coordinates - virtual void GetGlobal(Int_t module,Float_t *l ,Float_t *g) const; + virtual void GetPadCxz(Int_t ix,Int_t iz,Float_t &x ,Float_t &z ) const; + // Get anode and time bucket as floats - numbering from 0 virtual void GetPadTxz(Float_t &x ,Float_t &z) const; // Transformation from Geant cm detector center local coordinates @@ -55,6 +52,17 @@ public AliITSsegmentation { // from (0,0) to Geant cm detector center local coordinates. virtual void DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const; // + virtual Float_t GetAnodeFromLocal(Float_t x,Float_t z) const; + virtual Float_t GetLocalZFromAnode(Int_t nAnode) const; + virtual Float_t GetLocalZFromAnode(Float_t zAnode) const; + virtual Float_t GetDriftTimeFromTb(Int_t tb) const { + Float_t xtb=(Float_t)tb+0.5; + return GetDriftTimeFromTb(xtb); + } + virtual Float_t GetDriftTimeFromTb(Float_t xtb) const { + return xtb*fTimeStep; + } + // // Initialisation virtual void Init(); // @@ -101,8 +109,9 @@ public AliITSsegmentation { static const Float_t fgkClockDefault; //Default value for the clock freq. static const Int_t fgkHalfNanodesDefault; //Default value for fNanodes/2 static const Int_t fgkNsamplesDefault; //Default value for fNsamples - - ClassDef(AliITSsegmentationSDD,4) // SDD segmentation + static const Float_t fgkCm2Micron; + static const Float_t fgkMicron2Cm; + ClassDef(AliITSsegmentationSDD,5) // SDD segmentation }; #endif diff --git a/ITS/AliITSsegmentationSPD.cxx b/ITS/AliITSsegmentationSPD.cxx index f1f1d2eb1ce..2a92057c636 100644 --- a/ITS/AliITSsegmentationSPD.cxx +++ b/ITS/AliITSsegmentationSPD.cxx @@ -68,7 +68,7 @@ Float_t AliITSsegmentationSPD::ColFromZ(Float_t z) const { Float_t s,col; if(z<0||z>fDz){ - Error("ColFromZ","z=%f outside of range 0.0<=z=fNpz){ - Error("ZFromCol","col=%d outside of range 0<=colDz(); - Int_t dummy = 0; - Float_t anodePitch = seg->Dpz(dummy); - Double_t timeStep = (Double_t)seg->Dpx(dummy); + Float_t anodePitch = seg->Dpz(0); + Double_t timeStep = (Double_t)seg->Dpx(0); if(anodePitch*(fNofMaps/2) > sddWidth) { Warning("AliITSsimulationSDD", @@ -441,19 +440,17 @@ void AliITSsimulationSDD::FinishDigits() { //______________________________________________________________________ void AliITSsimulationSDD::HitsToAnalogDigits( AliITSmodule *mod ) { // create maps to build the lists of tracks for each digit - AliITSsegmentationSDD* seg = (AliITSsegmentationSDD*)GetSegmentationModel(1); AliITSCalibrationSDD* res = (AliITSCalibrationSDD*)GetCalibrationModel(fModule); TObjArray *hits = mod->GetHits(); Int_t nhits = hits->GetEntriesFast(); // Int_t arg[6] = {0,0,0,0,0,0}; - Int_t dummy = 0; Int_t nofAnodes = fNofMaps/2; Double_t sddLength = seg->Dx(); Double_t sddWidth = seg->Dz(); - Double_t anodePitch = seg->Dpz(dummy); - Double_t timeStep = seg->Dpx(dummy); + Double_t anodePitch = seg->Dpz(0); + Double_t timeStep = seg->Dpx(0); Double_t driftSpeed ; // drift velocity (anode dependent) //Float_t maxadc = res->GetMaxAdc(); //Float_t topValue = res->GetDynamicRange(); @@ -472,9 +469,7 @@ void AliITSsimulationSDD::HitsToAnalogDigits( AliITSmodule *mod ) { const Float_t kconv = 1.0e+6; // GeV->KeV Int_t itrack = 0; - Int_t hitDetector; // detector number (lay,lad,hitDetector) Int_t iWing; // which detector wing/side. - Int_t detector; // 2*(detector-1)+iWing Int_t ii,kk,ka,kt; // loop indexs Int_t ia,it,index; // sub-pixel integration indexies Int_t iAnode; // anode number. @@ -494,7 +489,7 @@ void AliITSsimulationSDD::HitsToAnalogDigits( AliITSmodule *mod ) { Double_t nmul; // drift time window multiplication factor. Double_t avDrft; // x position of path length segment in cm. Double_t avAnode; // Anode for path length segment in Anode number (float) - Double_t xAnode; // Floating point anode number. + Double_t zAnode; // Floating point anode number. Double_t driftPath; // avDrft in microns. Double_t width; // width of signal at anodes. Double_t depEnergy; // Energy deposited in this GEANT step. @@ -512,192 +507,180 @@ void AliITSsimulationSDD::HitsToAnalogDigits( AliITSmodule *mod ) { // Double_t tof; // Time of flight in ns of this step. for(ii=0; iiLineSegmentL(ii,xL[0],dxL[0],xL[1],dxL[1],xL[2],dxL[2], + if(!mod->LineSegmentL(ii,xL[0],dxL[0],xL[1],dxL[1],xL[2],dxL[2], depEnergy,itrack)) continue; - xL[0] += 0.0001*gRandom->Gaus( 0, jitter ); // - xAnode=10000.*(xL[2]+0.5*dxL[2])/anodePitch + nofAnodes/2;; - driftSpeed = res->GetDriftSpeedAtAnode(xAnode); - if(timeStep*fMaxNofSamples < sddLength/driftSpeed) { - Warning("AliITSsimulationSDD", - "Time Interval > Allowed Time Interval\n"); - } - depEnergy *= kconv; - hitDetector = mod->GetDet(); - //tof = 1.E+09*(mod->GetHit(ii)->GetTOF()); // tof in ns. - //if(tof>sddLength/driftSpeed) continue; // hit happed too late. + Float_t xloc=xL[0]; + if(xloc>0) iWing=0; // left side, carlos channel 0 + else iWing=1; // right side + + Float_t zloc=xL[2]+0.5*dxL[2]; + zAnode=seg->GetAnodeFromLocal(xloc,zloc); // anode number in the range 0.-511. + driftSpeed = res->GetDriftSpeedAtAnode(zAnode); + if(timeStep*fMaxNofSamples < sddLength/driftSpeed) { + AliWarning("Time Interval > Allowed Time Interval\n"); + } + depEnergy *= kconv; - // scale path to simulate a perpendicular track - // continue if the particle did not lose energy - // passing through detector - if (!depEnergy) { - AliDebug(1, - Form("fTrack = %d hit=%d module=%d This particle has passed without losing energy!", - itrack,ii,mod->GetIndex())); - continue; - } // end if !depEnergy - - pathInSDD = TMath::Sqrt(dxL[0]*dxL[0]+dxL[1]*dxL[1]+dxL[2]*dxL[2]); - - if (fFlag && pathInSDD) { depEnergy *= (0.03/pathInSDD); } - drPath = 10000.*(dxL[0]+2.*xL[0])*0.5; - if(drPath < 0) drPath = -drPath; - drPath = sddLength-drPath; - if(drPath < 0) { - AliDebug(1, // this should be fixed at geometry level - Form("negative drift path drPath=%e sddLength=%e dxL[0]=%e xL[0]=%e", + // scale path to simulate a perpendicular track + // continue if the particle did not lose energy + // passing through detector + if (!depEnergy) { + AliDebug(1, + Form("fTrack = %d hit=%d module=%d This particle has passed without losing energy!", + itrack,ii,mod->GetIndex())); + continue; + } // end if !depEnergy + + xL[0] += 0.0001*gRandom->Gaus( 0, jitter ); // + pathInSDD = TMath::Sqrt(dxL[0]*dxL[0]+dxL[1]*dxL[1]+dxL[2]*dxL[2]); + + if (fFlag && pathInSDD) { depEnergy *= (0.03/pathInSDD); } + drPath = TMath::Abs(10000.*(dxL[0]+2.*xL[0])*0.5); + drPath = sddLength-drPath; + if(drPath < 0) { + AliDebug(1, // this should be fixed at geometry level + Form("negative drift path drPath=%e sddLength=%e dxL[0]=%e xL[0]=%e", drPath,sddLength,dxL[0],xL[0])); - continue; - } // end if drPath < 0 + continue; + } // end if drPath < 0 // Compute number of segments to brake step path into - drTime = drPath/driftSpeed; // Drift Time - sigA = TMath::Sqrt(2.*dfCoeff*drTime+s1*s1);// Sigma along the anodes - // calcuate the number of time the path length should be split into. - nOfSplits = (Int_t) (1. + 10000.*pathInSDD/sigA); - if(fFlag) nOfSplits = 1; - - // loop over path segments, init. some variables. - depEnergy /= nOfSplits; - nOfSplitsF = (Float_t) nOfSplits; - for(kk=0;kk fScaleSize*fMaxNofSamples) { - Warning("HitsToAnalogDigits","Wrong Time Sample: %e", - timeSample); - continue; - } // end if timeSample > fScaleSize*fMaxNoofSamples - - // Anode - xAnode = 10000.*(avAnode)/anodePitch + nofAnodes/2; // +1? - if(xAnode*anodePitch > sddWidth || xAnode*anodePitch < 0.) - Warning("HitsToAnalogDigits", - "Exceedubg sddWidth=%e Z = %e", - sddWidth,xAnode*anodePitch); - iAnode = (Int_t) (1.+xAnode); // xAnode? - if(iAnode < 1 || iAnode > nofAnodes) { - Warning("HitToAnalogDigits","Wrong iAnode: 1<%d>%d (xanode=%e)", - iAnode,nofAnodes, xAnode); - continue; - } // end if iAnode < 1 || iAnode > nofAnodes - - // store straight away the particle position in the array - // of particles and take idhit=ii only when part is entering (this - // requires FillModules() in the macro for analysis) : - - // Sigma along the anodes for track segment. - sigA = TMath::Sqrt(2.*dfCoeff*drTime+s1*s1); - sigT = sigA/driftSpeed; - // Peak amplitude in nanoAmpere - amplitude = fScaleSize*160.*depEnergy/ - (timeStep*eVpairs*2.*acos(-1.)*sigT*sigA); - amplitude *= timeStep/25.; // WARNING!!!!! Amplitude scaling to - // account for clock variations - // (reference value: 40 MHz) - chargeloss = 1.-cHloss*driftPath/1000; - amplitude *= chargeloss; - width = 2.*nsigma/(nlookups-1); - // Spread the charge - // Pixel index - ndiv = 2; - nmul = 3.; - if(drTime > 1200.) { - ndiv = 4; - nmul = 1.5; - } // end if drTime > 1200. - // Sub-pixel index - nsplit = 4; // hard-wired //nsplit=4;nsplit = (nsplit+1)/2*2; - // Sub-pixel size see computation of aExpo and tExpo. - aStep = anodePitch/(nsplit*fScaleSize*sigA); - aConst = xAnode*anodePitch/sigA; - tStep = timeStep/(nsplit*fScaleSize*sigT); - tConst = drTime/sigT; - // Define SDD window corresponding to the hit - anodeWindow = (Int_t)(fScaleSize*nsigma*sigA/anodePitch+1); - timeWindow = (Int_t) (fScaleSize*nsigma*sigT/timeStep+1.); - jamin = (iAnode - anodeWindow/ndiv - 1)*fScaleSize*nsplit +1; - jamax = (iAnode + anodeWindow/ndiv)*fScaleSize*nsplit; - if(jamin <= 0) jamin = 1; - if(jamax > fScaleSize*nofAnodes*nsplit) - jamax = fScaleSize*nofAnodes*nsplit; - // jtmin and jtmax are Hard-wired - jtmin = (Int_t)(timeSample-timeWindow*nmul-1)*nsplit+1; - jtmax = (Int_t)(timeSample+timeWindow*nmul)*nsplit; - if(jtmin <= 0) jtmin = 1; - if(jtmax > fScaleSize*fMaxNofSamples*nsplit) - jtmax = fScaleSize*fMaxNofSamples*nsplit; - // Spread the charge in the anode-time window - for(ka=jamin; ka <=jamax; ka++) { - ia = (ka-1)/(fScaleSize*nsplit) + 1; - if(ia <= 0) { - Warning("HitsToAnalogDigits","ia < 1: "); - continue; - } // end if - if(ia > nofAnodes) ia = nofAnodes; - aExpo = (aStep*(ka-0.5)-aConst); - if(TMath::Abs(aExpo) > nsigma) anodeAmplitude = 0.; - else { - dummy = (Int_t) ((aExpo+nsigma)/width); - anodeAmplitude = amplitude*res->GetGausLookUp(dummy); - } // end if TMath::Abs(aEspo) > nsigma - // index starts from 0 - index = ((detector+1)%2)*nofAnodes+ia-1; - if(anodeAmplitude) for(kt=jtmin; kt<=jtmax; kt++) { - it = (kt-1)/nsplit+1; // it starts from 1 - if(it<=0){ - Warning("HitsToAnalogDigits","it < 1:"); - continue; - } // end if - if(it>fScaleSize*fMaxNofSamples) - it = fScaleSize*fMaxNofSamples; - tExpo = (tStep*(kt-0.5)-tConst); - if(TMath::Abs(tExpo) > nsigma) timeAmplitude = 0.; - else { - dummy = (Int_t) ((tExpo+nsigma)/width); - timeAmplitude = anodeAmplitude* - res->GetGausLookUp(dummy); - } // end if TMath::Abs(tExpo) > nsigma - // build the list of Sdigits for this module - // arg[0] = index; - // arg[1] = it; - // arg[2] = itrack; // track number - // arg[3] = ii-1; // hit number. - timeAmplitude *= norm; - timeAmplitude *= 10; - // ListOfFiredCells(arg,timeAmplitude,alst,padr); - Double_t charge = timeAmplitude; - charge += fHitMap2->GetSignal(index,it-1); - fHitMap2->SetHit(index, it-1, charge); - fpList->AddSignal(index,it-1,itrack,ii-1, - mod->GetIndex(),timeAmplitude); - fAnodeFire[index] = kTRUE; - } // end if anodeAmplitude and loop over time in window - } // loop over anodes in window - } // end loop over "sub-hits" + drTime = drPath/driftSpeed; // Drift Time + sigA = TMath::Sqrt(2.*dfCoeff*drTime+s1*s1);// Sigma along the anodes + // calcuate the number of time the path length should be split into. + nOfSplits = (Int_t) (1. + 10000.*pathInSDD/sigA); + if(fFlag) nOfSplits = 1; + + // loop over path segments, init. some variables. + depEnergy /= nOfSplits; + nOfSplitsF = (Float_t) nOfSplits; + Float_t theAverage=0.,theSteps=0.; + for(kk=0;kkGetAnodeFromLocal(avDrft,avAnode); + driftSpeed = res->GetDriftSpeedAtAnode(zAnode); + driftPath = TMath::Abs(10000.*avDrft); + driftPath = sddLength-driftPath; + if(driftPath < 0) { + AliDebug(1, // this should be fixed at geometry level + Form("negative drift path driftPath=%e sddLength=%e avDrft=%e dxL[0]=%e xL[0]=%e", + driftPath,sddLength,avDrft,dxL[0],xL[0])); + continue; + } // end if driftPath < 0 + drTime = driftPath/driftSpeed; // drift time for segment. + timeSample = (Int_t) (fScaleSize*drTime/timeStep + 1); // time bin in range 1-256 !!! + if(timeSample > fScaleSize*fMaxNofSamples) { + AliWarning(Form("Wrong Time Sample: %e",timeSample)); + continue; + } // end if timeSample > fScaleSize*fMaxNoofSamples + + if(zAnode>nofAnodes) zAnode-=nofAnodes; // to have the anode number between 0. and 256. + if(zAnode*anodePitch > sddWidth || zAnode*anodePitch < 0.) + AliWarning(Form("Exceeding sddWidth=%e Z = %e",sddWidth,zAnode*anodePitch)); + iAnode = (Int_t) (1.+zAnode); // iAnode in range 1-256 !!!! + if(iAnode < 1 || iAnode > nofAnodes) { + AliWarning(Form("Wrong iAnode: 1<%d>%d (xanode=%e)",iAnode,nofAnodes, zAnode)); + continue; + } // end if iAnode < 1 || iAnode > nofAnodes + + // store straight away the particle position in the array + // of particles and take idhit=ii only when part is entering (this + // requires FillModules() in the macro for analysis) : + + // Sigma along the anodes for track segment. + sigA = TMath::Sqrt(2.*dfCoeff*drTime+s1*s1); + sigT = sigA/driftSpeed; + // Peak amplitude in nanoAmpere + amplitude = fScaleSize*160.*depEnergy/ + (timeStep*eVpairs*2.*acos(-1.)*sigT*sigA); + amplitude *= timeStep/25.; // WARNING!!!!! Amplitude scaling to + // account for clock variations + // (reference value: 40 MHz) + chargeloss = 1.-cHloss*driftPath/1000.; + amplitude *= chargeloss; + width = 2.*nsigma/(nlookups-1); + // Spread the charge + // Pixel index + ndiv = 2; + nmul = 3.; + if(drTime > 1200.) { + ndiv = 4; + nmul = 1.5; + } // end if drTime > 1200. + // Sub-pixel index + nsplit = 4; // hard-wired //nsplit=4;nsplit = (nsplit+1)/2*2; + // Sub-pixel size see computation of aExpo and tExpo. + aStep = anodePitch/(nsplit*fScaleSize*sigA); + aConst = zAnode*anodePitch/sigA; + tStep = timeStep/(nsplit*fScaleSize*sigT); + tConst = drTime/sigT; + // Define SDD window corresponding to the hit + anodeWindow = (Int_t)(fScaleSize*nsigma*sigA/anodePitch+1); + timeWindow = (Int_t) (fScaleSize*nsigma*sigT/timeStep+1.); + jamin = (iAnode - anodeWindow/ndiv - 2)*fScaleSize*nsplit +1; + jamax = (iAnode + anodeWindow/ndiv + 1)*fScaleSize*nsplit; + if(jamin <= 0) jamin = 1; + if(jamax > fScaleSize*nofAnodes*nsplit) + jamax = fScaleSize*nofAnodes*nsplit; + // jtmin and jtmax are Hard-wired + jtmin = (Int_t)(timeSample-timeWindow*nmul-1)*nsplit+1; + jtmax = (Int_t)(timeSample+timeWindow*nmul)*nsplit; + if(jtmin <= 0) jtmin = 1; + if(jtmax > fScaleSize*fMaxNofSamples*nsplit) + jtmax = fScaleSize*fMaxNofSamples*nsplit; + // Spread the charge in the anode-time window + for(ka=jamin; ka <=jamax; ka++) { + ia = (ka-1)/(fScaleSize*nsplit) + 1; + if(ia <= 0) { + Warning("HitsToAnalogDigits","ia < 1: "); + continue; + } // end if + if(ia > nofAnodes) ia = nofAnodes; + aExpo = (aStep*(ka-0.5)-aConst); + if(TMath::Abs(aExpo) > nsigma) anodeAmplitude = 0.; + else { + Int_t theBin = (Int_t) ((aExpo+nsigma)/width+0.5); + anodeAmplitude = amplitude*res->GetGausLookUp(theBin); + } // end if TMath::Abs(aEspo) > nsigma + // index starts from 0 + index = iWing*nofAnodes+ia-1; + if(anodeAmplitude){ + for(kt=jtmin; kt<=jtmax; kt++) { + it = (kt-1)/nsplit+1; // it starts from 1 + if(it<=0){ + Warning("HitsToAnalogDigits","it < 1:"); + continue; + } // end if + if(it>fScaleSize*fMaxNofSamples) + it = fScaleSize*fMaxNofSamples; + tExpo = (tStep*(kt-0.5)-tConst); + if(TMath::Abs(tExpo) > nsigma) timeAmplitude = 0.; + else { + Int_t theBin = (Int_t) ((tExpo+nsigma)/width+0.5); + timeAmplitude = anodeAmplitude*res->GetGausLookUp(theBin); + } // end if TMath::Abs(tExpo) > nsigma + // build the list of Sdigits for this module + // arg[0] = index; + // arg[1] = it; + // arg[2] = itrack; // track number + // arg[3] = ii-1; // hit number. + timeAmplitude *= norm; + timeAmplitude *= 10; + // ListOfFiredCells(arg,timeAmplitude,alst,padr); + Double_t charge = timeAmplitude; + charge += fHitMap2->GetSignal(index,it-1); + fHitMap2->SetHit(index, it-1, charge); + fpList->AddSignal(index,it-1,itrack,ii-1, + mod->GetIndex(),timeAmplitude); + fAnodeFire[index] = kTRUE; + } // end loop over time in window + } // end if anodeAmplitude + } // loop over anodes in window + } // end loop over "sub-hits" } // end loop over hits } @@ -1400,7 +1383,7 @@ void AliITSsimulationSDD::WriteSDigits(){ for( Int_t i=0; iGetSignal( i, j ); if( sig > 0.2 ) { Int_t jdx = j*fScaleSize; diff --git a/ITS/Calib/RespSDD/Run0_999999999_v0_s0.root b/ITS/Calib/RespSDD/Run0_999999999_v0_s0.root index e1b39341fa70af9de48387655b7db3ddef78cd90..b10e4cf1b5376b9609cc18bd9a404b5eb79ae5b8 100644 GIT binary patch delta 173 zcmew<^;2qs0YCE@tBw!i8ygrI85rvKy`Si)%E!RK$il$Fz`!uUWX9PU6N~n`11S&_ zD6|@gPXKWW5CZ{E00Scfnh_8g7|G}fGK#SUqSAEvoDY(e cJ`9rFyq{?fCo@P@98W2jzQ$t!ra5^F07D-%>i_@% delta 173 zcmew<^;2qs0YBgK4|6-kXErc0GBDKddq2@pm5+gek%fVUfq`LyNzt^g6N~n`11S&_ zD6|@gPXKWW5CZ{E00Scfnh_8g7|G}fGK#SUqS18uoDY(e cJ`9rFyq{?fCo@P@98W2jzQ$t!ra5^F0Goa_IsgCw -- 2.43.0