CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/SimRomanPot/SimFP420/src/HitDigitizerFP420.cc

Go to the documentation of this file.
00001 
00002 // File: HitDigitizerFP420.cc
00003 // Date: 08.2008
00004 // Description: HitDigitizerFP420 for FP420
00005 // Modifications: 
00007 #include "SimRomanPot/SimFP420/interface/HitDigitizerFP420.h"
00008 //#include "SimG4CMS/FP420/interface/FP420G4HitCollection.h"
00009 //#include "SimG4CMS/FP420/interface/FP420G4Hit.h"
00010 
00011 #include "SimDataFormats/TrackingHit/interface/PSimHit.h"
00012 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
00013 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
00014 #include "DataFormats/GeometryVector/interface/LocalVector.h"
00015 
00016 #include "SimRomanPot/SimFP420/interface/ChargeDrifterFP420.h"
00017 #include "SimRomanPot/SimFP420/interface/ChargeDividerFP420.h"
00018 #include "SimRomanPot/SimFP420/interface/InduceChargeFP420.h"
00019 
00020 using namespace std;
00021 #include<vector>
00022 
00023 #define CBOLTZ (1.38E-23)
00024 #define e_SI (1.6E-19)
00025 
00026 //HitDigitizerFP420::HitDigitizerFP420(float in,float inp,float inpx,float inpy){
00027 //HitDigitizerFP420::HitDigitizerFP420(float in,float inp,float inpx,float inpy,float ild,float ildx,float ildy){
00028 HitDigitizerFP420::HitDigitizerFP420(float in,float ild,float ildx,float ildy,float in0,float in2,float in3,int verbosity){
00029   moduleThickness =in; 
00030   double bz420 = in0; 
00031   double bzD2 =  in2; 
00032   double bzD3 =  in3;
00033   //  double pitch =inp; 
00034   //  double pitchX =inpx; 
00035   //  double pitchY =inpy; 
00036   double ldrift =ild; 
00037   double ldriftX =ildx; 
00038   double ldriftY =ildy; 
00039   //
00040   // Construct default classes
00041   //
00042   
00043   //theCDividerFP420 = new ChargeDividerFP420(pitch);
00044   theCDividerFP420 = new ChargeDividerFP420(moduleThickness, bz420, bzD2, bzD3, verbosity);
00045   
00046   depletionVoltage=20.0; //
00047   appliedVoltage=25.0;  //  a bit bigger than depletionVoltage to have positive value A for logA, A=1-2*Tfract.*Vd/(Vd+Vb)
00048   
00049   //  chargeMobility=480.0;//  = 480.0  !holes    mobility [cm**2/V/sec] p-side;   = 1350.0 !electron mobility - n-side
00050   chargeMobility=1350.0;//  = 480.0  !holes    mobility [cm**2/V/sec] p-side;   = 1350.0 !electron mobility - n-side
00051   //temperature=297.; // 24 C degree +273 = 297 ---->diffusion const for electrons= (1.38E-23/1.6E-19)*1350.0*297=34.6
00052   //  diffusion const for holes  =   12.3   [cm**2/sec]
00053   temperature=263.; // -10  C degree +273 = 263 ---->diffusion const for electrons= (1.38E-23/1.6E-19)*1350.0*263=30.6
00054   double diffusionConstant = CBOLTZ/e_SI * chargeMobility * temperature;
00055   // noDiffusion=true; // true if no Diffusion
00056   noDiffusion=false; // false if Diffusion
00057   if (noDiffusion) diffusionConstant *= 1.0e-3;
00058   
00059   chargeDistributionRMS=6.5e-10;
00060   
00061   // arbitrary:
00062   tanLorentzAnglePerTesla = 0. ;       //  try =0.106 if B field exist
00063   
00064   //    double timeNormalisation = pow(moduleThickness,2)/(2.*depletionVoltage*chargeMobility);
00065   //    double timeNormalisation = pow(pitch,2)/(2.*depletionVoltage*chargeMobility);
00066   
00067   double timeNormalisation = pow(ldrift,2)/(2.*depletionVoltage*chargeMobility);// 
00068   // double timeNormalisation = pow(ldrift,2)/(2.*depletionVoltage*chargeMobility);// 
00069   timeNormalisation = timeNormalisation*0.01; // because ldrift in [mm] but mu_e in [cm2/V/sec 
00070   
00071   //      double timeNormalisation = pow(pitch/2.,2)/(2.*depletionVoltage*chargeMobility);// i entered pitch as a distance between 2 read-out strips, not real distance between any (p or n) electrods which will be in 2 times less. But in expression for timeNormalisation the real distance of charge collection must be, so use pitch/2.   !
00072   
00073   
00074   double clusterWidth=5.;// was = 3
00075   gevperelectron= 3.61e-09; //     double GevPerElectron = 3.61e-09
00076   
00077   // GevPerElectron AZ:average deposited energy per e-h pair [keV]??? =0.0036
00078   if(verbosity>0) {
00079     std::cout << "HitDigitizerFP420: constructor ldrift= " << ldrift << std::endl;
00080     std::cout << "ldriftY= " <<ldriftY  << "ldriftX= " <<ldriftX  << std::endl;
00081     std::cout << "depletionVoltage" <<  depletionVoltage    << "appliedVoltage" <<  appliedVoltage    << "chargeMobility" <<  chargeMobility    << "temperature" <<  temperature    << "diffusionConstant" <<  diffusionConstant    << "chargeDistributionRMS" <<   chargeDistributionRMS   << "moduleThickness" <<   moduleThickness   << "timeNormalisation" <<  timeNormalisation    << "gevperelectron" <<  gevperelectron    << std::endl;
00082   }
00083   //ndif
00084   
00085   theCDrifterFP420 = 
00086     new ChargeDrifterFP420(moduleThickness,
00087                            timeNormalisation,
00088                            diffusionConstant,
00089                            temperature,
00090                            chargeDistributionRMS,
00091                            depletionVoltage,
00092                            appliedVoltage,
00093                            ldriftX,
00094                            ldriftY, verbosity);
00095   //                                    pitchX,
00096   //                                    pitchY);
00097   
00098   theIChargeFP420 = new InduceChargeFP420(clusterWidth,gevperelectron);
00099 }
00100 
00101 
00102 HitDigitizerFP420::~HitDigitizerFP420(){
00103   delete theCDividerFP420;
00104   delete theCDrifterFP420;
00105   delete theIChargeFP420;
00106 }
00107 
00108 
00109 //HitDigitizerFP420::hit_map_type HitDigitizerFP420::processHit(const PSimHit& hit, G4ThreeVector bfield, int xytype,int numStrips, double pitch){
00110 HitDigitizerFP420::hit_map_type HitDigitizerFP420::processHit(const PSimHit& hit, G4ThreeVector bfield, int xytype,int numStrips, double pitch, int numStripsW, double pitchW, double moduleThickness, int verbosity){
00111   
00112   // use chargePosition just for cross-check in "induce" method
00113   // hit center in 3D-detector r.f.
00114   
00115   float middlex = (hit.exitPoint().x() + hit.entryPoint().x() )/2.;
00116   float middley = (hit.exitPoint().y() + hit.entryPoint().y() )/2.;
00117   
00118   
00119   float chargePosition= -100.;
00120   // Y: 
00121   if(xytype == 1) {
00122     //     chargePosition  = fabs(-numStrips/2. - ( int(middle.x()/pitch) +1.) );
00123     //chargePosition  = fabs(int(middle.x()/pitch+0.5*(numStrips+1)) + 1.);
00124     //      chargePosition  = fabs(int(middle.y()/pitch+0.5*(numStrips+1)) + 1.);
00125     // local and global reference frames are rotated in 90 degree, so global X and local Y are collinear
00126     //     chargePosition  = int(fabs(middle.x()/pitch + 0.5*numStrips + 1.));// charge in strip coord 
00127     chargePosition = 0.5*(numStrips) + middlex/pitch ;// charge in strip coord 0 - numStrips-1
00128     
00129     
00130   }
00131   // X:
00132   else if(xytype == 2) {
00133     //     chargePosition  = fabs(-numStrips/2. - ( int(middle.y()/pitch) +1.) );
00134     //chargePosition  = fabs(int(middle.y()/pitch+0.5*(numStrips+1)) + 1.);
00135     //      chargePosition  = fabs(int(middle.x()/pitch+0.5*(numStrips+1)) + 1.);
00136     // local and global reference frames are rotated in 90 degree, so global X and local Y are collinear
00137     //     chargePosition  = int(fabs(middle.y()/pitch + 0.5*numStrips + 1.));
00138     chargePosition = 0.5*(numStrips) + middley/pitch ;// charge in strip coord 0 - numStrips-1
00139     
00140     //  std::cout << " chargePosition    SiHitDi... = " << chargePosition                       << std::endl;
00141   }
00142   else {
00143     std::cout <<"================================================================"<<std::endl;
00144     std::cout << "****   HitDigitizerFP420:  !!!  ERROR: you have not to be here !!!  xytype=" << xytype << std::endl;
00145     // std::cout << "****   HitDigitizerFP420:  !!!  ERROR: you have not to be here !!!  xytype=" << xytype << std::endl;
00146     
00147     
00148     //     break;
00149   }
00150   //   if(chargePosition > numStrips || chargePosition<1) {
00151   if(chargePosition > numStrips || chargePosition < 0) {
00152     std::cout << "****   HitDigitizerFP420:  !!!  ERROR: check correspondence of XY detector dimensions in XML and here !!! chargePosition = " << chargePosition << std::endl;
00153     //     break;
00154   }
00155   
00156   if(verbosity>0) {
00157     std::cout << " ======   ****   HitDigitizerFP420:  !!!  processHit  !!!  : input: xytype=" << xytype << " numStrips=  " << numStrips << " pitch=  " << pitch << " Calculated chargePosition=  " << chargePosition << std::endl;
00158     std::cout << "The middle of hit point on input was: middlex =  " << middlex << std::endl;
00159     std::cout << "The middle of hit point on input was: middley =  " << middley << std::endl;
00160     //  std::cout << "For checks: hit point Entry =  " << hit.getEntry() << std::endl;
00161     std::cout << " ======   ****   HitDigitizerFP420:processHit:   start  CDrifterFP420 divide" << std::endl;
00162   }
00163   //
00164   // Fully process one SimHit
00165   //
00166   
00167   //   CDrifterFP420::ionization_type ion = theCDividerFP420->divide(hit,pitch);
00168   CDrifterFP420::ionization_type ion = theCDividerFP420->divide(hit,moduleThickness);
00169   //
00170   // Compute the drift direction for this det
00171   //
00172   
00173   //  G4ThreeVector driftDir = DriftDirection(&det,bfield);
00174   G4ThreeVector driftDir = DriftDirection(bfield,xytype,verbosity);
00175   if(verbosity>0) {
00176     std::cout << " ======   ****   HitDigitizerFP420:processHit: driftDir= " << driftDir << std::endl;
00177     std::cout << " ======   ****   HitDigitizerFP420:processHit:  start   induce , CDrifterFP420   drift   " << std::endl;
00178   }
00179   
00180   //  if(driftDir.z() ==0.) {
00181   //    std::cout << " pxlx: drift in z is zero " << std::endl; 
00182   //  }  else  
00183   //
00184 
00185   return theIChargeFP420->induce(theCDrifterFP420->drift(ion,driftDir,xytype), numStrips, pitch, numStripsW, pitchW, xytype, verbosity);
00186   
00187   //
00188 }
00189 
00190 
00191 
00192 G4ThreeVector HitDigitizerFP420::DriftDirection(G4ThreeVector _bfield, int xytype, int verbosity){
00193   
00194   // LOCAL hit: exchange xytype:  1 <-> 2
00195   
00196   //  Frame detFrame(_detp->surface().position(),_detp->surface().rotation());
00197   //  G4ThreeVector Bfield=detFrame.toLocal(_bfield);
00198   G4ThreeVector Bfield=_bfield;
00199   float dir_x, dir_y, dir_z; 
00200   // this lines with dir_... have to be specified(sign?) in dependence of field direction: 
00201   /*
00202     float dir_x = tanLorentzAnglePerTesla * Bfield.y();
00203     float dir_y = -tanLorentzAnglePerTesla * Bfield.x();
00204     float dir_z = 1.; // if E field is in z direction
00205   */
00206   // for electrons:
00207   // E field is either in X or Y direction with change vector to opposite
00208   
00209   // global Y or localX
00210   // E field is in Xlocal direction with change vector to opposite
00211   if(xytype == 2) {
00212     dir_x = 1.; // E field in Xlocal direction
00213     dir_y = +tanLorentzAnglePerTesla * Bfield.z();
00214     dir_z = -tanLorentzAnglePerTesla * Bfield.y();
00215   }
00216   // global X
00217   // E field is in Ylocal direction with change vector to opposite
00218   else if(xytype == 1) {
00219     dir_x = +tanLorentzAnglePerTesla * Bfield.z();
00220     dir_y = 1.; // E field in Ylocal direction
00221     dir_z = -tanLorentzAnglePerTesla * Bfield.x();
00222   }
00223   else{
00224     dir_x = 0.;
00225     dir_y = 0.;
00226     dir_z = 0.;
00227     std::cout << "HitDigitizerFP420: ERROR - wrong xytype=" <<  xytype   << std::endl;
00228   }
00229   
00230   
00231   //  G4ThreeVector theDriftDirection = LocalVector(dir_x,dir_y,dir_z);
00232   G4ThreeVector theDriftDirection(dir_x,dir_y,dir_z);
00233   // Local3DPoint EntryPo(aHit->getEntry().x(),aHit->getEntry().y(),aHit->getEntry().z());
00234   if(verbosity>0) {
00235     std::cout << "HitDigitizerFP420:DriftDirection tanLorentzAnglePerTesla= " << tanLorentzAnglePerTesla    << std::endl;
00236     std::cout << "HitDigitizerFP420:DriftDirection The drift direction in local coordinate is " <<  theDriftDirection    << std::endl;
00237   }
00238   
00239   return theDriftDirection;
00240   
00241 }