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();
//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;
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 );
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,
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];
for (k=0; k<npeaks-1; k++){//mark adjacent peaks
if (idx[k] < 0) continue; //this peak is already removed
for (l=k+1; l<npeaks; l++) {
- 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;
- }
+ 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;
+ }
}
}
}
for (k=0; k<npeaks; k++) {
- 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 (di<mini) mini=di;
- if (dj>maxj) maxj=dj;
- if (dj<minj) minj=dj;
- }
- //
- if(digits) {
- if (TMath::Abs(di)<2&&TMath::Abs(dj)<2){
- AliITSdigitSDD* d=(AliITSdigitSDD*)digits->UncheckedAt(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 (di<mini) mini=di;
+ if (dj>maxj) maxj=dj;
+ if (dj<minj) minj=dj;
+ }
+ //
+ if(digits) {
+ if (TMath::Abs(di)<2&&TMath::Abs(dj)<2){
+ AliITSdigitSDD* d=(AliITSdigitSDD*)digits->UncheckedAt(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);
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;iHyb<kHybridsPerDDL;iHyb++) ddlbins[iHyb]=new AliBin[kMaxBin];
//correction of coordinates using the maps stored in the DB
AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(fModule);
+ static const Int_t knbina = cal->Wings()*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;
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;
// Default constructor
}
+//_____________________________________________________________
+AliITSsegmentation::AliITSsegmentation(AliITSgeom* geom):
+fDx(0),
+fDz(0),
+fDy(0),
+fGeom(0),
+fCorr(0){
+ // Default constructor
+ fGeom=geom;
+}
+
//_____________________________________________________________
AliITSsegmentation::~AliITSsegmentation(){
#define ALIITSSEGMENTATION_H
#include <TObject.h>
+#include "AliLog.h"
+#include "AliITSgeom.h"
class TF1;
-class AliITSgeom;
//----------------------------------------------
//
// ITS segmentation virtual base class
public TObject {
public:
AliITSsegmentation();
+ AliITSsegmentation(AliITSgeom *geom);
AliITSsegmentation(const AliITSsegmentation& source);
virtual ~AliITSsegmentation();
AliITSsegmentation& operator=(const AliITSsegmentation &source);
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
#include <TMath.h>
#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.;
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),
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(),
SetDetSize(fgkDxDefault,fgkDzDefault,fgkDyDefault);
SetPadSize(fgkPitchDefault,fgkClockDefault);
SetNPads(fgkHalfNanodesDefault,fgkNsamplesDefault);
-
}
//______________________________________________________________________
// 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();
}
//----------------------------------------------------------------------
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(zAnode<fNanodes/2){ // left side
+ zloc=(zAnode*fPitch-fDz/2)*fgkMicron2Cm;
+ }else{ // right side
+ zAnode-=fNanodes/2;
+ zloc=-(zAnode*fPitch-fDz/2)*fgkMicron2Cm;
+ }
+ return zloc;
+}
+//----------------------------------------------------------------------
void AliITSsegmentationSDD::GetPadIxz(Float_t x,Float_t z,
Int_t &timebin,Int_t &anode) const {
-// Returns cell coordinates (time sample,anode) incremented by 1 !!!!!
+// Returns cell coordinates (time sample,anode)
// for given real local coordinates (x,z)
- // expects x, z in cm
-
- const Float_t kconv=10000; // cm->um
+ // 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{
// 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 {
// Int_t iz detector z anode coordinate. Has the range 0<=iz<fNandoes.
// A value of -1 for ix or iz indecates that this point is outside of the
// detector segmentation as defined.
-// 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
- 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 || 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 || 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.
// 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<ix;i++) x += tb; // sum up to cell ix-1
- x += 0.5*tb; // add 1/2 of cell ix for center location.
- if(iz>=Npz()/2) iz -=Npz()/2;// If +x side don't count anodes from -x side.
- for(j=0;j<iz;j++) z += kconv*fPitch; // sum up cell iz-1
- z += 0.5*kconv*fPitch; // add 1/2 of cell iz for center location.
- if(!fSetDriftSpeed){
- x=-9999.;
- Warning("LocalToDet","Drift speed not set: x coord. is dummy");
- }
- return; // Found x and z, return.
+ x=-Dx();
+ z=-0.5*Dz();
+ if(ix<0 || ix>=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.
}
// 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
// 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();
//
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
Float_t s,col;
if(z<0||z>fDz){
- Error("ColFromZ","z=%f outside of range 0.0<=z<fDz=%f",z,fDz);
+ AliError(Form("z=%f outside of range 0.0<=z<fDz=%f",z,fDz));
return 0.0; // error
} // end if outsize of detector
s = 0.0;
Float_t z;
if(col<0||col>=fNpz){
- Error("ZFromCol","col=%d outside of range 0<=col<fNpZ=%d",col,fNpz);
+ AliError(Form("col=%d outside of range 0<=col<fNpZ=%d",col,fNpz));
return 0.0; // error
} // end if outsize of detector
z = 0.0;
}
//______________________________________________________________________
AliITSsegmentationSPD::AliITSsegmentationSPD(AliITSgeom *gm):
+AliITSsegmentation(gm),
fNpx(0),
fNpz(0){
// Constructor
fCorr=0;
Init();
- fGeom = gm;
-
}
//______________________________________________________________________
void AliITSsegmentationSPD::Copy(TObject &obj) const {
virtual void GetPadIxz(Float_t x,Float_t z,Int_t &ix,Int_t &iz) const;
// Transform from pixel to real coordinates
virtual void GetPadCxz(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const;
- // Transform from real local to global coordinates
- //virtual void GetGlobal(Int_t module,Float_t *l ,Float_t *g) {}
// Local transformation of real local coordinates -
virtual void GetPadTxz(Float_t &x ,Float_t &z) const;
// Transformation from Geant cm detector center local coordinates
(Int_t iX,Int_t iZ,Int_t* Nlist,Int_t Xlist[10],Int_t Zlist[10]) const;
// Print default parameters (static const data members, if any)
virtual void PrintDefaultParameters() const
- {Warning("PrintDefaultParameters","No def. parameters defined as const static data members\n");}
+ {AliWarning("No def. parameters defined as const static data members");}
protected:
}
//----------------------------------------------------------------------
AliITSsegmentationSSD::AliITSsegmentationSSD(AliITSgeom *geom):
+AliITSsegmentation(geom),
fNstrips(0),
fStereoP(0),
fStereoN(0),
fStereoNl6(0),
fLayer(0){
// constuctor
- fGeom = geom;
fCorr = 0;
SetDetSize(fgkDxDefault,fgkDzDefault,fgkDyDefault);
SetPadSize(fgkPitchDefault,0.);
SetAngles();
fLayer = 0;
}
-
//______________________________________________________________________
void AliITSsegmentationSSD::Copy(TObject &obj) const {
// protected method. copy this to obj
//set fLayer data member (only 5 or 6 are allowed)
if (l==5) fLayer =5;
if (l==6) fLayer =6;
- if((l!=5) && (l!=6))Error("SetLayer","Layer can be 5 or 6, not %d",l);
+ if((l!=5) && (l!=6))AliError(Form("Layer can be 5 or 6, not %d",l));
}
//----------------------------------------------------------------------
void AliITSsegmentationSSD::GetPadTxz(Float_t &x,Float_t &z) const{
fAnodeFire = new Bool_t [fNofMaps];
Float_t sddWidth = seg->Dz();
- 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",
//______________________________________________________________________
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();
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.
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.
// Double_t tof; // Time of flight in ns of this step.
for(ii=0; ii<nhits; ii++) {
- if(!mod->LineSegmentL(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<nOfSplits;kk++) { // loop over path segments
- kkF = (Float_t) kk + 0.5;
- avDrft = xL[0]+dxL[0]*kkF/nOfSplitsF;
- avAnode = xL[2]+dxL[2]*kkF/nOfSplitsF;
- driftPath = 10000.*avDrft;
-
- iWing = 2; // Assume wing is 2
- if(driftPath < 0) { // if wing is not 2 it is 1.
- iWing = 1;
- driftPath = -driftPath;
- } // end if driftPath < 0
- driftPath = sddLength-driftPath;
- detector = 2*(hitDetector-1) + iWing;
- 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
-
- // Drift Time
- drTime = driftPath/driftSpeed; // drift time for segment.
- timeSample = (Int_t) (fScaleSize*drTime/timeStep + 1);
- // compute time Sample including tof information. The tof only
- // effects the time of the signal is recoreded and not the
- // the defusion.
- // timeSample = (Int_t) (fScaleSize*(drTime+tof)/timeStep + 1);
- if(timeSample > 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;kk<nOfSplits;kk++) { // loop over path segments
+ kkF = (Float_t) kk + 0.5;
+ avDrft = xL[0]+dxL[0]*kkF/nOfSplitsF;
+ avAnode = xL[2]+dxL[2]*kkF/nOfSplitsF;
+ theSteps+=1.;
+ theAverage+=avAnode;
+ zAnode = seg->GetAnodeFromLocal(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
}
for( Int_t i=0; i<fNofMaps; i++ ) {
if( !fAnodeFire[i] ) continue;
- for( Int_t j=0; j<fMaxNofSamples; j++ ) {
+ for( Int_t j=0; j<fMaxNofSamples; j++ ) {
Double_t sig = fHitMap2->GetSignal( i, j );
if( sig > 0.2 ) {
Int_t jdx = j*fScaleSize;