CMS 3D CMS Logo

HitDigitizerFP420.cc

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

Generated on Tue Jun 9 17:47:52 2009 for CMSSW by  doxygen 1.5.4