00001
00002
00003
00004
00005
00007 #include "SimRomanPot/SimFP420/interface/InduceChargeFP420.h"
00008 #include <gsl/gsl_sf_erf.h>
00009 #include<iostream>
00010 using namespace std;
00011
00012
00013
00014 static float capacitive_coupling[2] = {.80,.10};
00015 static float FiducialXYZ[3] = {5.,10.,0.250};
00016
00017 IChargeFP420::hit_map_type InduceChargeFP420::induce(CDrifterFP420::collection_type _collection_points, int numStrips, double localPitch, int numStripsW, double localPitchW, int zside){
00018 signalCoupling.clear();
00019 signalCoupling.push_back(capacitive_coupling[0]);
00020 signalCoupling.push_back(capacitive_coupling[1]);
00021
00022
00023
00024 int stripLeft, stripRight, stripLeftW, stripRightW;
00025 double upperBound, lowerBound, upperBoundW, lowerBoundW;
00026
00027
00028 hit_map_type hit_signal;
00029
00030
00031 map<int, float, less<int> > x,y;
00032
00033
00034 for (CDrifterFP420::collection_type::const_iterator sp=_collection_points.begin(); sp != _collection_points.end(); sp++ ){
00035
00036 float chargePositionW=-1.;
00037 float chargePosition=-1.;
00038
00039
00040 G4ThreeVector Position3D = (*sp).position();
00041
00042 #ifdef mydigidebug4
00043 std::cout << " =============================*InduceChargeFP420:induce:Position3D= " << Position3D << std::endl;
00044 std::cout << " localPitch= " << localPitch << std::endl;
00045 std::cout << " zside= " << zside << " numStrips= " << numStrips << std::endl;
00046 #endif
00047
00048
00049
00050
00051 if( abs(Position3D.x())<FiducialXYZ[0] &&
00052 abs(Position3D.y())<FiducialXYZ[1] ) {
00053 if( abs(Position3D.z())<FiducialXYZ[2] ) {
00054 }
00055 else{
00056 (*sp).amplitude() == 0.;
00057
00058 std::cout << " *InduceChargeFP420:Z slice outside the plate: Position3D= " << Position3D << std::endl;
00059
00060 }
00061 }
00062 else{
00063 (*sp).amplitude() == 0.;
00064
00065 std::cout << " *InduceChargeFP420:XY slice outside the plate: Position3D= " << Position3D << std::endl;
00066
00067 }
00068
00069
00070
00071 if(zside == 1) {
00072
00073 chargePosition = 0.5*numStrips + Position3D.x()/localPitch ;
00074 chargePositionW = 0.5*numStripsW + Position3D.y()/localPitchW ;
00075 }
00076
00077 else if(zside == 2) {
00078
00079 chargePosition = 0.5*numStrips + Position3D.y()/localPitch ;
00080 chargePositionW = 0.5*numStripsW + Position3D.x()/localPitchW ;
00081 }
00082 else {
00083 std::cout << "**** InduceChargeFP420: !!! ERROR: you have not to be here !!! zside=" << zside << std::endl;
00084
00085 }
00086
00087 #ifdef mydigidebug5
00088 if(zside==2){
00089 std::cout << " =========================================================================== " << std::endl;
00090 std::cout << "**** InduceChargeFP420: zside= " << zside << std::endl;
00091 std::cout << " chargePositionW= " << chargePositionW << std::endl;
00092 std::cout << " chargePosition= " << chargePosition << std::endl;
00093 std::cout << "Position3D= " << Position3D << std::endl;
00094 }
00095 #endif
00096
00097 float chargeSpread = (*sp).sigma()/localPitch ;
00098 float chargeSpreadW = (*sp).sigma()/localPitchW ;
00099
00100
00101
00102 stripLeft = int( chargePosition-clusterWidth*chargeSpread);
00103 stripRight = int( chargePosition+clusterWidth*chargeSpread);
00104 stripLeft = (0<stripLeft ? stripLeft : 0);
00105 stripRight = (numStrips >stripRight ? stripRight : numStrips-1);
00106
00107 stripLeftW = int( chargePositionW-clusterWidth*chargeSpreadW);
00108 stripRightW = int( chargePositionW+clusterWidth*chargeSpreadW);
00109 stripLeftW = (0<stripLeftW ? stripLeftW : 0);
00110 stripRightW = (numStripsW >stripRightW ? stripRightW : numStripsW-1);
00111
00112 #ifdef mydigidebug4
00113 std::cout << " Position3D = " << Position3D << "amplitude=" << (*sp).amplitude() << std::endl;
00114 std::cout << " MaxChargeSpread= " << clusterWidth*chargeSpread << " sigma= " << (*sp).sigma() << std::endl;
00115 std::cout << "*** numStrips= " << numStrips << " localPitch= " << localPitch << "zside=" << zside << std::endl;
00116 std::cout << " chargePosition= " << chargePosition << " chargeSpread= " << chargeSpread << std::endl;
00117 std::cout << " stripLeft= " << stripLeft << " stripRight= " << stripRight << std::endl;
00118 std::cout << " chargePositionW= " << chargePositionW << " chargeSpreadW= " << chargeSpreadW << std::endl;
00119 std::cout << " stripLeftW= " << stripLeftW << " stripRightW= " << stripRightW << std::endl;
00120 #endif
00122 for (int i=stripLeft; i<=stripRight; i++){
00123
00124
00125 if (i == 0) lowerBound = 0. ;
00126 else {
00127 gsl_sf_result result;
00128 int status = gsl_sf_erf_Q_e((i-chargePosition)/chargeSpread, &result);
00129 if (status != 0) cerr<<"InduceChargeFP420::could not compute gaussian tail probability for the threshold chosen"<<std::endl;
00130 lowerBound = 1. - result.val;
00131
00132 #ifdef mydigidebug4
00133 std::cout << "go to left: i= " << i << "lowerBound=" << lowerBound << std::endl;
00134 #endif
00135 }
00136
00137
00138 if (i == numStrips-1) upperBound = 1.;
00139 else {
00140 gsl_sf_result result;
00141 int status = gsl_sf_erf_Q_e((i-chargePosition+1)/chargeSpread, &result);
00142 if (status != 0) cerr<<"InduceChargeFP420::could not compute gaussian tail probability for the threshold chosen"<<std::endl;
00143 upperBound = 1. - result.val;
00144
00145 #ifdef mydigidebug4
00146 std::cout << "go to right: i= " << i << "upperBound=" << upperBound << std::endl;
00147 #endif
00148 }
00149
00150 double totalIntegrationRange = upperBound - lowerBound;
00151 x[i] = totalIntegrationRange;
00152
00153 if(totalIntegrationRange<=0.) std::cout << " upperBound= " << upperBound << " lowerBound= " << lowerBound << std::endl;
00154
00155 #ifdef mydigidebug4
00156 std::cout << " *InduceChargeFP420:====================================X i = " << i << std::endl;
00157 std::cout << " upperBound= " << upperBound << " lowerBound= " << lowerBound << std::endl;
00158 std::cout << " totalIntegrationRange= " << totalIntegrationRange << std::endl;
00159 std::cout << " *InduceChargeFP420:==================================== " << std::endl;
00160 #endif
00161 }
00163 for (int i=stripLeftW; i<=stripRightW; i++){
00164
00165
00166 if (i == 0) lowerBoundW = 0. ;
00167 else {
00168 gsl_sf_result result;
00169 int status = gsl_sf_erf_Q_e((i-chargePositionW)/chargeSpreadW, &result);
00170 if (status != 0) cerr<<"InduceChargeFP420::W could not compute gaussian tail probability for the threshold chosen"<<std::endl;
00171 lowerBoundW = 1. - result.val;
00172
00173 #ifdef mydigidebug4
00174 std::cout << "go to left: i= " << i << "lowerBoundW=" << lowerBoundW << std::endl;
00175 #endif
00176 }
00177
00178
00179 if (i == numStripsW-1) upperBoundW = 1.;
00180 else {
00181 gsl_sf_result result;
00182 int status = gsl_sf_erf_Q_e((i-chargePositionW+1)/chargeSpreadW, &result);
00183 if (status != 0) cerr<<"InduceChargeFP420::W could not compute gaussian tail probability for the threshold chosen"<<std::endl;
00184 upperBoundW = 1. - result.val;
00185
00186 #ifdef mydigidebug4
00187 std::cout << "go to right: i= " << i << "upperBoundW=" << upperBoundW << std::endl;
00188 #endif
00189 }
00190
00191 double totalIntegrationRange = upperBoundW - lowerBoundW;
00192 y[i] = totalIntegrationRange;
00193
00194 if(totalIntegrationRange<=0.) std::cout << " upperBoundW= " << upperBoundW << " lowerBoundW= " << lowerBoundW << std::endl;
00195
00196 #ifdef mydigidebug4
00197 std::cout << " *InduceChargeFP420:====================================XW i= " << i << std::endl;
00198 std::cout << " upperBoundW= " << upperBoundW << " lowerBoundW= " << lowerBoundW << std::endl;
00199 std::cout << " totalIntegrationRange= " << totalIntegrationRange << std::endl;
00200 std::cout << " *InduceChargeFP420:==================================== " << std::endl;
00201 #endif
00202 }
00204
00205
00206
00207
00208
00209
00210
00211 int nSignalCoupling = signalCoupling.size();
00212 #ifdef mydigidebug4
00213 std::cout << " nSignalCoupling= " << nSignalCoupling << std::endl;
00214 #endif
00215
00216 for (int iy=stripLeftW; iy<=stripRightW; iy++){
00217 for (int ix=stripLeft; ix<=stripRight; ix++){
00218 for (int k = -nSignalCoupling+1 ; k<=nSignalCoupling-1 ; k++) {
00219 if (ix+k >= 0 && ix+k < numStrips ) {
00220 float ChargeFraction = signalCoupling[abs(k)]*(x[ix]*y[iy]/geVperElectron)*(*sp).amplitude();
00221 if( ChargeFraction > 0. ) {
00222
00223 int chan = iy*numStrips + (ix+k) ;
00224 #ifdef mydigidebug5
00225 if(k==0 && zside==2){
00226 std::cout << "InduceChargeFP420: chan= " << chan << std::endl;
00227 std::cout << "ix= " << ix << "iy= " << iy << "k= " << k << "ChargeFraction= " << ChargeFraction << std::endl;
00228 std::cout << "hit_signal[chan]= " << hit_signal[chan] << "geVperElectron= " << geVperElectron << std::endl;
00229 std::cout << "signalCoupling[abs(k)]= " << signalCoupling[abs(k)] << "x[ix]= " << x[ix] << "y[iy]= " << y[iy] << "(*sp).amplitude()= " << (*sp).amplitude() << std::endl;
00230 }
00231 #endif
00232
00233 hit_signal[chan] += ChargeFraction;
00234 }
00235 }
00236 else{
00237
00238 }
00239 }
00240 }
00241 }
00242 #ifdef mydigidebug5
00243 std::cout << "============================= " << std::endl;
00244 #endif
00245
00246 #ifdef mydigidebug4
00247
00248 std::cout << " *InduceChargeFP420:=========== zside=" << zside << std::endl;
00249 std::cout << " chargePos= " << chargePosition << std::endl;
00250 std::cout << "Position3D= " << Position3D << std::endl;
00251 std::cout << " i+j= " << i+j << " hit_signal[i+j]= " << hit_signal[i+j] << std::endl;
00252 std::cout << " (*sp).amplitude()= " << (*sp).amplitude() << " i= " << i << " j= " << j << std::endl;
00253 std::cout << " upperBound= " << upperBound << " lowerBound= " << lowerBound << std::endl;
00254 std::cout << " signalCoupling[abs(j)]= " << signalCoupling[abs(j)] << std::endl;
00255 std::cout << " ===================== " << std::endl;
00256
00257 #endif
00258
00259
00260
00261 }
00262
00263 #ifdef mydigidebug5
00264 std::cout << "end of InduceChargeFP420============================= " << std::endl;
00265 #endif
00266
00267
00268 return hit_signal;
00269
00270
00271 }