CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/SimRomanPot/SimFP420/src/InduceChargeFP420.cc

Go to the documentation of this file.
00001 
00002 // File: InduceChargeFP420
00003 // Date: 08.2008
00004 // Description: InduceChargeFP420 for FP420
00005 // Modifications:  
00007 //#include "SimRomanPot/SimFP420/interface/SimRPUtil.h"
00008 #include "SimRomanPot/SimFP420/interface/InduceChargeFP420.h"
00009 #include <gsl/gsl_sf_erf.h>
00010 #include<iostream>
00011 using namespace std;
00012 
00013 static float capacitive_coupling[2] =  {.80,.10};
00014 static float FiducialXYZ[3] =  {3.6,4.,0.250};// dX/2, dY/2,dZ -- mm fiducial dimension of Si plate
00015 
00016 IChargeFP420::hit_map_type InduceChargeFP420::induce(CDrifterFP420::collection_type _collection_points, int numStrips, double localPitch, int numStripsW, double localPitchW, int xytype, int verbosity){
00017   signalCoupling.clear();
00018   signalCoupling.push_back(capacitive_coupling[0]);
00019   signalCoupling.push_back(capacitive_coupling[1]);
00020   
00021   // in mm local coordinates   (temporarily)
00022   // float FiducialX = 5., FiducialY = 10., FiducialZ = 0.250;
00023   int stripLeft, stripRight, stripLeftW, stripRightW;
00024   double upperBound, lowerBound, upperBoundW, lowerBoundW;
00025   
00026   
00027   hit_map_type hit_signal;
00028   
00029   // map to store pixel integrals in the x and in the y directions
00030   std::map<int, float, less<int> > x,y; 
00031   
00032   
00033   for (CDrifterFP420::collection_type::const_iterator sp=_collection_points.begin();  sp != _collection_points.end(); sp++ ){
00034     
00035     float chargePositionW=-1.; // charge in strip coord in Wide pixel
00036     float chargePosition=-1.; // charge in strip coord
00037     
00038     // define chargePosition
00039     G4ThreeVector Position3D = (*sp).position(); // charge in strip coord
00040     
00041     if(verbosity>0) {
00042       std::cout << " =============================*InduceChargeFP420:induce:Position3D= " << Position3D << std::endl;
00043       std::cout << " localPitch= " << localPitch << std::endl;
00044       std::cout << " xytype= " << xytype << " numStrips= " << numStrips << std::endl;
00045     }
00046     
00047     
00048     
00049     // is slice still inside fiducial volume of the plate? if not ->  put slice energy to zero.
00050     if( abs(Position3D.x())<FiducialXYZ[0] && 
00051         abs(Position3D.y())<FiducialXYZ[1] ) {
00052       if( abs(Position3D.z())<FiducialXYZ[2] ) {
00053       }
00054       else{
00055         //      (*sp).amplitude() == 0.;
00056         std::cout << " *InduceChargeFP420:Z slice outside the plate: Position3D= " << Position3D << std::endl;
00057       }
00058     }
00059     else{
00060       //      (*sp).amplitude() == 0.;
00061       std::cout << " *InduceChargeFP420:XY slice outside the plate: Position3D= " << Position3D << std::endl;
00062     }
00063     
00064     // chargePosition - still local coordinates, so exchange x and y due to 90 degree rotation
00065     // Yglobal::
00066     if(xytype == 1) {
00067       // = 
00068       chargePosition = 0.5*numStrips + Position3D.x()/localPitch ;// charge in strip coord. in l.r.f starting at edge of plate
00069       chargePositionW = 0.5*numStripsW + Position3D.y()/localPitchW ;// charge in strip coord. in l.r.f starting at edge of plate
00070     }
00071     //X:
00072     else if(xytype == 2) {
00073       // = 
00074       chargePosition = 0.5*numStrips + Position3D.y()/localPitch ;// charge in strip coord. in l.r.f starting at edge of plate
00075       chargePositionW = 0.5*numStripsW + Position3D.x()/localPitchW ;// charge in strip coord. in l.r.f starting at edge of plate
00076     }
00077     else {
00078       std::cout << "**** InduceChargeFP420:  !!!  ERROR: you have not to be here !!!  xytype=" << xytype << std::endl;
00079       //     break;
00080     }
00081     
00082     if(verbosity>0) {
00083       if(xytype==2){
00084         std::cout << "===================================**** InduceChargeFP420: xytype= " << xytype << std::endl;
00085         std::cout << "  chargePositionW= " << chargePositionW << "  chargePosition= " << chargePosition << std::endl;
00086         std::cout << "Position3D= " << Position3D << std::endl;
00087       }
00088     }
00089     
00090     float chargeSpread = (*sp).sigma()/localPitch ;  // sigma in strip pitches
00091     float chargeSpreadW = (*sp).sigma()/localPitchW ;  // sigma in strip pitches
00092     
00093     // Define strips intervals along x: check edge condition
00094     
00095     stripLeft  = int( chargePosition-clusterWidth*chargeSpread);
00096     stripRight = int( chargePosition+clusterWidth*chargeSpread);
00097     stripLeft  = (0<stripLeft ? stripLeft : 0);
00098     stripRight = (numStrips >stripRight ? stripRight : numStrips-1);
00099     
00100     stripLeftW  = int( chargePositionW-clusterWidth*chargeSpreadW);
00101     stripRightW = int( chargePositionW+clusterWidth*chargeSpreadW);
00102     stripLeftW  = (0<stripLeftW ? stripLeftW : 0);
00103     stripRightW = (numStripsW >stripRightW ? stripRightW : numStripsW-1);
00104     
00105     if(verbosity>1) {
00106       std::cout << " Position3D =  " << Position3D << "amplitude=" << (*sp).amplitude() << std::endl;
00107       std::cout << " MaxChargeSpread= " << clusterWidth*chargeSpread << " sigma= " << (*sp).sigma() << std::endl;
00108       std::cout << "*** numStrips= " << numStrips << " localPitch= " << localPitch << "xytype=" << xytype << std::endl;
00109       std::cout << " chargePosition= " << chargePosition << " chargeSpread= " << chargeSpread << std::endl;
00110       std::cout << " stripLeft= " << stripLeft << " stripRight= " << stripRight << std::endl;
00111       std::cout << " chargePositionW= " << chargePositionW << " chargeSpreadW= " << chargeSpreadW << std::endl;
00112       std::cout << " stripLeftW= " << stripLeftW << " stripRightW= " << stripRightW << std::endl;
00113     }
00115     for (int i=stripLeft; i<=stripRight; i++){
00116       /* Definition of the integration borns */
00117       // go to "left"
00118       if (i == 0) lowerBound = 0. ;
00119       else {
00120         gsl_sf_result result;
00121         int status = gsl_sf_erf_Q_e((i-chargePosition)/chargeSpread, &result);
00122         if (status != 0) std::cerr<<"InduceChargeFP420::could not compute gaussian tail probability for the threshold chosen"<<std::endl;
00123         lowerBound = 1. - result.val;
00124         if(verbosity>0) {
00125           std::cout << "go to left: i=  " << i << "lowerBound=" << lowerBound << std::endl;
00126         }
00127       }
00128       
00129       // go to "right"
00130       if (i == numStrips-1) upperBound = 1.;
00131       else {
00132         gsl_sf_result result;
00133         int status = gsl_sf_erf_Q_e((i-chargePosition+1)/chargeSpread, &result);
00134         if (status != 0) std::cerr<<"InduceChargeFP420::could not compute gaussian tail probability for the threshold chosen"<<std::endl;
00135         upperBound = 1. - result.val;
00136         
00137         if(verbosity>0) {
00138           std::cout << "go to right: i=  " << i << "upperBound=" << upperBound << std::endl;
00139         }
00140       }
00141       
00142       double totalIntegrationRange = upperBound - lowerBound;
00143       x[i] = totalIntegrationRange; // save strip integral 
00144       
00145       if(totalIntegrationRange<=0.) std::cout << " upperBound= " << upperBound << " lowerBound= " << lowerBound << std::endl;
00146       if(verbosity==-30) {
00147         std::cout << " *InduceChargeFP420:====================================X i =  " << i << std::endl;
00148         std::cout << " upperBound= " << upperBound << " lowerBound= " << lowerBound << std::endl;
00149         std::cout << " totalIntegrationRange= " << totalIntegrationRange << std::endl;
00150         std::cout << " *InduceChargeFP420:==================================== " << std::endl;
00151       }
00152       
00153     }// for
00155     for (int i=stripLeftW; i<=stripRightW; i++){
00156       /* Definition of the integration borns */
00157       // go to "left"
00158       if (i == 0) lowerBoundW = 0. ;
00159       else {
00160         gsl_sf_result result;
00161         int status = gsl_sf_erf_Q_e((i-chargePositionW)/chargeSpreadW, &result);
00162         if (status != 0) std::cerr<<"InduceChargeFP420::W could not compute gaussian tail probability for the threshold chosen"<<std::endl;
00163         lowerBoundW = 1. - result.val;
00164         
00165         
00166         if(verbosity>0) {
00167           std::cout << "go to left: i=  " << i << "lowerBoundW=" << lowerBoundW << std::endl;
00168         }
00169       }
00170       
00171       // go to "right"
00172       if (i == numStripsW-1) upperBoundW = 1.;
00173       else {
00174         gsl_sf_result result;
00175         int status = gsl_sf_erf_Q_e((i-chargePositionW+1)/chargeSpreadW, &result);
00176         if (status != 0) std::cerr<<"InduceChargeFP420::W could not compute gaussian tail probability for the threshold chosen"<<std::endl;
00177         upperBoundW = 1. - result.val;
00178         
00179         if(verbosity>0) {
00180           std::cout << "go to right: i=  " << i << "upperBoundW=" << upperBoundW << std::endl;
00181         }
00182       }
00183       
00184       double totalIntegrationRange = upperBoundW - lowerBoundW;
00185       y[i] = totalIntegrationRange; // save W strip integral 
00186       
00187       if(totalIntegrationRange<=0.) std::cout << " upperBoundW= " << upperBoundW << " lowerBoundW= " << lowerBoundW << std::endl;
00188       
00189       if(verbosity==-30) {
00190         std::cout << " *InduceChargeFP420:====================================XW  i= " << i << std::endl;
00191         std::cout << " upperBoundW= " << upperBoundW << " lowerBoundW= " << lowerBoundW << std::endl;
00192         std::cout << " totalIntegrationRange= " << totalIntegrationRange << std::endl;
00193         std::cout << " *InduceChargeFP420:==================================== " << std::endl;
00194       }
00195     }
00197     //calculate signal on x strips with including capacitive coupling
00198     int nSignalCoupling = signalCoupling.size();
00199     
00201     /*
00202     int lll,copyinlll;
00203     lll = unpackLayerIndex(rn0,zside);
00204     if(lll==1) {copyinlll=  lll/2;}
00205     else if(lll==2) {copyinlll=  (lll-1)/2;}
00206     else{std::cout << " InduceChargeFP420:WARNING plane number in superlayer= " << lll << std::endl;}
00207 */    
00209     if(verbosity>1) {
00210       std::cout << "InduceChargeFP420:   *************************************************************** " << std::endl;
00211       std::cout << " numStripsW= " << numStripsW << " numStrips= " << numStrips << std::endl;
00212       std::cout << " nSignalCoupling= " << nSignalCoupling << " xytype= " << xytype << std::endl;
00213       std::cout << " stripLeftW= " << stripLeftW << " stripRightW= " << stripRightW << std::endl;
00214       std::cout << " stripLeft= " << stripLeft << " stripRight= " << stripRight << std::endl;
00215     }
00216     // Get the 2D charge integrals by folding x and y strips
00217     for (int iy=stripLeftW; iy<=stripRightW; iy++){ // loop over Wide y index
00218       for (int ix=stripLeft; ix<=stripRight; ix++){ // loop over x index
00219         for (int k = -nSignalCoupling+1 ; k<=nSignalCoupling-1 ; k++) {
00220           if (ix+k >= 0 && ix+k < numStrips ) { 
00221             float ChargeFraction = signalCoupling[abs(k)]*(x[ix]*y[iy]/geVperElectron)*(*sp).amplitude();
00222             if( ChargeFraction > 0. ) {
00223               //  int chan = PixelDigi::pixelToChannel( ix, iy);  // Get index 
00224               int chan = iy*numStrips + (ix+k) ;  // Get index 
00225               
00226               //    if(k==0 ){
00227               //        std::cout << "InduceChargeFP420:                                              chan= " << chan << std::endl;
00228               //        std::cout << "ix= " << ix << "iy= " << iy << std::endl;
00229               //  }
00230               if(verbosity>0) {
00231                 if(k==0 && xytype==2){
00232                   std::cout << "InduceChargeFP420:                                              chan= " << chan << std::endl;
00233                   std::cout << "ix= " << ix << "iy= " << iy << "k= " << k << "ChargeFraction= " << ChargeFraction << std::endl;
00234                   std::cout << "hit_signal[chan]= " << hit_signal[chan] << "geVperElectron= " << geVperElectron << std::endl;
00235                   std::cout << "signalCoupling[abs(k)]= " << signalCoupling[abs(k)] << "x[ix]= " << x[ix] << "y[iy]= " << y[iy] << "(*sp).amplitude()= " << (*sp).amplitude() << std::endl;
00236                 }
00237               }
00238               // Load the amplitude:
00239               hit_signal[chan] += ChargeFraction;
00240             } // endif ChargeFraction
00241           } // endif ix+k
00242           else{
00243             //std::cout << "WARNING:                         ix+k =" << ix+k << std::endl;
00244           }// endif ix+k
00245         } // endfor k
00246       } //endfor ix
00247     } //endfor iy
00248     
00249     if(verbosity>0) {
00250       std::cout << "================================================================================= " << std::endl;
00251     }
00252     
00253     
00254     
00255   } //for loop on ions (*sp)
00256   
00257   if(verbosity>0) {
00258     std::cout << "end of InduceChargeFP420============================= " << std::endl;
00259   }
00260   
00261   
00262   return hit_signal;
00263   
00264   
00265 }