4 #include <EVENT/LCCollection.h>
5 #include <IMPL/LCRelationImpl.h>
6 #include <EVENT/SimTrackerHit.h>
7 #include <EVENT/MCParticle.h>
8 #include <IMPL/LCFlagImpl.h>
10 #include "gsl/gsl_sf_erf.h"
11 #include "CLHEP/Random/RandGauss.h"
12 #include "CLHEP/Random/RandPoisson.h"
13 #include "CLHEP/Random/RandFlat.h"
17 #include <marlin/Global.h>
18 #include <gear/GEAR.h>
19 #include <gear/VXDParameters.h>
20 #include <gear/VXDLayerLayout.h>
24 using namespace CLHEP ;
26 using namespace lcio ;
27 using namespace marlin ;
39 _description =
"CCDDigitizer should create VTX TrackerHits from SimTrackerHits" ;
47 registerInputCollection( LCIO::SIMTRACKERHIT,
49 "Name of the SimTrackerHit collection" ,
51 std::string(
"vxd01_VXD") ) ;
54 registerOutputCollection( LCIO::TRACKERHIT,
55 "OutputCollectionName" ,
56 "Name of the output TrackerHit collection" ,
58 std::string(
"VTXTrackerHits") ) ;
60 registerOutputCollection( LCIO::LCRELATION,
62 "Name of the output VTX trackerhit relation collection" ,
64 std::string(
"VTXRelation") ) ;
69 registerProcessorParameter(
"CutOnDeltaRays",
70 "Cut on delta-ray energy (MeV)",
76 registerProcessorParameter(
"PixelSizeX",
83 registerProcessorParameter(
"PixelSizeY",
90 registerProcessorParameter(
"Debug",
98 registerProcessorParameter(
"ElectronsPerKeV",
105 std::vector<float> bkgdHitsInLayer;
106 bkgdHitsInLayer.push_back(34400.);
107 bkgdHitsInLayer.push_back(23900.);
108 bkgdHitsInLayer.push_back(9600.);
109 bkgdHitsInLayer.push_back(5500.);
110 bkgdHitsInLayer.push_back(3100.);
111 registerProcessorParameter(
"BackgroundHitsPerLayer",
112 "Background Hits per Layer",
120 registerProcessorParameter(
"SegmentLength",
127 registerProcessorParameter(
"PoissonSmearing",
128 "Apply Poisson smearing of electrons collected on pixels",
133 registerProcessorParameter(
"ElectronicEffects",
134 "Apply Electronic Effects",
139 registerProcessorParameter(
"ElectronicNoise",
140 "electronic noise in electrons",
144 registerProcessorParameter(
"Saturation",
145 "maximum number of electrons, which can be stroed in a pixel",
157 registerProcessorParameter(
"EnergyLoss",
158 "Energy Loss keV/mm",
164 registerProcessorParameter(
"GenerateBackground",
165 "Generate Background",
170 registerProcessorParameter(
"depletedDepth",
171 "Thickness of depleted zone",
176 registerProcessorParameter(
"undepletedDepth",
177 "Thickness of undepleted zone",
183 registerProcessorParameter(
"BField",
189 registerProcessorParameter(
"BiasVolt",
196 registerProcessorParameter(
"ElectricField",
197 "Electric Field in V/cm",
202 registerProcessorParameter(
"mu",
203 "electrons mobility in depleted zoneat low elcectric fields, in cm^2*V^-1*S^-1",
208 registerProcessorParameter(
"Temperatur",
209 "Temperatur in Kelvin",
215 registerProcessorParameter(
"diffusioncoefficient",
216 "diffcoeff in depleted zone in cm^2*S^-1",
224 registerProcessorParameter(
"reconstructmethod",
225 "reconstruction method",
230 registerProcessorParameter(
"Threshold",
231 "Cell Threshold in electrons",
238 registerProcessorParameter(
"framesize",
239 "size of cluster in reconstruction",
254 PI = (double)acos((
double)(-1.0));
277 #ifdef CCD_diagnostics
278 AIDA::IHistogramFactory* pHistogramFactory=marlin::AIDAProcessor::histogramFactory(
this );
280 histdist= pHistogramFactory->createHistogram1D(
"dist",
"distance (mm) between rawhits and reconstructed hits",100, 0, 0.05 );
281 histcluster= pHistogramFactory->createHistogram1D(
"clustersize",
"number of fired pixels in cluster",20, 0, 20 );
282 histclustxy= pHistogramFactory->createHistogram2D(
"clustxy",
"width and heigth of cluster",30,0,15 , 30,0,15 );
283 histcharge= pHistogramFactory->createHistogram1D(
"clustcharge",
"number of electrons per hit",120,0,12000);
284 histdistxy= pHistogramFactory->createHistogram2D(
"distxy",
"distance(mm) between rawhits and reconstructed hit (x,y- direction in local coordinates of ladder)",100,-0.05,0.05 , 100,-0.05,0.05 );
285 histNionpoint= pHistogramFactory->createHistogram1D(
"numberofionpoints",
"number of ionisationpoints per hit",30,0,30);
288 histenergy= pHistogramFactory->createHistogram1D(
"energyloss",
"energy loss per hit",100,0,10);
290 histsignal= pHistogramFactory->createHistogram1D(
"signal",
"electronnumber per pixel",100,0,500);
291 histsignalframe= pHistogramFactory->createHistogram1D(
"signalframe",
"electronnumber per pixel",100,0,1000);
293 histenergycentre= pHistogramFactory->createHistogram1D(
"signalcentre",
"electronnumber per pixel",100,0,5000);
305 const gear::VXDParameters& gearVXD = Global::GEAR->getVXDParameters() ;
306 const gear::VXDLayerLayout& layerVXD = gearVXD.getVXDLayerLayout();
335 const gear::GearParameters& gearVXDInfra = Global::GEAR->getGearParameters(
"VXDInfra") ;
336 const std::vector<double> laddergaps = gearVXDInfra.getDoubleVals(
"LadderGaps");
337 std::cout<<
"laddergaps size "<<laddergaps.size()<<std::endl;
364 cout<<
" _numberOfLayers "<<_numberOfLayers<<endl;
372 cout<<
"layer "<<i<<endl;
400 LCCollection * STHcol = evt->getCollection(
_colName ) ;
417 int nSTH = STHcol->getNumberOfElements();
420 for (
int i=0; i<nSTH; ++i) {
423 SimTrackerHit * simTrkHit =
424 dynamic_cast<SimTrackerHit*
>(STHcol->getElementAt(i));
481 if (recoHit != NULL) {
487 std::cout <<
"Number of pixels above threshold = 0 " << std::endl;
493 if ( recoHit != NULL) {
496 recoHit->rawHits().push_back(simTrkHit);
499 float pointResoRPhi=0.004;
500 float pointResoZ=0.004;
501 float covMat[TRKHITNCOVMATRIX]={0.,0.,pointResoRPhi*pointResoRPhi,0.,0.,pointResoZ*pointResoZ};
502 recoHit->setCovMatrix(covMat);
505 recoHit->setType(100+simTrkHit->getCellID0());
506 THcol->addElement( recoHit );
508 LCRelationImpl * rel =
new LCRelationImpl(recoHit,simTrkHit,
float(1.0));
509 RelCol->addElement(rel);
512 for (
int i=0; i < int(simTrkHitVec.size()); ++i) {
513 SimTrackerHit * hit = simTrkHitVec[i];
524 evt->addCollection(STHLocCol,
"VTXLocalSimTrackerHits");
525 evt->addCollection(THLocCol,
"VTXLocalTrackerHits");
526 evt->addCollection(RelLocCol,
"VTXLocalRelation");
529 catch(DataNotAvailableException &
e){}
534 if (
_nEvt % 100 == 0)
535 std::cout <<
"Processed " <<
_nEvt <<
"events " << std::endl;
550 std::cout <<
"CCDDigitizer::end() " << name()
551 <<
" processed " <<
_nEvt <<
" events in " <<
_nRun <<
" runs "
556 double * localPosition,
557 double * localDirection) {
579 double xLab[3] = { hit->getPosition()[0],
580 hit->getPosition()[1],
581 hit->getPosition()[2]};
592 double RXY = sqrt(xLab[0]*xLab[0]+
597 layer = hit->getCellID0() - 1;
609 if (xLab[2] < 0.0 ) {
619 if (hit->getMCParticle()) {
620 for (
int j=0; j<3; ++j)
621 Momentum[j] = hit->getMCParticle()->getMomentum()[j];
624 for (
int j=0; j<3; ++j) {
625 Momentum[j] = hit->getMomentum()[j];
631 if (hit->getMCParticle())
636 for (
int i=0; i<3; ++i)
641 for (
int i=0; i<3; ++i){
649 double PXY = sqrt(Momentum[0]*Momentum[0]+
650 Momentum[1]*Momentum[1]);
652 double PhiInLab = (double)atan2(xLab[1],xLab[0]);
653 if (PhiInLab < 0.0) PhiInLab +=
TWOPI;
654 double PhiInLabMom = atan2(Momentum[1],Momentum[0]);
655 if (PhiInLabMom < 0.0) PhiInLabMom +=
TWOPI;
673 for (
int ic=0; ic<nLadders; ++ic) {
674 PhiLadder = double(ic)*dPhi + Phi0;
675 PhiInLocal = PhiInLab - PhiLadder;
684 double PhiLocalMom = PhiInLabMom - PhiLadder;
685 localPosition[0] = RXY*sin(PhiInLocal);
686 localPosition[1] = xLab[2];
687 localPosition[2] = RXY*cos(PhiInLocal)-Radius;
690 localDirection[0]=PXY*sin(PhiLocalMom);
691 localDirection[1]=Momentum[2];
692 localDirection[2]=PXY*cos(PhiLocalMom);
700 #ifdef CCD_diagnostics
701 for(
int i=0;i<3;i++){
702 dirraw[i]=localDirection[i];
703 posraw[i]=localPosition[i];
723 double baseLine = Radius + xLoc[2];
724 double PhiInLab = Phi + atan2(xLoc[0],baseLine);
725 double RXY = sqrt(baseLine*baseLine+xLoc[0]*xLoc[0]);
727 xLab[0] = RXY*cos(PhiInLab);
728 xLab[1] = RXY*sin(PhiInLab);
753 double tanx = dir[0]/dir[2];
754 double tany = dir[1]/dir[2];
755 double trackLength = min(10.,
epitaxdep*sqrt(1.0+tanx*tanx+tany*tany));
776 #ifdef CCD_diagnostics
789 #ifdef CCD_diagnostics
798 double x = pos[0]+dir[0]*(z-pos[2])/dir[2];
799 double y = pos[1]+dir[1]*(z-pos[2])/dir[2];
804 double(1000.*dEmean))/1000.;
806 #ifdef CCD_diagnostics
818 #ifdef CCD_diagnostics
832 double TanLorentzY = 0;
840 double energy=ipoint.
eloss;
846 double distancetoplane;
863 if(distancetoplane<=epitaxdep && distancetoplane>
depdep){
878 double spxl[maxpixx][maxpixy];
886 for(
int i=0;i<maxpixx;i++){
887 for(
int k=0;
k<maxpixy;
k++){
889 spxl[i][
k]= (1-weight) *
pxl[i][
k];
895 for(
int i=0;i<maxpixx;i++){
896 for(
int k=0;
k<maxpixy;
k++){
897 pxl[i][
k]= spxl[i][
k]+ weight *
pxl[i][
k];
904 if(distancetoplane<=depdep){
906 x+= TanLorentzX*distancetoplane;
907 y+= TanLorentzY*distancetoplane;
909 double trt=(distancetoplane*0.1)/(
_mu*
_efield);
912 double sigma=sqrt(2*
_difcoef*trt)*10;
925 double Numladderpixx=(int)(ladderwidth/
_pixelSizeX);
927 double Numladderpixy=(int)(ladderlength/
_pixelSizeY);
930 for (
int i = 0; i<maxpixx; i++) {
934 if (ix >= 0 && ix<=Numladderpixx) {
936 for (
int k = 0;
k<maxpixy;
k++) {
938 if (iy >=0 && iy<=Numladderpixy) {
948 int currentcellid = 100000*ix + iy;
949 SimTrackerHitImpl * existingHit = 0;
951 for (
int iHits=0; iHits<int(vectorOfHits.size()); ++iHits) {
952 existingHit = vectorOfHits[iHits];
953 int cellid = existingHit->getCellID0();
954 if (cellid == currentcellid) {
960 float edep = existingHit->getEDep();
962 existingHit->setEDep( edep );
965 SimTrackerHitImpl * hit =
new SimTrackerHitImpl();
970 hit->setCellID0( currentcellid );
971 hit->setEDep( charge );
972 vectorOfHits.push_back( hit );
984 int & iy,
double & xdif,
double & ydif) {
995 double yInLadder = 0.0;
997 yInLadder = y + ladderLength;
1000 yInLadder = y - ladderGap;
1007 double xInLadder = 0.0;
1017 double & x,
double & y) {
1032 y = -ladderLength + y;
1050 for (
int ihit=0; ihit<int(simTrkVec.size()); ++ihit) {
1051 SimTrackerHitImpl * hit = simTrkVec[ihit];
1052 double charge = hit->getEDep();
1054 if (charge > 1000.) {
1055 double sigma = sqrt(charge);
1056 rng = double(RandGauss::shoot(charge,sigma));
1060 rng = double(RandPoisson::shoot(charge));
1062 hit->setEDep(
float(rng));
1071 int nPixels = int( simTrkVec.size() );
1074 for (
int i=0;i<nPixels;++i) {
1076 SimTrackerHitImpl * hit = simTrkVec[i];
1077 double charge = hit->getEDep() + Noise ;
1079 hit->setEDep( charge );
1092 double pos[3] = {0,0,0};
1098 for (
int iHit=0; iHit<int(simTrkVec.size()); ++iHit) {
1099 SimTrackerHit * hit = simTrkVec[iHit];
1106 charge+= hit->getEDep();
1109 int cellID = hit->getCellID0();
1110 int ix = cellID / 100000 ;
1111 int iy = cellID - 100000 * ix;
1112 double xCurrent,yCurrent;
1114 pos[0]+=xCurrent* hit->getEDep();
1115 pos[1]+=yCurrent* hit->getEDep();
1131 for (
int iHit=0; iHit<int(simTrkVec.size()); ++iHit) {
1132 SimTrackerHit * hit = simTrkVec[iHit];
1134 if (hit->getEDep() > emax) {
1135 emax=hit->getEDep();
1136 int cellID = hit->getCellID0();
1137 xcentre = cellID / 100000 ;
1138 ycentre = cellID - 100000 * xcentre;
1141 #ifdef CCD_diagnostics
1145 for (
int iHit=0; iHit<int(simTrkVec.size()); ++iHit) {
1146 SimTrackerHit * hit = simTrkVec[iHit];
1148 int cellID = hit->getCellID0();
1149 int ix = cellID / 100000 ;
1150 int iy = cellID - 100000 * ix;
1155 charge+= hit->getEDep();
1156 double xCurrent,yCurrent;
1158 pos[0]+=xCurrent* hit->getEDep();
1159 pos[1]+=yCurrent* hit->getEDep();
1161 #ifdef CCD_diagnostics
1162 double a=hit->getEDep();
1173 TrackerHitImpl * recoHit =
new TrackerHitImpl();
1174 recoHit->setEDep( charge );
1175 for (
int j=0; j<2; ++j)
1185 pos[0] = pos[0] - meanlorentzdepth * tanXLorentz;
1195 pos[2] += bulkthickness/2;
1198 #ifdef CCD_diagnostics
1201 shift[2]=-bulkthickness/2;
1203 for (
int i=0; i<2; ++i) {
1208 for (
int i=0;i<3;i++){
1217 int ixmin = 1000000;
1218 int ixmax = -1000000;
1219 int iymin = 1000000;
1220 int iymax = -1000000;
1224 for (
int iHit=0; iHit<int(simTrkVec.size()); ++iHit) {
1225 SimTrackerHit * hit = simTrkVec[iHit];
1229 int cellID = hit->getCellID0();
1230 int ix = cellID / 100000 ;
1231 int iy = cellID - 100000 * ix ;
1245 int xwidth=ixmax-ixmin+1;
1246 int ywidth=iymax-iymin+1;
1267 double dist=sqrt(pow(
posraw[0]-pos[0],2)
1269 +pow(
posraw[2]-pos[2],2));
1273 double distx=
posraw[0]-pos[0];
1274 double disty=
posraw[1]-pos[1];
1300 recoHit->setPosition( pos );
1313 for (
int i=0; i<3; ++i)
1314 pos[i] = recoHit->getPosition()[i];
1319 recoHit->setPosition( xLab );
1326 std::cout << std::endl;
1328 std::cout <<
"Simulated hit position = "
1329 <<
" " << simHit->getPosition()[0]
1330 <<
" " << simHit->getPosition()[1]
1331 <<
" " << simHit->getPosition()[2] << std::endl;
1333 std::cout <<
"Reconstructed hit position = "
1334 <<
" " << recoHit->getPosition()[0]
1335 <<
" " << recoHit->getPosition()[1]
1336 <<
" " << recoHit->getPosition()[2]
1337 <<
" total number of electrons " << recoHit->getEDep() <<std::endl;
1340 std::cout << std::endl;
1341 std::cout <<
"Type Q to exit display mode" << std::endl;
1343 if (q==
'q' || q==
'Q')
1352 int nHits = int(RandPoisson::shoot(mean));
1353 for (
int ihit=0;ihit<nHits;++ihit) {
1358 if (RandFlat::shoot(
double(1.)) > 0.5) {
1366 int nPhi = int(RandFlat::shoot(xLadders));
1370 TrackerHitImpl * trkHit =
new TrackerHitImpl();
1371 trkHit->setPosition( xLab );
1372 trkHit->setEDep(1000.);
1373 trkHit->setType(ilayer+1);
1374 col->addElement( trkHit );
1386 double xobs0,yobs0,xobs,yobs,sum,damp,dist,distsquare;
1391 double twosigmasquare=2*sigma*sigma;
1393 for(
int xpix=0;xpix<maxpixx;xpix++){
1396 for(
int ypix=0;ypix<maxpixy;ypix++){
1400 for(
int i=0;i<Numstepx;i++){
1403 for(
int k=0;
k<Numstepx;
k++){
1406 distsquare=(xobs-xhit)*(xobs-xhit)+(yobs-yhit)*(yobs-yhit);
1407 dist=sqrt(distsquare);
1408 damp=exp(-distsquare/twosigmasquare)/dist;
1414 pxl[xpix][ypix]=sum;
1421 for (
int i=0;i<maxpixx;i++){
1422 for(
int k=0;
k<maxpixy;
k++){
1456 double r = 1.13 + 0.0008 * (T - 273.);
1457 double beta = 1.04 * pow(T/273.0 ,exp3);
1459 double Ec = Ec0 * pow(T/273.0 ,exp2);
1460 double mud = mu / pow((1.+pow(E/Ec,beta)),1./beta);
1485 double beta = 1.109 * pow(T/300.0 ,exp3);
1488 double vsat =1.07e+7 * pow((T/300),exp2);
1489 double mud = mu / pow((1.+pow(E*mu/vsat,beta)),1./beta);
std::vector< float > _layerActiveSiOffset
AIDA::IHistogram1D * histsignal
std::vector< float > _layerHalfPhi
std::vector< float > _layerLadderHalfWidth
std::vector< float > _bkgdHitsInLayer
void PoissonSmearer(SimTrackerHitImplVec &simTrkVec)
void diffusion(double xdif, double ydif, double sigma)
AIDA::IHistogram1D * histcharge
void TransformXYToCellID(double x, double y, int &ix, int &iy, double &xdif, double &ydif)
AIDA::IHistogram1D * histsignalframe
virtual void end()
Termination member function.
std::vector< float > _layerLadderGap
void settanlorentzangleb(double B, double E, double mu, double T)
double _currentTotalCharge
IonisationPointVec _ionisationPoints
void ProduceHits(SimTrackerHitImplVec &simTrkVec)
virtual void processEvent(LCEvent *evt)
Processing of one event.
AIDA::IHistogram1D * histenergy
double _currentParticleMomentum
AIDA::IHistogram1D * histenergycentre
virtual void processRunHeader(LCRunHeader *run)
Processing of run header.
AIDA::IHistogram1D * histcluster
AIDA::IHistogram2D * histclustxy
void TransformToLab(double *xLoc, double *xLab)
std::vector< float > _layerHalfThickness
virtual void init()
Initialisation member function.
void FindLocalPosition(SimTrackerHit *hit, double *localPosition, double *localDirection)
void PrintInfo(SimTrackerHit *simTrkHit, TrackerHitImpl *recoHit)
CCDDigitizer aCCDDigitizer
void GainSmearer(SimTrackerHitImplVec &simTrkVec)
void generateBackground(LCCollectionVec *col)
std::vector< int > _laddersInLayer
std::vector< SimTrackerHitImpl * > SimTrackerHitImplVec
AIDA::IHistogram1D * histNionpoint
std::vector< float > _layerLadderLength
std::vector< EVENT::SimTrackerHit * > SimTrackerHitVec
void TransformCellIDToXY(int ix, int iy, double &x, double &y)
std::vector< float > _layerPhiOffset
std::string _colName
Input collection name.
void ProduceIonisationPoints(SimTrackerHit *hit)
double _cutOnDeltaRays
tangent of Lorentz angle
std::vector< float > _layerLadderWidth
std::vector< LCCollection * > LCCollectionVec
virtual void check(LCEvent *evt)
Produces check plots.
double SampleFluctuations(const double momentum, const double mass, double &tmax, const double length, const double meanLoss)
AIDA::IHistogram1D * histdist
void settanlorentzangle(double B, double E, double mu, double T)
std::string _outputCollectionName
std::vector< float > _layerRadius
std::string _colVTXRelation
std::vector< float > _layerThickness
double _currentParticleMass
AIDA::IHistogram2D * histdistxy
TrackerHitImpl * ReconstructTrackerHit(SimTrackerHitImplVec &simTrkVec)
MyG4UniversalFluctuationForSi * _fluctuate
void TrackerHitToLab(TrackerHitImpl *recoHit)
double pxl[maxpixx][maxpixy]