48 #include <gsl/gsl_sf_erf.h>
50 #include "CLHEP/Random/RandGaussQ.h"
51 #include "CLHEP/Random/RandFlat.h"
92 using namespace sipixelobjects;
94 #define TP_DEBUG // protect all LogDebug with ifdef. Takes too much CPU
97 if(use_ineff_from_db_){
99 theSiPixelGainCalibrationService_->setESObjects( es );
103 fillLorentzAngle(es);
110 if(!use_deadmodule_DB_){
111 DeadModules = conf_.getParameter<
Parameters>(
"DeadModules");
120 if(!use_LorentzAngle_DB_){
122 tanLorentzAnglePerTesla_FPix=conf_.getParameter<
double>(
"TanLorentzAnglePerTesla_FPix");
123 tanLorentzAnglePerTesla_BPix=conf_.getParameter<
double>(
"TanLorentzAnglePerTesla_BPix");
141 conf_(conf) , fluctuate(0), theNoiser(0), pIndexConverter(0),
142 use_ineff_from_db_(conf_.getParameter<bool>(
"useDB")),
143 use_module_killing_(conf_.getParameter<bool>(
"killModules")),
144 use_deadmodule_DB_(conf_.getParameter<bool>(
"DeadModules_DB")),
145 use_LorentzAngle_DB_(conf_.getParameter<bool>(
"LorentzAngle_DB")),
146 theSiPixelGainCalibrationService_(0),rndEngine(eng)
240 if (thePixelLuminosity==-1) {
242 for (
int i=0;
i<6;
i++) {
250 }
else if (thePixelLuminosity==0) {
253 for (
int i=0;
i<6;
i++) {
274 }
else if (thePixelLuminosity>0) {
277 for (
int i=0;
i<6;
i++) {
298 if(thePixelLuminosity==10) {
306 if(addNoise || thePixelLuminosity || fluctuateCharge || addThresholdSmearing ) {
315 if(fluctuateCharge) {
320 if(addThresholdSmearing) {
328 if(doMissCalibrate) {
330 <<
" miss-calibrate the pixel amplitude ";
332 const bool ReadCalParameters =
false;
333 if(ReadCalParameters) {
336 char filename[80] =
"phCalibrationFit_C0.dat";
338 in_file.open(filename,
ios::in );
340 cout <<
" File not found " << endl;
343 cout <<
" file opened : " << filename << endl;
346 for (
int i = 0;
i < 3;
i++) {
347 in_file.getline(line, 500,
'\n');
351 cout <<
" test map" << endl;
353 float par0,par1,par2,par3;
357 for(
int i=0;
i<(52*80);
i++) {
358 in_file >> par0 >> par1 >> par2 >> par3 >> name >> colid
361 cerr <<
"Cannot read data file" << endl;
364 if ( in_file.eof() != 0 ) {
365 cerr << in_file.eof() <<
" " << in_file.gcount() <<
" "
366 << in_file.fail() <<
" " << in_file.good() <<
" end of file "
382 calmap.insert(pair<int,CalParameters>(chan,onePix));
386 if(rowid!=p.first)
cout<<
" wrong channel row "<<rowid<<
" "<<p.first<<endl;
387 if(colid!=p.second)
cout<<
" wrong channel col "<<colid<<
" "<<p.second<<endl;
412 LogInfo (
"PixelDigitizer ") <<
"SiPixelDigitizerAlgorithm constructed"
413 <<
"Configuration parameters:"
414 <<
"Threshold/Gain = "
415 <<
"threshold in electron FPix = "
416 << theThresholdInE_FPix
417 <<
"threshold in electron BPix = "
418 << theThresholdInE_BPix
419 <<
" " << theElectronPerADC <<
" " << theAdcFullScale
420 <<
" The delta cut-off is set to " << tMax
427 LogDebug (
"PixelDigitizer")<<
"SiPixelDigitizerAlgorithm deleted";
450 const std::vector<PSimHit> &
input,
470 vector<PixelDigi> collector =
digitize(pixdet);
475 LogDebug (
"PixelDigitizer") <<
"[SiPixelDigitizerAlgorithm] converted " << collector.size() <<
" PixelDigis in DetUnit" <<
detID;
532 <<
" PixelDigitizer "
539 vector<PSimHit>::const_iterator ssbegin;
544 << (*ssbegin).particleType() <<
" " << (*ssbegin).pabs() <<
" "
545 << (*ssbegin).energyLoss() <<
" " << (*ssbegin).tof() <<
" "
546 << (*ssbegin).trackId() <<
" " << (*ssbegin).processType() <<
" "
547 << (*ssbegin).detUnitId()
548 << (*ssbegin).entryPoint() <<
" " << (*ssbegin).exitPoint() ;
594 const float SegmentLength = 0.0010;
601 float length = direction.
mag();
623 float momentum = hit.
pabs();
655 delete[] elossVector;
663 float eloss,
float length,
664 int NumberOfSegs,
float elossVector[]) {
668 if( length > 0.) dedx = eloss/length;
671 double particleMass = 139.6;
674 if(pid==11) particleMass = 0.511;
675 else if(pid==13) particleMass = 105.7;
676 else if(pid==321) particleMass = 493.7;
677 else if(pid==2212) particleMass = 938.3;
680 float segmentLength = length/NumberOfSegs;
685 double segmentEloss = (1000.*eloss)/NumberOfSegs;
686 for (
int i=0;
i<NumberOfSegs;
i++) {
692 double deltaCutoff =
tMax;
694 particleMass, deltaCutoff,
695 double(segmentLength*10.),
696 segmentEloss )/1000.;
704 float ratio = eloss/sum;
706 for (
int ii=0;ii<NumberOfSegs;ii++) elossVector[ii]= ratio*elossVector[ii];
708 float averageEloss = eloss/NumberOfSegs;
709 for (
int ii=0;ii<NumberOfSegs;ii++) elossVector[ii]= averageEloss;
721 LogDebug (
"Pixel Digitizer") <<
" enter drift " ;
727 if(driftDir.
z() ==0.) {
728 LogWarning(
"Magnetic field") <<
" pxlx: drift in z is zero ";
736 float TanLorenzAngleX, TanLorenzAngleY,dir_z, CosLorenzAngleX,
740 TanLorenzAngleX = driftDir.
x();
741 TanLorenzAngleY = driftDir.
y();
742 dir_z = driftDir.
z();
743 CosLorenzAngleX = 1./
sqrt(1.+TanLorenzAngleX*TanLorenzAngleX);
744 CosLorenzAngleY = 1./
sqrt(1.+TanLorenzAngleY*TanLorenzAngleY);
748 TanLorenzAngleX = driftDir.
x();
749 TanLorenzAngleY = 0.;
750 dir_z = driftDir.
z();
751 CosLorenzAngleX = 1./
sqrt(1.+TanLorenzAngleX*TanLorenzAngleX);
752 CosLorenzAngleY = 1.;
758 <<
" Lorentz Tan " << TanLorenzAngleX <<
" " << TanLorenzAngleY <<
" "
759 << CosLorenzAngleX <<
" " << CosLorenzAngleY <<
" "
772 float SegX, SegY, SegZ;
790 if( DriftDistance < 0.) {
796 float XDriftDueToMagField = DriftDistance * TanLorenzAngleX;
797 float YDriftDueToMagField = DriftDistance * TanLorenzAngleY;
800 float CloudCenterX = SegX + XDriftDueToMagField;
801 float CloudCenterY = SegY + YDriftDueToMagField;
804 DriftLength =
sqrt( DriftDistance*DriftDistance +
805 XDriftDueToMagField*XDriftDueToMagField +
806 YDriftDueToMagField*YDriftDueToMagField );
812 Sigma_x = Sigma / CosLorenzAngleX ;
813 Sigma_y = Sigma / CosLorenzAngleY ;
834 <<
" enter induce_signal, "
839 typedef map< int, float, less<int> > hit_map_type;
840 hit_map_type hit_signal;
843 map<int, float, less<int> >
x,
y;
851 float CloudCenterX =
i->position().x();
852 float CloudCenterY =
i->position().y();
853 float SigmaX =
i->sigma_x();
854 float SigmaY =
i->sigma_y();
855 float Charge =
i->amplitude();
866 <<
" cloud " <<
i->position().x() <<
" " <<
i->position().y() <<
" "
867 <<
i->sigma_x() <<
" " <<
i->sigma_y() <<
" " <<
i->amplitude();
890 int IPixRightUpX = int( floor( mp.
x()));
891 int IPixRightUpY = int( floor( mp.
y()));
894 LogDebug (
"Pixel Digitizer") <<
" right-up " << PointRightUp <<
" "
895 << mp.
x() <<
" " << mp.
y() <<
" "
896 << IPixRightUpX <<
" " << IPixRightUpY ;
901 int IPixLeftDownX = int( floor( mp.
x()));
902 int IPixLeftDownY = int( floor( mp.
y()));
905 LogDebug (
"Pixel Digitizer") <<
" left-down " << PointLeftDown <<
" "
906 << mp.
x() <<
" " << mp.
y() <<
" "
907 << IPixLeftDownX <<
" " << IPixLeftDownY ;
913 IPixLeftDownX = 0<IPixLeftDownX ? IPixLeftDownX : 0 ;
914 IPixLeftDownY = 0<IPixLeftDownY ? IPixLeftDownY : 0 ;
921 for (ix=IPixLeftDownX; ix<=IPixRightUpX; ix++) {
922 float xUB, xLB, UpperBound, LowerBound;
927 if (ix == 0 || SigmaX==0. )
933 int status = gsl_sf_erf_Q_e( (xLB-CloudCenterX)/SigmaX, &result);
935 LogWarning (
"Integration")<<
"could not compute gaussian probability";
936 LowerBound = 1-result.val;
939 if (ix ==
numRows-1 || SigmaX==0. )
945 int status = gsl_sf_erf_Q_e( (xUB-CloudCenterX)/SigmaX, &result);
947 LogWarning (
"Integration")<<
"could not compute gaussian probability";
948 UpperBound = 1. - result.val;
951 float TotalIntegrationRange = UpperBound - LowerBound;
952 x[ix] = TotalIntegrationRange;
960 for (iy=IPixLeftDownY; iy<=IPixRightUpY; iy++) {
961 float yUB, yLB, UpperBound, LowerBound;
963 if (iy == 0 || SigmaY==0.)
969 int status = gsl_sf_erf_Q_e( (yLB-CloudCenterY)/SigmaY, &result);
971 LogWarning (
"Integration")<<
"could not compute gaussian probability";
972 LowerBound = 1. - result.val;
981 int status = gsl_sf_erf_Q_e( (yUB-CloudCenterY)/SigmaY, &result);
983 LogWarning (
"Integration")<<
"could not compute gaussian probability";
984 UpperBound = 1. - result.val;
987 float TotalIntegrationRange = UpperBound - LowerBound;
988 y[iy] = TotalIntegrationRange;
995 for (ix=IPixLeftDownX; ix<=IPixRightUpX; ix++) {
996 for (iy=IPixLeftDownY; iy<=IPixRightUpY; iy++) {
998 float ChargeFraction = Charge*x[ix]*y[iy];
1000 if( ChargeFraction > 0. ) {
1003 hit_signal[chan] += ChargeFraction;
1013 <<
" pixel " << ix <<
" " << iy <<
" - "<<
" "
1014 << chan <<
" " << ChargeFraction<<
" "
1015 << mp.
x() <<
" " << mp.
y() <<
" "
1016 << lp.
x() <<
" " << lp.
y() <<
" "
1046 for ( hit_map_type::const_iterator im = hit_signal.begin();
1047 im != hit_signal.end(); im++) {
1050 int chan = (*im).first;
1055 <<
" pixel " << ip.first <<
" " << ip.second <<
" "
1069 LogDebug (
"Pixel Digitizer") <<
" make digis "<<
" "
1072 <<
" List pixels passing threshold ";
1079 float signalInElectrons = (*i).second ;
1088 int chan = (*i).first;
1095 int col = ip.second;
1104 << (*i).first <<
" " << (*i).second <<
" " << signalInElectrons
1105 <<
" " << adc << ip.first <<
" " << ip.second ;
1112 if((*i).second.hits().size()>0){
1115 for( vector<const PSimHit*>::const_iterator ihit = (*i).second.hits().begin();
1116 ihit != (*i).second.hits().end(); ihit++) {
1117 simi[(**ihit).trackId()].push_back((*i).second.individualampl()[il]);
1122 for( simlink_map::iterator simiiter=
simi.begin();
1123 simiiter!=
simi.end();
1126 float sum_samechannel=0;
1127 for (
unsigned int iii=0;iii<(*simiiter).second.size();iii++){
1128 sum_samechannel+=(*simiiter).second[iii];
1130 float fraction=sum_samechannel/(*i).second;
1131 if (fraction>1.) fraction=1.;
1156 if((*i).second < 3000)
1159 }
else if((*i).second < 6000){
1170 if(((*i).second +
Amplitude(noise+noise_ChargeVCALSmearing,0,-1.)) < 0. ) {
1171 (*i).second.set(0);}
1173 (*i).second +=
Amplitude(noise+noise_ChargeVCALSmearing,0,-1.);
1183 if(((*i).second +
Amplitude(noise,0,-1.)) < 0. ) {
1184 (*i).second.set(0);}
1198 map<int,float, less<int> > otherPixels;
1199 map<int,float, less<int> >::iterator mapI;
1208 <<
" Add noisy pixels " <<
numRows <<
" "
1211 << otherPixels.size() ;
1215 for (mapI = otherPixels.begin(); mapI!= otherPixels.end(); mapI++) {
1216 int iy = ((*mapI).first) /
numRows;
1217 int ix = ((*mapI).first) - (iy*
numRows);
1221 LogWarning (
"Pixel Geometry") <<
" error in iy " << iy ;
1222 if( ix < 0 || ix > (numRows-1) )
1223 LogWarning (
"Pixel Geometry") <<
" error in ix " << ix ;
1229 <<
" Storing noise = " << (*mapI).first <<
" " << (*mapI).second
1230 <<
" " << ix <<
" " << iy <<
" " << chan ;
1235 int noise=int( (*mapI).second );
1250 float pixelEfficiency = 1.0;
1251 float columnEfficiency = 1.0;
1252 float chipEfficiency = 1.0;
1283 LogDebug (
"Pixel Digitizer") <<
" enter pixel_inefficiency " << pixelEfficiency <<
" "
1284 << columnEfficiency <<
" " << chipEfficiency;
1292 map<int, int, less<int> >chips, columns;
1293 map<int, int, less<int> >::iterator iter;
1299 int chan =
i->first;
1302 int col = ip.second;
1310 columns[dColInDet]++;
1314 for ( iter = chips.begin(); iter != chips.end() ; iter++ ) {
1317 if( rand > chipEfficiency ) chips[iter->first]=0;
1321 for ( iter = columns.begin(); iter != columns.end() ; iter++ ) {
1324 if( rand > columnEfficiency ) columns[iter->first]=0;
1334 int col = ip.second;
1344 if( chips[chipIndex]==0 || columns[dColInDet]==0
1345 || rand>pixelEfficiency ) {
1364 const float signalInElectrons)
const {
1403 newAmp = p3 + p2 * tanh(p0*signal - p1);
1481 dir_z = -(1 + alpha2_BPix* Bfield.z()*Bfield.z() );
1482 scale = (1 + alpha2_BPix* Bfield.z()*Bfield.z() );
1487 dir_z = -(1 + alpha2_FPix* Bfield.z()*Bfield.z() );
1488 scale = (1 + alpha2_FPix* Bfield.z()*Bfield.z() );
1495 std::map<unsigned int,float>::const_iterator it;
1498 for (it=detid_la.begin();it!=detid_la.end();it++)
1500 if (
detID==it->first) {
1502 alpha2 = it->second * it->second;
1508 dir_x = -( it->second * Bfield.y() + alpha2 * Bfield.z()* Bfield.x() );
1509 dir_y = +( it->second * Bfield.x() - alpha2 * Bfield.z()* Bfield.y() );
1510 dir_z = -(1 + alpha2 * Bfield.z()*Bfield.z() );
1511 scale = (1 + alpha2 * Bfield.z()*Bfield.z() );
1519 LogDebug (
"Pixel Digitizer") <<
" The drift direction in local coordinate is "
1520 << theDriftDirection ;
1523 return theDriftDirection;
1538 int col = ip.second;
1559 Parameters::iterator itDeadModules=
DeadModules.begin();
1561 for(; itDeadModules !=
DeadModules.end(); ++itDeadModules){
1562 int Dead_detID = itDeadModules->getParameter<
int>(
"Dead_detID");
1563 if(detid==Dead_detID){
1572 std::string
Module = itDeadModules->getParameter<std::string>(
"Module");
1574 if(Module==
"whole"){
1583 if(Module==
"tbmA" && ip.first>=80 && ip.first<=159){
1587 if( Module==
"tbmB" && ip.first<=79){
1604 std::vector<SiPixelQuality::disabledModuleType>disabledModules =
SiPixelBadModule_->getBadComponentList();
1608 for (
size_t id=0;
id<disabledModules.size();
id++)
1610 if(detid==disabledModules[
id].DetID){
1612 badmodule = disabledModules[
id];
1629 std::vector<GlobalPixel> badrocpositions (0);
1630 std::pair<uint8_t, uint8_t> coord(1,1);
1631 for(
unsigned int j = 0;
j < 16;
j++){
1634 std::vector<CablingPathToDetUnit>
path =
map_.
product()->pathToDetUnit(detid);
1635 typedef std::vector<CablingPathToDetUnit>::const_iterator
IT;
1636 for (IT it = path.begin(); it != path.end(); ++it) {
1641 badrocpositions.push_back(global);
1651 for(std::vector<GlobalPixel>::const_iterator it = badrocpositions.begin(); it != badrocpositions.end(); ++it){
1654 if((ip.first>=(it->row)-40 && ip.first<=(it->row)+39) && (ip.second>=(it->col)-25 && ip.second<=(it->col)+26)){
1659 if((ip.first>=(it->row)-39 && ip.first<=(it->row)+40) && (ip.second>=(it->col)-25 && ip.second<=(it->col)+26)){
int adc(sample_type sample)
get the ADC sample (12 bits)
void init(const edm::EventSetup &es)
std::vector< T > collection_type
T getParameter(std::string const &) const
float thePixelThresholdInE
T getUntrackedParameter(std::string const &, T const &) const
bool use_LorentzAngle_DB_
Local3DVector LocalVector
float tof() const
deprecated name for timeOfFlight()
edm::ESHandle< SiPixelFedCablingMap > map_
GaussianTailNoiseGenerator * theNoiser
float tanLorentzAnglePerTesla_BPix
GlobalPixel toGlobal(const LocalPixel &loc) const
static int DColumn(const int colROC)
virtual LocalPoint localPosition(const MeasurementPoint &) const =0
virtual int ncolumns() const =0
const PixelGeomDetUnit * _detp
SiG4UniversalFluctuation * fluctuate
float thePixelColEfficiency[6]
float thePixelChipEfficiency[6]
virtual int nrows() const =0
int transformToROC(const int col, const int row, int &rocId, int &colROC, int &rowROC) const
std::vector< PixelDigi > digitize(PixelGeomDetUnit *det)
~SiPixelDigitizerAlgorithm()
void fluctuateEloss(int particleId, float momentum, float eloss, float length, int NumberOfSegments, float elossVector[])
identify pixel inside single ROC
unsigned int layer() const
layer id
SiPixelGainCalibrationOfflineSimService * theSiPixelGainCalibrationService_
static int pixelToChannel(int row, int col)
global coordinates (row and column in DetUnit, as in PixelDigi)
uint32_t rawId() const
get the raw id
CLHEP::RandGaussQ * gaussDistributionVCALNoise_
virtual float thickness() const =0
double SampleFluctuations(const double momentum, const double mass, double &tmax, const double length, const double meanLoss)
double theThresholdSmearing_BPix
Measurement2DPoint MeasurementPoint
Measurement points are two-dimensional by default.
Local3DPoint exitPoint() const
Exit point in the local Det frame.
virtual const BoundPlane & specificSurface() const
Same as surface(), kept for backward compatibility.
float theThresholdInE_BPix
void fillDeadModules(const edm::EventSetup &es)
float thePixelEfficiency[6]
static int pixelToChannelROC(const int rowROC, const int colROC)
std::vector< PixelDigiSimLink > link_coll
edm::DetSet< PixelDigi >::collection_type run(const std::vector< PSimHit > &input, PixelGeomDetUnit *pixdet, GlobalVector)
static std::pair< int, int > channelToPixelROC(const int chan)
unsigned int idInDetUnit() const
id of this ROC in DetUnit etermined by token path
float tanLorentzAnglePerTesla_FPix
PixelIndices * pIndexConverter
virtual int channel(const LocalPoint &p) const =0
DetId geographicalId() const
The label of this GeomDet.
virtual MeasurementPoint measurementPosition(const LocalPoint &) const =0
static const char * Sigma
void fillLorentzAngle(const edm::EventSetup &es)
std::vector< LinkConnSpec >::const_iterator IT
float theThresholdInE_FPix
float pabs() const
fast and more accurate access to momentumAtEntry().mag()
signal_map_type::iterator signal_map_iterator
int subdetId() const
get the contents of the subdetector field (not cast into any detector's numbering enum) ...
std::vector< PSimHit > _PixelHits
float theNoiseInElectrons
void module_killing_conf()
edm::ESHandle< SiPixelLorentzAngle > SiPixelLorentzAngle_
std::map< int, CalParameters, std::less< int > > calmap
double electronsPerVCAL_Offset
CLHEP::RandGaussQ * gaussDistribution_
virtual std::pair< float, float > pitch() const =0
const PixelTopology * topol
const Bounds & bounds() const
std::vector< PixelDigi > internal_coll
edm::ESHandle< SiPixelQuality > SiPixelBadModule_
void fillMapandGeom(const edm::EventSetup &es)
static std::pair< int, int > channelToPixel(int ch)
void pixel_inefficiency()
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
T const * product() const
bool addChargeVCALSmearing
row and collumn in ROC representation
CLHEP::RandGaussQ * smearedThreshold_FPix_
double theThresholdSmearing_FPix
std::vector< EnergyDepositUnit > _ionization_points
std::vector< edm::ParameterSet > Parameters
CLHEP::RandGaussQ * smearedThreshold_BPix_
void generate(int NumberOfchannels, float threshold, float noiseRMS, std::map< int, float > &theMap)
float energyLoss() const
The energy deposit in the PSimHit, in ???.
void drift(const PSimHit &hit)
float theSmearedChargeRMS
bool addThresholdSmearing
const RotationType & rotation() const
void primary_ionization(const PSimHit &hit)
CLHEP::RandFlat * flatDistribution_
SiPixelDigitizerAlgorithm(const edm::ParameterSet &conf, CLHEP::HepRandomEngine &)
std::vector< SignalPoint > _collection_points
float missCalibrate(int col, int row, float amp) const
static int DColumnInModule(const int dcol, const int chipIndex)
void induce_signal(const PSimHit &hit)
const PositionType & position() const
Local3DPoint entryPoint() const
Entry point in the local Det frame.
bool isDead(const uint32_t &detID, const int &col, const int &row)
virtual const BoundPlane & surface() const
The nominal surface of the GeomDet.
void pixel_inefficiency_db()
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
LocalVector DriftDirection()
CLHEP::HepRandomEngine & rndEngine