From 3ecf9e6691eed5bde827989fae1d89d33e85b089 Mon Sep 17 00:00:00 2001 From: Petar Date: Sat, 3 Mar 2018 00:34:49 -0600 Subject: [PATCH] New 2D pixel template reconstruction, with "cluster repair" capability. --- .../Records/interface/TkPixelCPERecord.h | 3 +- .../SiPixelRecHits/interface/PixelCPEBase.h | 3 + .../interface/PixelCPEGenericESProducer.h | 3 +- .../interface/PixelCPETemplateReco.h | 5 + .../PixelCPETemplateRecoESProducer.h | 3 +- .../interface/SiPixelGenError.h | 29 +- .../interface/SiPixelTemplate.h | 17 +- .../interface/SiPixelTemplate2D.h | 181 +- .../interface/SiPixelTemplateDefs.h | 9 +- .../plugins/PixelCPEGenericESProducer.cc | 5 +- .../plugins/PixelCPETemplateRecoESProducer.cc | 6 +- .../SiPixelRecHits/src/PixelCPEBase.cc | 21 +- .../src/PixelCPETemplateReco.cc | 21 +- .../SiPixelRecHits/src/SiPixelGenError.cc | 49 +- .../SiPixelRecHits/src/SiPixelTemplate.cc | 10 +- .../SiPixelRecHits/src/SiPixelTemplate2D.cc | 2299 +++++++++++------ 16 files changed, 1777 insertions(+), 887 deletions(-) diff --git a/RecoLocalTracker/Records/interface/TkPixelCPERecord.h b/RecoLocalTracker/Records/interface/TkPixelCPERecord.h index 484aeba58e0f8..c3b0ce03a356e 100644 --- a/RecoLocalTracker/Records/interface/TkPixelCPERecord.h +++ b/RecoLocalTracker/Records/interface/TkPixelCPERecord.h @@ -10,11 +10,12 @@ //#include "CondFormats/DataRecord/interface/SiPixelCPEGenericErrorParmRcd.h" #include "CondFormats/DataRecord/interface/SiPixelGenErrorDBObjectRcd.h" #include "CalibTracker/Records/interface/SiPixelTemplateDBObjectESProducerRcd.h" +#include "CalibTracker/Records/interface/SiPixel2DTemplateDBObjectESProducerRcd.h" #include "boost/mpl/vector.hpp" class TkPixelCPERecord: public edm::eventsetup::DependentRecordImplementation > {}; + boost::mpl::vector > {}; #endif diff --git a/RecoLocalTracker/SiPixelRecHits/interface/PixelCPEBase.h b/RecoLocalTracker/SiPixelRecHits/interface/PixelCPEBase.h index 8058eb5f4d311..e344824630003 100644 --- a/RecoLocalTracker/SiPixelRecHits/interface/PixelCPEBase.h +++ b/RecoLocalTracker/SiPixelRecHits/interface/PixelCPEBase.h @@ -113,6 +113,9 @@ class PixelCPEBase : public PixelClusterParameterEstimator // ggiurgiu@jhu.edu (10/18/2008) bool with_track_angle; // filled in computeAnglesFrom.... + // More detailed edge information (for CPE ClusterRepair, and elsewhere...) + int edgeTypeX_ = 0; // 0: not on edge, 1: low end on edge, 2: high end + int edgeTypeY_ = 0; // 0: not on edge, 1: low end on edge, 2: high end }; public: diff --git a/RecoLocalTracker/SiPixelRecHits/interface/PixelCPEGenericESProducer.h b/RecoLocalTracker/SiPixelRecHits/interface/PixelCPEGenericESProducer.h index e10ecc700de03..3e1dd6ac171e5 100644 --- a/RecoLocalTracker/SiPixelRecHits/interface/PixelCPEGenericESProducer.h +++ b/RecoLocalTracker/SiPixelRecHits/interface/PixelCPEGenericESProducer.h @@ -11,8 +11,9 @@ class PixelCPEGenericESProducer: public edm::ESProducer{ public: PixelCPEGenericESProducer(const edm::ParameterSet & p); ~PixelCPEGenericESProducer() override; - std::unique_ptr produce(const TkPixelCPERecord &); + std::shared_ptr produce(const TkPixelCPERecord &); private: + std::shared_ptr cpe_; edm::ParameterSet pset_; edm::ESInputTag magname_; bool useLAWidthFromDB_; diff --git a/RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateReco.h b/RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateReco.h index 70a412ffb617e..f8b2592064cdc 100644 --- a/RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateReco.h +++ b/RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateReco.h @@ -78,6 +78,11 @@ class PixelCPETemplateReco : public PixelCPEBase int speed_ ; bool UseClusterSplitter_; + + // Template file management (when not getting the templates from the DB) + int barrelTemplateID_ ; + int forwardTemplateID_ ; + std::string templateDir_ ; //bool DoCosmics_; //bool LoadTemplatesFromDB_; diff --git a/RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateRecoESProducer.h b/RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateRecoESProducer.h index 4a47426f44f23..67e1c081b09f6 100644 --- a/RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateRecoESProducer.h +++ b/RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateRecoESProducer.h @@ -11,8 +11,9 @@ class PixelCPETemplateRecoESProducer: public edm::ESProducer{ public: PixelCPETemplateRecoESProducer(const edm::ParameterSet & p); ~PixelCPETemplateRecoESProducer() override; - std::unique_ptr produce(const TkPixelCPERecord &); + std::shared_ptr produce(const TkPixelCPERecord &); private: + std::shared_ptr cpe_; edm::ParameterSet pset_; bool DoLorentz_; }; diff --git a/RecoLocalTracker/SiPixelRecHits/interface/SiPixelGenError.h b/RecoLocalTracker/SiPixelRecHits/interface/SiPixelGenError.h index bd4f069a26a51..8be4f20b7ca94 100644 --- a/RecoLocalTracker/SiPixelRecHits/interface/SiPixelGenError.h +++ b/RecoLocalTracker/SiPixelRecHits/interface/SiPixelGenError.h @@ -1,11 +1,17 @@ // -// SiPixelGenError.h (v2.00) +// SiPixelGenError.h (v2.20) // // Object to contain Lorentz drift and error information for the Generic Algorithm // // Created by Morris Swartz on 1/10/2014. // // Update for Phase 1 FPix, M.S. 1/15/17 +// V2.01 - Allow subdetector ID=5 for FPix R2P2, Fix error message +// V2.10 - Update the variable size [SI_PIXEL_TEMPLATE_USE_BOOST] option so that it works with VI's enhancements +// V2.20 - Add directory path selection to the ascii pushfile method + + + // // Build the template storage structure from several pieces @@ -16,6 +22,7 @@ #include #include +#include "boost/multi_array.hpp" #ifndef SI_PIXEL_TEMPLATE_STANDALONE #include "CondFormats/SiPixelObjects/interface/SiPixelGenErrorDBObject.h" @@ -77,11 +84,19 @@ struct SiPixelGenErrorHeader { //!< template header structure struct SiPixelGenErrorStore { //!< template storage structure SiPixelGenErrorHeader head; +#ifndef SI_PIXEL_TEMPLATE_USE_BOOST float cotbetaY[60]; float cotbetaX[5]; float cotalphaX[29]; SiPixelGenErrorEntry enty[60]; //!< 60 Barrel y templates spanning cluster lengths from 0px to +18px [28 entries for fpix] SiPixelGenErrorEntry entx[5][29]; //!< 29 Barrel x templates spanning cluster lengths from -6px (-1.125Rad) to +6px (+1.125Rad) in each of 5 slices [3x29 for fpix] +#else + float* cotbetaY; + float* cotbetaX; + float* cotalphaX; + boost::multi_array enty; //!< use 1d entry to store [60] barrel entries or [28] fpix entries + boost::multi_array entx; //!< use 2d entry to store [5][29] barrel entries or [3][29] fpix entries +#endif } ; @@ -104,9 +119,10 @@ class SiPixelGenError { public: SiPixelGenError(const std::vector< SiPixelGenErrorStore > & thePixelTemp) : thePixelTemp_(thePixelTemp) { id_current_ = -1; index_id_ = -1;} //!< Constructor for cases in which template store already exists - static bool pushfile(int filenum, std::vector< SiPixelGenErrorStore > & thePixelTemp_); // load the private store with info from the - // file with the index (int) filenum - +// Load the private store with info from the file with the index (int) filenum from directory dir: +// ${dir}generror_summary_zp${filenum}.out + static bool pushfile(int filenum, std::vector< SiPixelGenErrorStore > & thePixelTemp_ , std::string dir = ""); + #ifndef SI_PIXEL_TEMPLATE_STANDALONE static bool pushfile(const SiPixelGenErrorDBObject& dbobject, std::vector< SiPixelGenErrorStore > & thePixelTemp_); // load the private store with info from db #endif @@ -119,6 +135,11 @@ class SiPixelGenError { int qbin(int id, float cotalpha, float cotbeta, float locBz, float locBx, float qclus, bool irradiationCorrections, int& pixmx, float& sigmay, float& deltay, float& sigmax, float& deltax, float& sy1, float& dy1, float& sy2, float& dy2, float& sx1, float& dx1, float& sx2, float& dx2); + +// Overload to provide backward compatibility + + int qbin(int id, float cotalpha, float cotbeta, float locBz, float locBx, float qclus, float& pixmx, float& sigmay, float& deltay, float& sigmax, float& deltax, + float& sy1, float& dy1, float& sy2, float& dy2, float& sx1, float& dx1, float& sx2, float& dx2); // Overloaded method to provide only the LA parameters int qbin(int id); diff --git a/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplate.h b/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplate.h index dd204c34b0909..f3d538e892c72 100755 --- a/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplate.h +++ b/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplate.h @@ -1,5 +1,5 @@ // -// SiPixelTemplate.h (v10.13) +// SiPixelTemplate.h (v10.20) // // Add goodness-of-fit info and spare entries to templates, version number in template header, more error checking // Add correction for (Q_F-Q_L)/(Q_F+Q_L) bias @@ -76,6 +76,8 @@ // V10.11 - Allow subdetector ID=5 for FPix R2P2 [allows better internal labeling of templates] // V10.12 - Enforce minimum signal size in pixel charge uncertainty calculation // V10.13 - Update the variable size [SI_PIXEL_TEMPLATE_USE_BOOST] option so that it works with VI's enhancements +// V10.20 - Add directory path selection to the ascii pushfile method + @@ -217,9 +219,9 @@ struct SiPixelTemplateStore { //!< template storage structure SiPixelTemplateEntry entx[5][29]; //!< 29 Barrel x templates spanning cluster lengths from -6px (-1.125Rad) to +6px (+1.125Rad) in each of 5 slices [3x29 for fpix] void destroy() {}; #else - float* cotbetaY=nullptr; - float* cotbetaX=nullptr; - float* cotalphaX=nullptr; + float* cotbetaY; + float* cotbetaX; + float* cotalphaX; boost::multi_array enty; //!< use 1d entry to store [60] barrel entries or [28] fpix entries boost::multi_array entx; //!< use 2d entry to store [5][29] barrel entries or [3][29] fpix entries void destroy() { // deletes arrays created by pushfile method of SiPixelTemplate @@ -254,8 +256,11 @@ class SiPixelTemplate { public: SiPixelTemplate(const std::vector< SiPixelTemplateStore > & thePixelTemp) : thePixelTemp_(thePixelTemp) { id_current_ = -1; index_id_ = -1; cota_current_ = 0.; cotb_current_ = 0.; } //!< Constructor for cases in which template store already exists - static bool pushfile(int filenum, std::vector< SiPixelTemplateStore > & thePixelTemp_); // load the private store with info from the - // file with the index (int) filenum + +// Load the private store with info from the file with the index (int) filenum from directory dir: +// ${dir}template_summary_zp${filenum}.out + static bool pushfile(int filenum, std::vector< SiPixelTemplateStore > & thePixelTemp_ , std::string dir = ""); + #ifndef SI_PIXEL_TEMPLATE_STANDALONE static bool pushfile(const SiPixelTemplateDBObject& dbobject, std::vector< SiPixelTemplateStore > & thePixelTemp_); // load the private store with info from db diff --git a/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplate2D.h b/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplate2D.h index 18c119f7b90f6..f1b67122fe49b 100644 --- a/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplate2D.h +++ b/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplate2D.h @@ -1,5 +1,5 @@ // -// SiPixelTemplate2D.h (v1.03) +// SiPixelTemplate2D.h (v2.35) // // Full 2-D templates for cluster splitting, simulated cluster reweighting, and improved cluster probability // @@ -7,7 +7,13 @@ // V1.01 - fix qavg_ filling // V1.02 - Add locBz to test if FPix use is out of range // V1.03 - Fix edge checking on final template to increase template size and to properly truncate cluster -// +// v2.00 - Major changes to accommodate 2D reconstruction +// v2.10 - Change chi2 and error scaling information to work with partially reconstructed clusters +// v2.20 - Add cluster charge probability information, side loading for template generation +// v2.21 - Double derivative interval [improves fit convergence] +// v2.25 - Resize template store to accommodate FPix Templates +// v2.30 - Fix bug found by P. Shuetze that compromises sqlite file loading +// v2.35 - Add directory path selection to the ascii pushfile method // // Build the template storage structure from several pieces @@ -15,15 +21,16 @@ #ifndef SiPixelTemplate2D_h #define SiPixelTemplate2D_h 1 -#include "RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateDefs.h" - #include #include #include "boost/multi_array.hpp" #ifndef SI_PIXEL_TEMPLATE_STANDALONE -#include "CondFormats/SiPixelObjects/interface/SiPixelTemplateDBObject.h" +#include "CondFormats/SiPixelObjects/interface/SiPixel2DTemplateDBObject.h" #include "FWCore/Utilities/interface/Exception.h" +#include "RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateDefs.h" +#else +#include "SiPixelTemplateDefs.h" #endif struct SiPixelTemplateEntry2D { //!< Basic template entry corresponding to a single set of track angles @@ -41,32 +48,49 @@ struct SiPixelTemplateEntry2D { //!< Basic template entry corresponding to a sin float xypar[2][5]; //!< pixel uncertainty parameterization float lanpar[2][5]; //!< pixel landau distribution parameters float xytemp[7][7][T2YSIZE][T2XSIZE]; //!< templates for y-reconstruction (binned over 1 central pixel) - float chi2avg[4]; //!< average chi^2 in 4 charge bins - float chi2min[4]; //!< minimum of chi^2 in 4 charge bins + float chi2ppix; //!< average chi^2 per pixel + float chi2scale; //!< scale factor for the chi2 distribution float chi2avgone; //!< average y chi^2 for 1 pixel clusters float chi2minone; //!< minimum of y chi^2 for 1 pixel clusters - float spare[20]; + float clsleny; //!< cluster y-length in pixels at signal height symax/2 + float clslenx; //!< cluster x-length in pixels at signal height sxmax/2 + float mpvvav; //!< most probable charge in Vavilov distribution (not actually for larger kappa) + float sigmavav; //!< "sigma" scale fctor for Vavilov distribution + float kappavav; //!< kappa parameter for Vavilov distribution + float scalexavg; //!< average x-error scale factor + float scaleyavg; //!< average y-error scale factor + float delyavg; //!< average length difference between template and cluster + float delysig; //!< rms of length difference between template and cluster + float scalex[4]; //!< x-error scale factor in 4 charge bins + float scaley[4]; //!< y-error scale factor in 4 charge bins + float offsetx[4]; //!< x-offset in 4 charge bins + float offsety[4]; //!< y-offset in 4 charge bins + float spare[3]; } ; struct SiPixelTemplateHeader2D { //!< template header structure - char title[80]; //!< template title int ID; //!< template ID number - int templ_version; //!< Version number of the template to ensure code compatibility - float Bfield; //!< Bfield in Tesla - int NTy; //!< number of Template y entries (= 0 for 2-D templates) + int NTy; //!< number of Template y entries int NTyx; //!< number of Template y-slices of x entries int NTxx; //!< number of Template x-entries in each slice int Dtype; //!< detector type (0=BPix, 1=FPix) + float qscale; //!< Charge scaling to match cmssw and pixelav + float lorywidth; //!< estimate of y-lorentz width for optimal resolution + float lorxwidth; //!< estimate of x-lorentz width for optimal resolution + float lorybias; //!< estimate of y-lorentz bias + float lorxbias; //!< estimate of x-lorentz bias float Vbias; //!< detector bias potential in Volts float temperature; //!< detector temperature in deg K float fluence; //!< radiation fluence in n_eq/cm^2 - float qscale; //!< Charge scaling to match cmssw and pixelav - float s50; //!< 1/2 of the readout threshold in ADC units - float lorywidth; //!< estimate of y-lorentz width from single pixel offset - float lorxwidth; //!< estimate of x-lorentz width from single pixel offset + float s50; //!< 1/2 of the multihit dcol threshold in electrons + float ss50; //!< 1/2 of the single hit dcol threshold in electrons + char title[80]; //!< template title + int templ_version; //!< Version number of the template to ensure code compatibility + float Bfield; //!< Bfield in Tesla + float fbin[3]; //!< The QBin definitions in Q_clus/Q_avg float xsize; //!< pixel size (for future use in upgraded geometry) float ysize; //!< pixel size (for future use in upgraded geometry) float zsize; //!< pixel size (for future use in upgraded geometry) @@ -76,7 +100,11 @@ struct SiPixelTemplateHeader2D { //!< template header structure struct SiPixelTemplateStore2D { //!< template storage structure SiPixelTemplateHeader2D head; - boost::multi_array entry; //!< use 2d entry to store [47][5] barrel entries or [5][9] fpix entries +#ifndef SI_PIXEL_TEMPLATE_USE_BOOST + SiPixelTemplateEntry2D entry[73][7]; //!< use 2d entry to store [47][5] barrel entries or [5][9] fpix +#else + boost::multi_array entry; //!< use 2d entry to store [47][5] barrel entries or [5][9] fpix entries +#endif } ; @@ -105,23 +133,35 @@ struct SiPixelTemplateStore2D { //!< template storage structure class SiPixelTemplate2D { public: SiPixelTemplate2D(const std::vector< SiPixelTemplateStore2D > & thePixelTemp) : thePixelTemp_(thePixelTemp) {id_current_ = -1; index_id_ = -1; cota_current_ = 0.; cotb_current_ = 0.;} //!< Default constructor - static bool pushfile(int filenum, std::vector< SiPixelTemplateStore2D > & thePixelTemp_); // load the private store with info from the - // file with the index (int) filenum + +// load the private store with info from the + // file with the index (int) filenum ${dir}template_summary_zp${filenum}.out + static bool pushfile(int filenum, std::vector< SiPixelTemplateStore2D > & thePixelTemp_, std::string dir = ""); #ifndef SI_PIXEL_TEMPLATE_STANDALONE - static bool pushfile(const SiPixelTemplateDBObject& dbobject, std::vector< SiPixelTemplateStore2D > & thePixelTemp_); // load the private store with info from db + static bool pushfile(const SiPixel2DTemplateDBObject& dbobject, std::vector< SiPixelTemplateStore2D > & thePixelTemp_); // load the private store with info from db #endif + // Initialize things before interpolating + + void sideload(SiPixelTemplateEntry2D* entry, int iDtype, float locBx, float locBz, float lorwdy, float lorwdx, float q50, float fbin[3], float xsize, float ysize, float zsize); + + // Initialize things before interpolating + + bool interpolate(int id, float cotalpha, float cotbeta, float locBz, float locBx); // Interpolate input alpha and beta angles to produce a working template for each individual hit. - bool xytemp(int id, float cotalpha, float cotbeta, float locBz, float xhit, float yhit, std::vector& ydouble, std::vector& xdouble, float template2d[BXM2][BYM2]); + // Works with Phase 0+1 + bool xytemp(float xhit, float yhit, bool ydouble[BYM2], bool xdouble[BXM2], float template2d[BXM2][BYM2], bool dervatives, float dpdx2d[2][BXM2][BYM2], float& QTemplate); - // Overload to allow user to avoid the locBz information + // Overload for backward compatibility - bool xytemp(int id, float cotalpha, float cotbeta, float xhit, float yhit, std::vector& ydouble, std::vector& xdouble, float template2d[BXM2][BYM2]); + bool xytemp(float xhit, float yhit, bool ydouble[BYM2], bool xdouble[BXM2], float template2d[BXM2][BYM2]); - // Get pixel signal uncertainties + // Overload for backward compatibility with re-weighting code + + bool xytemp(int id, float cotalpha, float cotbeta, float xhit, float yhit, std::vector& ydouble, std::vector& xdouble, float template2d[BXM2][BYM2]); void xysigma2(float qpixel, int index, float& xysig2); @@ -134,35 +174,62 @@ class SiPixelTemplate2D { float qscale() {return qscale_;} //!< charge scaling factor float s50() {return s50_;} //!< 1/2 of the pixel threshold signal in adc units float sxymax() {return sxymax_;} //!< max pixel signal for pixel error calculation - float xytemp(int j, int i) { //!< get the 2-d template for pixel j (x), i (y) in BXM2 x BYM2 array (x,y)=(0,0) in lower LH corner of pixel[1][1] + float scalex(int i) { #ifndef SI_PIXEL_TEMPLATE_STANDALONE - if(j < 0 || j > BXM3 || i < 0 || i > BYM3) {throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::xytemp called with illegal indices = " << j << "," << i << std::endl;} + if(i < 0 || i > 3) {throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::scalex called with illegal index = " << i << std::endl;} #else - assert((j>=0 && j=0 && i=0 && i<4); #endif - return xytemp_[j][i];} //!< current 2-d template - float chi2avg(int i) { + return scalex_[i];} //!< x-error scale factor in 4 charge bins + float scaley(int i) { #ifndef SI_PIXEL_TEMPLATE_STANDALONE - if(i < 0 || i > 3) {throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::chi2yavg called with illegal index = " << i << std::endl;} + if(i < 0 || i > 3) {throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::scaley called with illegal index = " << i << std::endl;} #else assert(i>=0 && i<4); #endif - return chi2avg_[i];} //!< average chi^2 in 4 charge bins - float chi2min(int i) { + return scaley_[i];} //! 3) {throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::chi2ymin called with illegal index = " << i << std::endl;} + if(i < 0 || i > 3) {throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::scaley called with illegal index = " << i << std::endl;} #else assert(i>=0 && i<4); #endif - return chi2min_[i];} //!< minimum chi^2 in 4 charge bins - float chi2avgone() {return chi2avgone_;} //!< //!< average y chi^2 for 1 pixel clusters - float chi2minone() {return chi2minone_;} //!< //!< minimum of y chi^2 for 1 pixel clusters - float lorywidth() {return lorywidth_;} //!< signed lorentz y-width (microns) - float lorxwidth() {return lorxwidth_;} //!< signed lorentz x-width (microns) + return offsetx_[i];} //!< x-offset in 4 charge bins + float offsety(int i) { +#ifndef SI_PIXEL_TEMPLATE_STANDALONE + if(i < 0 || i > 3) {throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::scaley called with illegal index = " << i << std::endl;} +#else + assert(i>=0 && i<4); +#endif + return offsety_[i];} //!< x-offset in 4 charge bins + float fbin(int i) { +#ifndef SI_PIXEL_TEMPLATE_STANDALONE + if(i < 0 || i > 2) {throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::fbin called with illegal index = " << i << std::endl;} +#else + assert(i>=0 && i<3); +#endif + return fbin_[i];} //!< Return lower bound of Qbin definition + float sizex() {return clslenx_;} //!< return x size of template cluster + float sizey() {return clsleny_;} //!< return y size of template cluster + float chi2ppix() {return chi2ppix_;} //!< average chi^2 per struck pixel + float chi2scale() {return chi2scale_;} //!< scale factor for chi^2 distribution + float chi2avgone() {return chi2avgone_;} //!< average y chi^2 for 1 pixel clusters + float chi2minone() {return chi2minone_;} //!< minimum of y chi^2 for 1 pixel clusters + float mpvvav() {return mpvvav_;} //!< most probable Q in Vavilov distribution + float sigmavav() {return sigmavav_;} //!< scale factor in Vavilov distribution + float kappavav() {return kappavav_;} //!< kappa parameter in Vavilov distribution + float lorydrift() {return lorydrift_;} //!< signed lorentz y-width (microns) + float lorxdrift() {return lorxdrift_;} //!< signed lorentz x-width (microns) + float clsleny() {return clsleny_;} //!< cluster y-size + float clslenx() {return clslenx_;} //!< cluster x-size + float scaleyavg() {return scaleyavg_;} //!< y-reco error scaling factor + float scalexavg() {return scalexavg_;} //!< x-reco error scaling factor + float delyavg() {return delyavg_;} //!< average difference between clsleny_ and cluster length [with threshold effects] + float delysig() {return delysig_;} //!< rms difference between clsleny_ and cluster length [with threshold effects] float xsize() {return xsize_;} //!< pixel x-size (microns) float ysize() {return ysize_;} //!< pixel y-size (microns) float zsize() {return zsize_;} //!< pixel z-size or thickness (microns) - int storesize() {return (int)thePixelTemp_.size();} //!< return the size of the template store (the number of stored IDs + int storesize() {return (int)thePixelTemp_.size();} //!< return the size of the template store (the number of stored IDs private: @@ -187,6 +254,12 @@ class SiPixelTemplate2D { int jx0_; //!< index of nearest cot(alpha) bin int jx1_; //!< index of next-nearest cot(alpha) bin float adcota_; //!< fractional pixel distance of cot(alpha) from jx0_ + int imin_; //!< min y index of templated cluster + int imax_; //!< max y index of templated cluster + int jmin_; //!< min x index of templated cluster + int jmax_; //!< max x index of templated cluster + bool flip_y_; //!< flip y sign-sensitive quantities + bool flip_x_; //!< flip x sign-sensitive quantities bool success_; //!< true if cotalpha, cotbeta are inside of the acceptance (dynamically loaded) @@ -197,24 +270,44 @@ class SiPixelTemplate2D { float qscale_; //!< charge scaling factor float s50_; //!< 1/2 of the pixel threshold signal in adc units float sxymax_; //!< average pixel signal for y-projection of cluster - float xytemp_[BXM2][BYM2];//!< templates for y-reconstruction (binned over 5 central pixels) + float xytemp_[BXM2][BYM2];//!< template for xy-reconstruction float xypary0x0_[2][5]; //!< Polynomial error parameterization at ix0,iy0 float xypary1x0_[2][5]; //!< Polynomial error parameterization at ix0,iy1 float xypary0x1_[2][5]; //!< Polynomial error parameterization at ix1,iy0 float lanpar_[2][5]; //!< Interpolated Landau parameters - float chi2avg_[4]; //!< average chi^2 in 4 charge bins - float chi2min_[4]; //!< minimum of chi^2 in 4 charge bins - float chi2avgone_; //!< average chi^2 for 1 pixel clusters - float chi2minone_; //!< minimum of chi^2 for 1 pixel clusters + float chi2ppix_; //!< average chi^2 per struck pixel + float chi2scale_; //!< scale factor for chi2 distribution + float chi2avgone_; //!< average chi^2 for 1 pixel clusters + float chi2minone_; //!< minimum of chi^2 for 1 pixel clusters + float clsleny_; //!< projected y-length of cluster + float clslenx_; //!< projected x-length of cluster + float scalexavg_; //!< average x-error scale factor + float scaleyavg_; //!< average y-error scale factor + float delyavg_; //!< average difference between clsleny_ and cluster length [with threshold effects] + float delysig_; //!< rms of difference between clsleny_ and cluster length [with threshold effects] + float scalex_[4]; //!< x-error scale factor in charge bins + float scaley_[4]; //!< y-error scale factor in charge bins + float offsetx_[4]; //!< x-offset in charge bins + float offsety_[4]; //!< y-offset in charge bins + float mpvvav_; //!< most probable Q in Vavilov distribution + float sigmavav_; //!< scale factor in Vavilov distribution + float kappavav_; //!< kappa parameter in Vavilov distribution float lorywidth_; //!< Lorentz y-width (sign corrected for fpix frame) float lorxwidth_; //!< Lorentz x-width + float lorydrift_; //!< Lorentz y-drift + float lorxdrift_; //!< Lorentz x-drift float xsize_; //!< Pixel x-size float ysize_; //!< Pixel y-size float zsize_; //!< Pixel z-size (thickness) + float fbin_[3]; //!< The QBin definitions in Q_clus/Q_avg + const SiPixelTemplateEntry2D* entry00_; // Pointer to presently interpolated point + const SiPixelTemplateEntry2D* entry10_; // Pointer to presently interpolated point [iy+1] + const SiPixelTemplateEntry2D* entry01_; // Pointer to presently interpolated point [ix+1] // The actual template store is a std::vector container const std::vector< SiPixelTemplateStore2D > & thePixelTemp_; + } ; diff --git a/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateDefs.h b/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateDefs.h index 4e38b80efb5c6..2ff244ac0519c 100644 --- a/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateDefs.h +++ b/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateDefs.h @@ -1,9 +1,11 @@ // -// SiPixelTemplateDefs.h (v1.10) +// SiPixelTemplateDefs.h (v2.00) // // Created by Morris Swartz on 12/01/09. // 2009 __TheJohnsHopkinsUniversity__. // +// V2.00 - Resize the 2D objects to improve angle acceptance +// // // Define template buffer size parameters @@ -33,9 +35,10 @@ #define BXM1 TXSIZE+3 #define BXM2 TXSIZE+2 #define BXM3 TXSIZE+1 -#define T2YSIZE 13 +#define T2YSIZE 21 #define T2XSIZE 7 -#define T2HY 6 // = T2YSIZE/2 +#define T2HY 10 // = T2YSIZE/2 +#define T2HYP1 T2HY+1 // = T2YSIZE/2+1 #define T2HX 3 // = T2XSIZE/2 #endif diff --git a/RecoLocalTracker/SiPixelRecHits/plugins/PixelCPEGenericESProducer.cc b/RecoLocalTracker/SiPixelRecHits/plugins/PixelCPEGenericESProducer.cc index 76cb0cab2e302..f5dfeab62a735 100644 --- a/RecoLocalTracker/SiPixelRecHits/plugins/PixelCPEGenericESProducer.cc +++ b/RecoLocalTracker/SiPixelRecHits/plugins/PixelCPEGenericESProducer.cc @@ -45,7 +45,7 @@ PixelCPEGenericESProducer::PixelCPEGenericESProducer(const edm::ParameterSet & p PixelCPEGenericESProducer::~PixelCPEGenericESProducer() {} -std::unique_ptr +std::shared_ptr PixelCPEGenericESProducer::produce(const TkPixelCPERecord & iRecord){ ESHandle magfield; @@ -83,11 +83,12 @@ PixelCPEGenericESProducer::produce(const TkPixelCPERecord & iRecord){ //} else { //std::cout<<" pass an empty GenError pointer"<( + cpe_ = std::make_shared( pset_,magfield.product(),*pDD.product(), *hTT.product(),lorentzAngle.product(), genErrorDBObjectProduct,lorentzAngleWidthProduct); + return cpe_; } diff --git a/RecoLocalTracker/SiPixelRecHits/plugins/PixelCPETemplateRecoESProducer.cc b/RecoLocalTracker/SiPixelRecHits/plugins/PixelCPETemplateRecoESProducer.cc index 3bc2e3ff4bf57..8877d7459c3be 100644 --- a/RecoLocalTracker/SiPixelRecHits/plugins/PixelCPETemplateRecoESProducer.cc +++ b/RecoLocalTracker/SiPixelRecHits/plugins/PixelCPETemplateRecoESProducer.cc @@ -35,7 +35,7 @@ PixelCPETemplateRecoESProducer::PixelCPETemplateRecoESProducer(const edm::Parame PixelCPETemplateRecoESProducer::~PixelCPETemplateRecoESProducer() {} -std::unique_ptr +std::shared_ptr PixelCPETemplateRecoESProducer::produce(const TkPixelCPERecord & iRecord){ ESHandle magfield; @@ -60,7 +60,9 @@ PixelCPETemplateRecoESProducer::produce(const TkPixelCPERecord & iRecord){ ESHandle templateDBobject; iRecord.getRecord().get(templateDBobject); - return std::make_unique(pset_,magfield.product(),*pDD.product(),*hTT.product(),lorentzAngleProduct,templateDBobject.product() ); + // cpe_ = std::make_shared(pset_,magfield.product(),lorentzAngle.product(),templateDBobject.product() ); + cpe_ = std::make_shared(pset_,magfield.product(),*pDD.product(),*hTT.product(),lorentzAngleProduct,templateDBobject.product() ); + return cpe_; } diff --git a/RecoLocalTracker/SiPixelRecHits/src/PixelCPEBase.cc b/RecoLocalTracker/SiPixelRecHits/src/PixelCPEBase.cc index d16c61b116ff1..81516d1ff0ee5 100644 --- a/RecoLocalTracker/SiPixelRecHits/src/PixelCPEBase.cc +++ b/RecoLocalTracker/SiPixelRecHits/src/PixelCPEBase.cc @@ -239,9 +239,24 @@ PixelCPEBase::setTheClu( DetParam const & theDetParam, ClusterParam & theCluster minInY = theClusterParam.theCluster->minPixelCol(); maxInX = theClusterParam.theCluster->maxPixelRow(); maxInY = theClusterParam.theCluster->maxPixelCol(); - - theClusterParam.isOnEdge_ = theDetParam.theRecTopol->isItEdgePixelInX(minInX) | theDetParam.theRecTopol->isItEdgePixelInX(maxInX) | - theDetParam.theRecTopol->isItEdgePixelInY(minInY) | theDetParam.theRecTopol->isItEdgePixelInY(maxInY) ; + + if ( theDetParam.theRecTopol->isItEdgePixelInX(minInX) ) + theClusterParam.edgeTypeX_ = 1; + else if ( theDetParam.theRecTopol->isItEdgePixelInX(maxInX) ) + theClusterParam.edgeTypeX_ = 2; + else + theClusterParam.edgeTypeX_ = 0; + + if ( theDetParam.theRecTopol->isItEdgePixelInY(minInY) ) + theClusterParam.edgeTypeY_ = 1; + else if ( theDetParam.theRecTopol->isItEdgePixelInY(maxInY) ) + theClusterParam.edgeTypeY_ = 2; + else + theClusterParam.edgeTypeY_ = 0; + + theClusterParam.isOnEdge_ = ( theClusterParam.edgeTypeX_ || theClusterParam.edgeTypeY_ ); + // theClusterParam.isOnEdge_ = theDetParam.theRecTopol->isItEdgePixelInX(minInX) | theDetParam.theRecTopol->isItEdgePixelInX(maxInX) | + // theDetParam.theRecTopol->isItEdgePixelInY(minInY) | theDetParam.theRecTopol->isItEdgePixelInY(maxInY) ; // FOR NOW UNUSED. KEEP IT IN CASE WE WANT TO USE IT IN THE FUTURE // Bad Pixels have their charge set to 0 in the clusterizer diff --git a/RecoLocalTracker/SiPixelRecHits/src/PixelCPETemplateReco.cc b/RecoLocalTracker/SiPixelRecHits/src/PixelCPETemplateReco.cc index f502d6b6f29ab..8e84a413390d7 100644 --- a/RecoLocalTracker/SiPixelRecHits/src/PixelCPETemplateReco.cc +++ b/RecoLocalTracker/SiPixelRecHits/src/PixelCPETemplateReco.cc @@ -73,15 +73,18 @@ PixelCPETemplateReco::PixelCPETemplateReco(edm::ParameterSet const & conf, } else { - //cout << "PixelCPETemplateReco : Loading templates 40 and 41 from ASCII files ------------------------" << endl; - - if ( !SiPixelTemplate::pushfile( 40, thePixelTemp_ ) ) + //cout << "PixelCPETemplateReco : Loading templates for barrel and forward from ASCII files ----------" << endl; + barrelTemplateID_ = conf.getParameter( "barrelTemplateID" ); + forwardTemplateID_ = conf.getParameter( "forwardTemplateID" ); + templateDir_ = conf.getParameter( "directoryWithTemplates" ); + + if ( !SiPixelTemplate::pushfile( barrelTemplateID_ , thePixelTemp_ , templateDir_ ) ) throw cms::Exception("PixelCPETemplateReco") - << "\nERROR: Templates 40 not loaded correctly from text file. Reconstruction will fail.\n\n"; + << "\nERROR: Template ID " << barrelTemplateID_ << " not loaded correctly from text file. Reconstruction will fail.\n\n"; - if ( !SiPixelTemplate::pushfile( 41, thePixelTemp_ ) ) + if ( !SiPixelTemplate::pushfile( forwardTemplateID_ , thePixelTemp_ , templateDir_ ) ) throw cms::Exception("PixelCPETemplateReco") - << "\nERROR: Templates 41 not loaded correctly from text file. Reconstruction will fail.\n\n"; + << "\nERROR: Template ID " << forwardTemplateID_ << " not loaded correctly from text file. Reconstruction will fail.\n\n"; } speed_ = conf.getParameter( "speed"); @@ -131,8 +134,10 @@ PixelCPETemplateReco::localPosition(DetParam const & theDetParam, ClusterParam & ID = theDetParam.detTemplateId; if(ID0!=ID) cout<<" different id"<< ID<<" "< // next, layout the 1-d/2-d structures needed to store GenError info + + theCurrentTemp.cotbetaY = new float[theCurrentTemp.head.NTy]; + theCurrentTemp.cotbetaX = new float[theCurrentTemp.head.NTyx]; + theCurrentTemp.cotalphaX = new float[theCurrentTemp.head.NTxx]; + theCurrentTemp.enty.resize(boost::extents[theCurrentTemp.head.NTy]); theCurrentTemp.entx.resize(boost::extents[theCurrentTemp.head.NTyx][theCurrentTemp.head.NTxx]); @@ -308,6 +319,11 @@ bool SiPixelGenError::pushfile(const SiPixelGenErrorDBObject& dbobject, // next, layout the 1-d/2-d structures needed to store GenError + + theCurrentTemp.cotbetaY = new float[theCurrentTemp.head.NTy]; + theCurrentTemp.cotbetaX = new float[theCurrentTemp.head.NTyx]; + theCurrentTemp.cotalphaX = new float[theCurrentTemp.head.NTxx]; + theCurrentTemp.enty.resize(boost::extents[theCurrentTemp.head.NTy]); theCurrentTemp.entx.resize(boost::extents[theCurrentTemp.head.NTyx][theCurrentTemp.head.NTxx]); @@ -543,6 +559,7 @@ int SiPixelGenError::qbin(int id, float cotalpha, float cotbeta, float locBz, fl case 2: case 3: case 4: + case 5: if(locBx*locBz < 0.f) { cota = -cotalpha; flip_x = true; @@ -556,9 +573,9 @@ int SiPixelGenError::qbin(int id, float cotalpha, float cotbeta, float locBz, fl break; default: #ifndef SI_PIXEL_TEMPLATE_STANDALONE - throw cms::Exception("DataCorrupt") << "SiPixelTemplate::illegal subdetector ID = " << thePixelTemp_[index_id_].head.Dtype << std::endl; + throw cms::Exception("DataCorrupt") << "SiPixelGenError::illegal subdetector ID = " << thePixelTemp_[index_id_].head.Dtype << std::endl; #else - std::cout << "SiPixelTemplate::illegal subdetector ID = " << thePixelTemp_[index_id_].head.Dtype << std::endl; + std::cout << "SiPixelGenError::illegal subdetector ID = " << thePixelTemp_[index_id_].head.Dtype << std::endl; #endif } @@ -657,8 +674,7 @@ int SiPixelGenError::qbin(int id, float cotalpha, float cotbeta, float locBz, fl auto yrmsgen =(1.f - yratio)*thePixelTemp_[index].enty[ilow].yrmsgen[binq] + yratio*thePixelTemp_[index].enty[ihigh].yrmsgen[binq]; sy1 = (1.f - yratio)*thePixelTemp_[index].enty[ilow].syone + yratio*thePixelTemp_[index].enty[ihigh].syone; - sy2 = (1.f - yratio)*thePixelTemp_[index].enty[ilow].sytwo + yratio*thePixelTemp_[index].enty[ihigh].sytwo; - + sy2 = (1.f - yratio)*thePixelTemp_[index].enty[ilow].sytwo + yratio*thePixelTemp_[index].enty[ihigh].sytwo; // next, loop over all x-angle entries, first, find relevant y-slices @@ -738,3 +754,22 @@ int SiPixelGenError::qbin(int id, float cotalpha, float cotbeta, float locBz, fl return binq; } // qbin + +int SiPixelGenError::qbin(int id, float cotalpha, float cotbeta, float locBz, float locBx, float qclus, + float& pixmx, float& sigmay, float& deltay, float& sigmax, float& deltax, + float& sy1, float& dy1, float& sy2, float& dy2, float& sx1, float& dx1, + float& sx2, float& dx2) +{ + // Interpolate for a new set of track angles + + bool irradiationCorrections = true; + int ipixmx, ibin; + + ibin = SiPixelGenError::qbin(id, cotalpha, cotbeta, locBz, locBx, qclus, irradiationCorrections, + ipixmx, sigmay, deltay, sigmax, deltax, sy1, dy1, sy2, dy2, sx1, dx1, sx2, dx2); + + pixmx = (float)ipixmx; + + return ibin; + +} diff --git a/RecoLocalTracker/SiPixelRecHits/src/SiPixelTemplate.cc b/RecoLocalTracker/SiPixelRecHits/src/SiPixelTemplate.cc index 9eb3853c0ad68..0093487ae22a8 100755 --- a/RecoLocalTracker/SiPixelRecHits/src/SiPixelTemplate.cc +++ b/RecoLocalTracker/SiPixelRecHits/src/SiPixelTemplate.cc @@ -1,5 +1,5 @@ // -// SiPixelTemplate.cc Version 10.13 +// SiPixelTemplate.cc Version 10.20 // // Add goodness-of-fit info and spare entries to templates, version number in template header, more error checking // Add correction for (Q_F-Q_L)/(Q_F+Q_L) bias @@ -78,6 +78,7 @@ // V10.11 - Allow subdetector ID=5 for FPix R2P2 [allows better internal labeling of templates] // V10.12 - Enforce minimum signal size in pixel charge uncertainty calculation // V10.13 - Update the variable size [SI_PIXEL_TEMPLATE_USE_BOOST] option so that it works with VI's enhancements +// V10.20 - Add directory path selection to the ascii pushfile method @@ -126,7 +127,7 @@ using namespace edm; //! digits of filenum. //! \param filenum - an integer NNNN used in the filename template_summary_zpNNNN //**************************************************************** -bool SiPixelTemplate::pushfile(int filenum, std::vector< SiPixelTemplateStore > & thePixelTemp_) +bool SiPixelTemplate::pushfile(int filenum, std::vector< SiPixelTemplateStore > & thePixelTemp_ , std::string dir) { // Add template stored in external file numbered filenum to theTemplateStore @@ -147,8 +148,8 @@ bool SiPixelTemplate::pushfile(int filenum, std::vector< SiPixelTemplateStore > // Create different path in CMSSW than standalone #ifndef SI_PIXEL_TEMPLATE_STANDALONE - tout << "CalibTracker/SiPixelESProducers/data/template_summary_zp" - << std::setw(4) << std::setfill('0') << std::right << filenum << ".out" << std::ends; + tout << dir << "template_summary_zp" + << std::setw(4) << std::setfill('0') << std::right << filenum << ".out" << std::ends; std::string tempf = tout.str(); edm::FileInPath file( tempf.c_str() ); tempfile = (file.fullPath()).c_str(); @@ -2573,6 +2574,7 @@ int SiPixelTemplate::qbin(int id, float cotalpha, float cotbeta, float locBz, fl + ilow = ihigh = 0; auto xxratio = 0.f; { diff --git a/RecoLocalTracker/SiPixelRecHits/src/SiPixelTemplate2D.cc b/RecoLocalTracker/SiPixelRecHits/src/SiPixelTemplate2D.cc index dee2e5ead57aa..ec439219439f9 100644 --- a/RecoLocalTracker/SiPixelRecHits/src/SiPixelTemplate2D.cc +++ b/RecoLocalTracker/SiPixelRecHits/src/SiPixelTemplate2D.cc @@ -1,801 +1,1498 @@ -// -// SiPixelTemplate2D.cc Version 1.03 -// -// Full 2-D templates for cluster splitting, simulated cluster reweighting, and improved cluster probability -// -// Created by Morris Swartz on 12/01/09. -// 2009 __TheJohnsHopkinsUniversity__. -// -// V1.01 - fix qavg_ filling -// V1.02 - Add locBz to test if FPix use is out of range -// V1.03 - Fix edge checking on final template to increase template size and to properly truncate cluster -// - -//#include -//#include -#ifndef SI_PIXEL_TEMPLATE_STANDALONE -//#include -#else -#include -#endif -#include -#include -//#include "boost/multi_array.hpp" -#include -#include -#include -#include - - -#ifndef SI_PIXEL_TEMPLATE_STANDALONE -#include "RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplate2D.h" -#include "FWCore/ParameterSet/interface/FileInPath.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#define LOGERROR(x) LogError(x) -#define LOGINFO(x) LogInfo(x) -#define ENDL " " -#include "FWCore/Utilities/interface/Exception.h" -using namespace edm; -#else -#include "SiPixelTemplate2D.h" -#define LOGERROR(x) std::cout << x << ": " -#define LOGINFO(x) std::cout << x << ": " -#define ENDL std::endl -#endif - -//**************************************************************** -//! This routine initializes the global template structures from -//! an external file template_summary_zpNNNN where NNNN are four -//! digits of filenum. -//! \param filenum - an integer NNNN used in the filename template_summary_zpNNNN -//**************************************************************** -bool SiPixelTemplate2D::pushfile(int filenum, std::vector< SiPixelTemplateStore2D > & thePixelTemp_) -{ - // Add template stored in external file numbered filenum to theTemplateStore - - // Local variables - int i, j, k, l, iy, jx; - const char *tempfile; - // char title[80]; remove this - char c; - const int code_version={16}; - - - - // Create a filename for this run - - std::ostringstream tout; - - // Create different path in CMSSW than standalone - -#ifndef SI_PIXEL_TEMPLATE_STANDALONE - tout << "CalibTracker/SiPixelESProducers/data/template_summary2D_zp" - << std::setw(4) << std::setfill('0') << std::right << filenum << ".out" << std::ends; - std::string tempf = tout.str(); - edm::FileInPath file( tempf.c_str() ); - tempfile = (file.fullPath()).c_str(); -#else - tout << "template_summary2D_zp" << std::setw(4) << std::setfill('0') << std::right << filenum << ".out" << std::ends; - std::string tempf = tout.str(); - tempfile = tempf.c_str(); -#endif - - // open the template file - - std::ifstream in_file(tempfile, std::ios::in); - - if(in_file.is_open()) { - - // Create a local template storage entry - - SiPixelTemplateStore2D theCurrentTemp; - - // Read-in a header string first and print it - - for (i=0; (c=in_file.get()) != '\n'; ++i) { - if(i < 79) {theCurrentTemp.head.title[i] = c;} - } - if(i > 78) {i=78;} - theCurrentTemp.head.title[i+1] ='\0'; - LOGINFO("SiPixelTemplate2D") << "Loading Pixel Template File - " << theCurrentTemp.head.title << ENDL; - - // next, the header information - - in_file >> theCurrentTemp.head.ID >> theCurrentTemp.head.templ_version >> theCurrentTemp.head.Bfield >> theCurrentTemp.head.NTy >> theCurrentTemp.head.NTyx >> theCurrentTemp.head.NTxx - >> theCurrentTemp.head.Dtype >> theCurrentTemp.head.Vbias >> theCurrentTemp.head.temperature >> theCurrentTemp.head.fluence >> theCurrentTemp.head.qscale - >> theCurrentTemp.head.s50 >> theCurrentTemp.head.lorywidth >> theCurrentTemp.head.lorxwidth >> theCurrentTemp.head.ysize >> theCurrentTemp.head.xsize >> theCurrentTemp.head.zsize; - - if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file, no template load" << ENDL; return false;} - - LOGINFO("SiPixelTemplate2D") << "Template ID = " << theCurrentTemp.head.ID << ", Template Version " << theCurrentTemp.head.templ_version << ", Bfield = " << theCurrentTemp.head.Bfield - << ", NTy = " << theCurrentTemp.head.NTy << ", NTyx = " << theCurrentTemp.head.NTyx<< ", NTxx = " << theCurrentTemp.head.NTxx << ", Dtype = " << theCurrentTemp.head.Dtype - << ", Bias voltage " << theCurrentTemp.head.Vbias << ", temperature " - << theCurrentTemp.head.temperature << ", fluence " << theCurrentTemp.head.fluence << ", Q-scaling factor " << theCurrentTemp.head.qscale - << ", 1/2 threshold " << theCurrentTemp.head.s50 << ", y Lorentz Width " << theCurrentTemp.head.lorywidth << ", x Lorentz width " << theCurrentTemp.head.lorxwidth - << ", pixel x-size " << theCurrentTemp.head.xsize << ", y-size " << theCurrentTemp.head.ysize << ", zsize " << theCurrentTemp.head.zsize << ENDL; - - if(theCurrentTemp.head.templ_version != code_version) {LOGERROR("SiPixelTemplate2D") << "code expects version " << code_version << ", no template load" << ENDL; return false;} - - if(theCurrentTemp.head.NTy != 0) {LOGERROR("SiPixelTemplate2D") << "Trying to load 1-d template info into the 2-d template object, check your DB/global tag!" << ENDL; return false;} - - // next, layout the 2-d structure needed to store template - - theCurrentTemp.entry.resize(boost::extents[theCurrentTemp.head.NTyx][theCurrentTemp.head.NTxx]); - - // Read in the file info - - for (iy=0; iy < theCurrentTemp.head.NTyx; ++iy) { - for(jx=0; jx < theCurrentTemp.head.NTxx; ++jx) { - - in_file >> theCurrentTemp.entry[iy][jx].runnum >> theCurrentTemp.entry[iy][jx].costrk[0] - >> theCurrentTemp.entry[iy][jx].costrk[1] >> theCurrentTemp.entry[iy][jx].costrk[2]; - - if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 1, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - // Calculate cot(alpha) and cot(beta) for this entry - - theCurrentTemp.entry[iy][jx].cotalpha = theCurrentTemp.entry[iy][jx].costrk[0]/theCurrentTemp.entry[iy][jx].costrk[2]; - - theCurrentTemp.entry[iy][jx].cotbeta = theCurrentTemp.entry[iy][jx].costrk[1]/theCurrentTemp.entry[iy][jx].costrk[2]; - - in_file >> theCurrentTemp.entry[iy][jx].qavg >> theCurrentTemp.entry[iy][jx].pixmax >> theCurrentTemp.entry[iy][jx].sxymax >> theCurrentTemp.entry[iy][jx].iymin - >> theCurrentTemp.entry[iy][jx].iymax >> theCurrentTemp.entry[iy][jx].jxmin >> theCurrentTemp.entry[iy][jx].jxmax; - - if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 2, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - for (k=0; k<2; ++k) { - - in_file >> theCurrentTemp.entry[iy][jx].xypar[k][0] >> theCurrentTemp.entry[iy][jx].xypar[k][1] - >> theCurrentTemp.entry[iy][jx].xypar[k][2] >> theCurrentTemp.entry[iy][jx].xypar[k][3] >> theCurrentTemp.entry[iy][jx].xypar[k][4]; - - if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 3, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - } - - for (k=0; k<2; ++k) { - - in_file >> theCurrentTemp.entry[iy][jx].lanpar[k][0] >> theCurrentTemp.entry[iy][jx].lanpar[k][1] - >> theCurrentTemp.entry[iy][jx].lanpar[k][2] >> theCurrentTemp.entry[iy][jx].lanpar[k][3] >> theCurrentTemp.entry[iy][jx].lanpar[k][4]; - - if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 4, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - } - - for (l=0; l<7; ++l) { - for (k=0; k<7; ++k) { - for (j=0; j> theCurrentTemp.entry[iy][jx].xytemp[k][l][i][j];} - - if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 5, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - } - } - } - - - in_file >> theCurrentTemp.entry[iy][jx].chi2minone >> theCurrentTemp.entry[iy][jx].chi2avgone >> theCurrentTemp.entry[iy][jx].chi2min[0] >> theCurrentTemp.entry[iy][jx].chi2avg[0] - >> theCurrentTemp.entry[iy][jx].chi2min[1] >> theCurrentTemp.entry[iy][jx].chi2avg[1]>> theCurrentTemp.entry[iy][jx].chi2min[2] >> theCurrentTemp.entry[iy][jx].chi2avg[2] - >> theCurrentTemp.entry[iy][jx].chi2min[3] >> theCurrentTemp.entry[iy][jx].chi2avg[3]; - - if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 6, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - in_file >> theCurrentTemp.entry[iy][jx].spare[0] >> theCurrentTemp.entry[iy][jx].spare[1] >> theCurrentTemp.entry[iy][jx].spare[2] >> theCurrentTemp.entry[iy][jx].spare[3] - >> theCurrentTemp.entry[iy][jx].spare[4] >> theCurrentTemp.entry[iy][jx].spare[5] >> theCurrentTemp.entry[iy][jx].spare[6] >> theCurrentTemp.entry[iy][jx].spare[7] - >> theCurrentTemp.entry[iy][jx].spare[8] >> theCurrentTemp.entry[iy][jx].spare[9]; - - if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 7, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - in_file >> theCurrentTemp.entry[iy][jx].spare[10] >> theCurrentTemp.entry[iy][jx].spare[11] >> theCurrentTemp.entry[iy][jx].spare[12] >> theCurrentTemp.entry[iy][jx].spare[13] - >> theCurrentTemp.entry[iy][jx].spare[14] >> theCurrentTemp.entry[iy][jx].spare[15] >> theCurrentTemp.entry[iy][jx].spare[16] >> theCurrentTemp.entry[iy][jx].spare[17] - >> theCurrentTemp.entry[iy][jx].spare[18] >> theCurrentTemp.entry[iy][jx].spare[19]; - - if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 8, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - } - - } - - - in_file.close(); - - // Add this template to the store - - thePixelTemp_.push_back(theCurrentTemp); - - return true; - - } else { - - // If file didn't open, report this - - LOGERROR("SiPixelTemplate2D") << "Error opening File" << tempfile << ENDL; - return false; - - } - -} // TempInit - - -#ifndef SI_PIXEL_TEMPLATE_STANDALONE - -//**************************************************************** -//! This routine initializes the global template structures from an -//! external file template_summary_zpNNNN where NNNN are four digits -//! \param dbobject - db storing multiple template calibrations -//**************************************************************** -bool SiPixelTemplate2D::pushfile(const SiPixelTemplateDBObject& dbobject, std::vector< SiPixelTemplateStore2D > & thePixelTemp_) -{ - // Add template stored in external dbobject to theTemplateStore - - // Local variables - int i, j, k, l, iy, jx; - // const char *tempfile; - const int code_version={16}; - - // We must create a new object because dbobject must be a const and our stream must not be - SiPixelTemplateDBObject db = dbobject; - - // Create a local template storage entry - SiPixelTemplateStore2D theCurrentTemp; - - // Fill the template storage for each template calibration stored in the db - for(int m=0; m> theCurrentTemp.head.ID >> theCurrentTemp.head.templ_version >> theCurrentTemp.head.Bfield >> theCurrentTemp.head.NTy >> theCurrentTemp.head.NTyx >> theCurrentTemp.head.NTxx - >> theCurrentTemp.head.Dtype >> theCurrentTemp.head.Vbias >> theCurrentTemp.head.temperature >> theCurrentTemp.head.fluence >> theCurrentTemp.head.qscale - >> theCurrentTemp.head.s50 >> theCurrentTemp.head.lorywidth >> theCurrentTemp.head.lorxwidth >> theCurrentTemp.head.ysize >> theCurrentTemp.head.xsize >> theCurrentTemp.head.zsize; - - if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file, no template load" << ENDL; return false;} - - LOGINFO("SiPixelTemplate2D") << "Template ID = " << theCurrentTemp.head.ID << ", Template Version " << theCurrentTemp.head.templ_version << ", Bfield = " << theCurrentTemp.head.Bfield - << ", NTy = " << theCurrentTemp.head.NTy << ", NTyx = " << theCurrentTemp.head.NTyx<< ", NTxx = " << theCurrentTemp.head.NTxx << ", Dtype = " << theCurrentTemp.head.Dtype - << ", Bias voltage " << theCurrentTemp.head.Vbias << ", temperature " - << theCurrentTemp.head.temperature << ", fluence " << theCurrentTemp.head.fluence << ", Q-scaling factor " << theCurrentTemp.head.qscale - << ", 1/2 threshold " << theCurrentTemp.head.s50 << ", y Lorentz Width " << theCurrentTemp.head.lorywidth << ", x Lorentz width " << theCurrentTemp.head.lorxwidth - << ", pixel x-size " << theCurrentTemp.head.xsize << ", y-size " << theCurrentTemp.head.ysize << ", zsize " << theCurrentTemp.head.zsize << ENDL; - - if(theCurrentTemp.head.templ_version != code_version) {LOGERROR("SiPixelTemplate2D") << "code expects version " << code_version << ", no template load" << ENDL; return false;} - - if(theCurrentTemp.head.NTy != 0) {LOGERROR("SiPixelTemplate2D") << "Trying to load 1-d template info into the 2-d template object, check your DB/global tag!" << ENDL; return false;} - - // next, layout the 2-d structure needed to store template - - theCurrentTemp.entry.resize(boost::extents[theCurrentTemp.head.NTyx][theCurrentTemp.head.NTxx]); - - // Read in the file info - - for (iy=0; iy < theCurrentTemp.head.NTyx; ++iy) { - for(jx=0; jx < theCurrentTemp.head.NTxx; ++jx) { - - db >> theCurrentTemp.entry[iy][jx].runnum >> theCurrentTemp.entry[iy][jx].costrk[0] - >> theCurrentTemp.entry[iy][jx].costrk[1] >> theCurrentTemp.entry[iy][jx].costrk[2]; - - if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 1, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - // Calculate cot(alpha) and cot(beta) for this entry - - theCurrentTemp.entry[iy][jx].cotalpha = theCurrentTemp.entry[iy][jx].costrk[0]/theCurrentTemp.entry[iy][jx].costrk[2]; - - theCurrentTemp.entry[iy][jx].cotbeta = theCurrentTemp.entry[iy][jx].costrk[1]/theCurrentTemp.entry[iy][jx].costrk[2]; - - db >> theCurrentTemp.entry[iy][jx].qavg >> theCurrentTemp.entry[iy][jx].pixmax >> theCurrentTemp.entry[iy][jx].sxymax >> theCurrentTemp.entry[iy][jx].iymin - >> theCurrentTemp.entry[iy][jx].iymax >> theCurrentTemp.entry[iy][jx].jxmin >> theCurrentTemp.entry[iy][jx].jxmax; - - if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 2, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - for (k=0; k<2; ++k) { - - db >> theCurrentTemp.entry[iy][jx].xypar[k][0] >> theCurrentTemp.entry[iy][jx].xypar[k][1] - >> theCurrentTemp.entry[iy][jx].xypar[k][2] >> theCurrentTemp.entry[iy][jx].xypar[k][3] >> theCurrentTemp.entry[iy][jx].xypar[k][4]; - - if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 3, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - } - - for (k=0; k<2; ++k) { - - db >> theCurrentTemp.entry[iy][jx].lanpar[k][0] >> theCurrentTemp.entry[iy][jx].lanpar[k][1] - >> theCurrentTemp.entry[iy][jx].lanpar[k][2] >> theCurrentTemp.entry[iy][jx].lanpar[k][3] >> theCurrentTemp.entry[iy][jx].lanpar[k][4]; - - if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 4, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - } - - for (l=0; l<7; ++l) { - for (k=0; k<7; ++k) { - for (j=0; j> theCurrentTemp.entry[iy][jx].xytemp[k][l][i][j];} - - if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 5, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - } - } - } - - - db >> theCurrentTemp.entry[iy][jx].chi2minone >> theCurrentTemp.entry[iy][jx].chi2avgone >> theCurrentTemp.entry[iy][jx].chi2min[0] >> theCurrentTemp.entry[iy][jx].chi2avg[0] - >> theCurrentTemp.entry[iy][jx].chi2min[1] >> theCurrentTemp.entry[iy][jx].chi2avg[1]>> theCurrentTemp.entry[iy][jx].chi2min[2] >> theCurrentTemp.entry[iy][jx].chi2avg[2] - >> theCurrentTemp.entry[iy][jx].chi2min[3] >> theCurrentTemp.entry[iy][jx].chi2avg[3]; - - if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 6, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - db >> theCurrentTemp.entry[iy][jx].spare[0] >> theCurrentTemp.entry[iy][jx].spare[1] >> theCurrentTemp.entry[iy][jx].spare[2] >> theCurrentTemp.entry[iy][jx].spare[3] - >> theCurrentTemp.entry[iy][jx].spare[4] >> theCurrentTemp.entry[iy][jx].spare[5] >> theCurrentTemp.entry[iy][jx].spare[6] >> theCurrentTemp.entry[iy][jx].spare[7] - >> theCurrentTemp.entry[iy][jx].spare[8] >> theCurrentTemp.entry[iy][jx].spare[9]; - - if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 7, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - db >> theCurrentTemp.entry[iy][jx].spare[10] >> theCurrentTemp.entry[iy][jx].spare[11] >> theCurrentTemp.entry[iy][jx].spare[12] >> theCurrentTemp.entry[iy][jx].spare[13] - >> theCurrentTemp.entry[iy][jx].spare[14] >> theCurrentTemp.entry[iy][jx].spare[15] >> theCurrentTemp.entry[iy][jx].spare[16] >> theCurrentTemp.entry[iy][jx].spare[17] - >> theCurrentTemp.entry[iy][jx].spare[18] >> theCurrentTemp.entry[iy][jx].spare[19]; - - if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 8, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} - - } - } - - } - - - // Add this template to the store - - thePixelTemp_.push_back(theCurrentTemp); - - return true; - -} // TempInit - -#endif - - - -// ************************************************************************************************************************************* -//! Interpolate stored 2-D information for input angles and hit position to make a 2-D template -//! \param id - (input) the id of the template -//! \param cotalpha - (input) the cotangent of the alpha track angle (see CMS IN 2004/014) -//! \param cotbeta - (input) the cotangent of the beta track angle (see CMS IN 2004/014) -//! \param locBz - (input) the sign of this quantity is used to determine whether to flip cot(beta)<0 quantities from cot(beta)>0 (FPix only) -//! for FPix IP-related tracks, locBz < 0 for cot(beta) > 0 and locBz > 0 for cot(beta) < 0 -//! \param xhit - (input) x-position of hit relative to the lower left corner of pixel[1][1] (to allow for the "padding" of the two-d clusters in the splitter) -//! \param yhit - (input) y-position of hit relative to the lower left corner of pixel[1][1] -//! \param ydouble - (input) STL vector of 21 element array to flag a double-pixel starting at cluster[1][1] -//! \param xdouble - (input) STL vector of 11 element array to flag a double-pixel starting at cluster[1][1] -//! \param template2d - (output) 2d template of size matched to the cluster. Input must be zeroed since charge is added only. -// ************************************************************************************************************************************* - -bool SiPixelTemplate2D::xytemp(int id, float cotalpha, float cotbeta, float locBz, float xhit, float yhit, std::vector& ydouble, std::vector& xdouble, float template2d[BXM2][BYM2]) -{ - // Interpolate for a new set of track angles - - // Local variables - int i, j; - int pixx, pixy, k0, k1, l0, l1, imidx, deltax, deltay, iflipy, imin, imax, jmin, jmax; - int m, n; - float acotb, dcota, dcotb, dx, dy, ddx, ddy, adx, ady, tmpxy; - bool flip_y; - // std::vector xrms(4), xgsig(4), xrmsc2m(4), xgsigc2m(4); - std::vector chi2xavg(4), chi2xmin(4); - - - // Check to see if interpolation is valid - - if(id != id_current_ || cotalpha != cota_current_ || cotbeta != cotb_current_) { - - cota_current_ = cotalpha; cotb_current_ = cotbeta; success_ = true; - - if(id != id_current_) { - - // Find the index corresponding to id - - index_id_ = -1; - for(i=0; i<(int)thePixelTemp_.size(); ++i) { - - if(id == thePixelTemp_[i].head.ID) { - - index_id_ = i; - id_current_ = id; - - // Copy the charge scaling factor to the private variable - - Dtype_ = thePixelTemp_[index_id_].head.Dtype; - - // Copy the charge scaling factor to the private variable - - qscale_ = thePixelTemp_[index_id_].head.qscale; - - // Copy the pseudopixel signal size to the private variable - - s50_ = thePixelTemp_[index_id_].head.s50; - - // Copy the Lorentz widths to private variables - - lorywidth_ = thePixelTemp_[index_id_].head.lorywidth; - lorxwidth_ = thePixelTemp_[index_id_].head.lorxwidth; - - // Copy the pixel sizes private variables - - xsize_ = thePixelTemp_[index_id_].head.xsize; - ysize_ = thePixelTemp_[index_id_].head.ysize; - zsize_ = thePixelTemp_[index_id_].head.zsize; - - // Determine the size of this template - - Nyx_ = thePixelTemp_[index_id_].head.NTyx; - Nxx_ = thePixelTemp_[index_id_].head.NTxx; -#ifndef SI_PIXEL_TEMPLATE_STANDALONE - if(Nyx_ < 2 || Nxx_ < 2) { - throw cms::Exception("DataCorrupt") << "template ID = " << id_current_ << "has too few entries: Nyx/Nxx = " << Nyx_ << "/" << Nxx_ << std::endl; - } -#else - assert(Nyx_ > 1 && Nxx_ > 1); -#endif - imidx = Nxx_/2; - - cotalpha0_ = thePixelTemp_[index_id_].entry[0][0].cotalpha; - cotalpha1_ = thePixelTemp_[index_id_].entry[0][Nxx_-1].cotalpha; - deltacota_ = (cotalpha1_-cotalpha0_)/(float)(Nxx_-1); - - cotbeta0_ = thePixelTemp_[index_id_].entry[0][imidx].cotbeta; - cotbeta1_ = thePixelTemp_[index_id_].entry[Nyx_-1][imidx].cotbeta; - deltacotb_ = (cotbeta1_-cotbeta0_)/(float)(Nyx_-1); - - break; - } - } - } - } - -#ifndef SI_PIXEL_TEMPLATE_STANDALONE - if(index_id_ < 0 || index_id_ >= (int)thePixelTemp_.size()) { - throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::interpolate can't find needed template ID = " << id - << ", Are you using the correct global tag?" << std::endl; - } -#else - assert(index_id_ >= 0 && index_id_ < (int)thePixelTemp_.size()); -#endif - - // Check angle limits and et up interpolation parameters - - if(cotalpha < cotalpha0_) { - success_ = false; - jx0_ = 0; - jx1_ = 1; - adcota_ = 0.f; - } else if(cotalpha > cotalpha1_) { - success_ = false; - jx0_ = Nxx_ - 1; - jx1_ = jx0_ - 1; - adcota_ = 0.f; - } else { - jx0_ = (int)((cotalpha-cotalpha0_)/deltacota_+0.5f); - dcota = (cotalpha - (cotalpha0_ + jx0_*deltacota_))/deltacota_; - adcota_ = fabs(dcota); - if(dcota > 0.f) {jx1_ = jx0_ + 1;if(jx1_ > Nxx_-1) jx1_ = jx0_-1;} else {jx1_ = jx0_ - 1; if(jx1_ < 0) jx1_ = jx0_+1;} - } - - // Interpolate the absolute value of cot(beta) - - acotb = std::abs(cotbeta); - - if(acotb < cotbeta0_) { - success_ = false; - iy0_ = 0; - iy1_ = 1; - adcotb_ = 0.f; - } else if(acotb > cotbeta1_) { - success_ = false; - iy0_ = Nyx_ - 1; - iy1_ = iy0_ - 1; - adcotb_ = 0.f; - } else { - iy0_ = (int)((acotb-cotbeta0_)/deltacotb_+0.5f); - dcotb = (acotb - (cotbeta0_ + iy0_*deltacotb_))/deltacotb_; - adcotb_ = fabs(dcotb); - if(dcotb > 0.f) {iy1_ = iy0_ + 1; if(iy1_ > Nyx_-1) iy1_ = iy0_-1;} else {iy1_ = iy0_ - 1; if(iy1_ < 0) iy1_ = iy0_+1;} - } - - // This works only for IP-related tracks - - flip_y = false; - if(cotbeta < 0.f) {flip_y = true;} - - // If Fpix-related track has wrong cotbeta-field correlation, return false to trigger simple template instead - - if(Dtype_ == 1) { - if(cotbeta*locBz > 0.f) success_ = false; - } - - // Interpolate things in cot(alpha)-cot(beta) - - qavg_ = thePixelTemp_[index_id_].entry[iy0_][jx0_].qavg - +adcota_*(thePixelTemp_[index_id_].entry[iy0_][jx1_].qavg - thePixelTemp_[index_id_].entry[iy0_][jx0_].qavg) - +adcotb_*(thePixelTemp_[index_id_].entry[iy1_][jx0_].qavg - thePixelTemp_[index_id_].entry[iy0_][jx0_].qavg); - - pixmax_ = thePixelTemp_[index_id_].entry[iy0_][jx0_].pixmax - +adcota_*(thePixelTemp_[index_id_].entry[iy0_][jx1_].pixmax - thePixelTemp_[index_id_].entry[iy0_][jx0_].pixmax) - +adcotb_*(thePixelTemp_[index_id_].entry[iy1_][jx0_].pixmax - thePixelTemp_[index_id_].entry[iy0_][jx0_].pixmax); - - sxymax_ = thePixelTemp_[index_id_].entry[iy0_][jx0_].sxymax - +adcota_*(thePixelTemp_[index_id_].entry[iy0_][jx1_].sxymax - thePixelTemp_[index_id_].entry[iy0_][jx0_].sxymax) - +adcotb_*(thePixelTemp_[index_id_].entry[iy1_][jx0_].sxymax - thePixelTemp_[index_id_].entry[iy0_][jx0_].sxymax); - - chi2avgone_ = thePixelTemp_[index_id_].entry[iy0_][jx0_].chi2avgone - +adcota_*(thePixelTemp_[index_id_].entry[iy0_][jx1_].chi2avgone - thePixelTemp_[index_id_].entry[iy0_][jx0_].chi2avgone) - +adcotb_*(thePixelTemp_[index_id_].entry[iy1_][jx0_].chi2avgone - thePixelTemp_[index_id_].entry[iy0_][jx0_].chi2avgone); - - chi2minone_ = thePixelTemp_[index_id_].entry[iy0_][jx0_].chi2minone - +adcota_*(thePixelTemp_[index_id_].entry[iy0_][jx1_].chi2minone - thePixelTemp_[index_id_].entry[iy0_][jx0_].chi2minone) - +adcotb_*(thePixelTemp_[index_id_].entry[iy1_][jx0_].chi2minone - thePixelTemp_[index_id_].entry[iy0_][jx0_].chi2minone); - - for(i=0; i<4 ; ++i) { - chi2avg_[i] = thePixelTemp_[index_id_].entry[iy0_][jx0_].chi2avg[i] - +adcota_*(thePixelTemp_[index_id_].entry[iy0_][jx1_].chi2avg[i] - thePixelTemp_[index_id_].entry[iy0_][jx0_].chi2avg[i]) - +adcotb_*(thePixelTemp_[index_id_].entry[iy1_][jx0_].chi2avg[i] - thePixelTemp_[index_id_].entry[iy0_][jx0_].chi2avg[i]); - - chi2min_[i] = thePixelTemp_[index_id_].entry[iy0_][jx0_].chi2min[i] - +adcota_*(thePixelTemp_[index_id_].entry[iy0_][jx1_].chi2min[i] - thePixelTemp_[index_id_].entry[iy0_][jx0_].chi2min[i]) - +adcotb_*(thePixelTemp_[index_id_].entry[iy1_][jx0_].chi2min[i] - thePixelTemp_[index_id_].entry[iy0_][jx0_].chi2min[i]); - } - - for(i=0; i<2 ; ++i) { - for(j=0; j<5 ; ++j) { - // Charge loss switches sides when cot(beta) changes sign - if(flip_y) { - xypary0x0_[1-i][j] = thePixelTemp_[index_id_].entry[iy0_][jx0_].xypar[i][j]; - xypary1x0_[1-i][j] = thePixelTemp_[index_id_].entry[iy1_][jx0_].xypar[i][j]; - xypary0x1_[1-i][j] = thePixelTemp_[index_id_].entry[iy0_][jx1_].xypar[i][j]; - lanpar_[1-i][j] = thePixelTemp_[index_id_].entry[iy0_][jx0_].lanpar[i][j] - +adcota_*(thePixelTemp_[index_id_].entry[iy0_][jx1_].lanpar[i][j] - thePixelTemp_[index_id_].entry[iy0_][jx0_].lanpar[i][j]) - +adcotb_*(thePixelTemp_[index_id_].entry[iy1_][jx0_].lanpar[i][j] - thePixelTemp_[index_id_].entry[iy0_][jx0_].lanpar[i][j]); - } else { - xypary0x0_[i][j] = thePixelTemp_[index_id_].entry[iy0_][jx0_].xypar[i][j]; - xypary1x0_[i][j] = thePixelTemp_[index_id_].entry[iy1_][jx0_].xypar[i][j]; - xypary0x1_[i][j] = thePixelTemp_[index_id_].entry[iy0_][jx1_].xypar[i][j]; - lanpar_[i][j] = thePixelTemp_[index_id_].entry[iy0_][jx0_].lanpar[i][j] - +adcota_*(thePixelTemp_[index_id_].entry[iy0_][jx1_].lanpar[i][j] - thePixelTemp_[index_id_].entry[iy0_][jx0_].lanpar[i][j]) - +adcotb_*(thePixelTemp_[index_id_].entry[iy1_][jx0_].lanpar[i][j] - thePixelTemp_[index_id_].entry[iy0_][jx0_].lanpar[i][j]); - } - } - } - - // next, determine the indices of the closest point in k (y-displacement), l (x-displacement) - // pixy and pixx are the indices of the struck pixel in the (Ty,Tx) system - // k0,k1 are the k-indices of the closest and next closest point - // l0,l1 are the l-indices of the closest and next closest point - - pixy = (int)floorf(yhit/ysize_); - dy = yhit-(pixy+0.5f)*ysize_; - if(flip_y) {dy = -dy;} - k0 = (int)(dy/ysize_*6.f+3.5f); - if(k0 < 0) k0 = 0; - if(k0 > 6) k0 = 6; - ddy = 6.f*dy/ysize_ - (k0-3); - ady = fabs(ddy); - if(ddy > 0.f) {k1 = k0 + 1; if(k1 > 6) k1 = k0-1;} else {k1 = k0 - 1; if(k1 < 0) k1 = k0+1;} - pixx = (int)floorf(xhit/xsize_); - dx = xhit-(pixx+0.5f)*xsize_; - l0 = (int)(dx/xsize_*6.f+3.5f); - if(l0 < 0) l0 = 0; - if(l0 > 6) l0 = 6; - ddx = 6.f*dx/xsize_ - (l0-3); - adx = fabs(ddx); - if(ddx > 0.f) {l1 = l0 + 1; if(l1 > 6) l1 = l0-1;} else {l1 = l0 - 1; if(l1 < 0) l1 = l0+1;} - - // OK, lets do the template interpolation. - - // First find the limits of the indices for non-zero pixels - - imin = std::min(thePixelTemp_[index_id_].entry[iy0_][jx0_].iymin,thePixelTemp_[index_id_].entry[iy1_][jx0_].iymin); - imin = std::min(imin,thePixelTemp_[index_id_].entry[iy0_][jx1_].iymin); - - jmin = std::min(thePixelTemp_[index_id_].entry[iy0_][jx0_].jxmin,thePixelTemp_[index_id_].entry[iy1_][jx0_].jxmin); - jmin = std::min(jmin,thePixelTemp_[index_id_].entry[iy0_][jx1_].jxmin); - - imax = std::max(thePixelTemp_[index_id_].entry[iy0_][jx0_].iymax,thePixelTemp_[index_id_].entry[iy1_][jx0_].iymax); - imax = std::max(imax,thePixelTemp_[index_id_].entry[iy0_][jx1_].iymax); - - jmax = std::max(thePixelTemp_[index_id_].entry[iy0_][jx0_].jxmax,thePixelTemp_[index_id_].entry[iy1_][jx0_].jxmax); - jmax = std::max(jmax,thePixelTemp_[index_id_].entry[iy0_][jx1_].jxmax); - - // Calculate the x and y offsets to make the new template - - // First, shift the struck pixel coordinates to the (Ty+2, Tx+2) system - - ++pixy; ++pixx; - - // In the template store, the struck pixel is always (THy,THx) - - deltax = pixx - T2HX; - deltay = pixy - T2HY; - - // First zero the local 2-d template - - for(j=0; j=0 && m<=BXM3 && n>=0 && n<=BYM3) { - tmpxy = thePixelTemp_[index_id_].entry[iy0_][jx0_].xytemp[k0][l0][i][j] - + adx*(thePixelTemp_[index_id_].entry[iy0_][jx0_].xytemp[k0][l1][i][j] - thePixelTemp_[index_id_].entry[iy0_][jx0_].xytemp[k0][l0][i][j]) - + ady*(thePixelTemp_[index_id_].entry[iy0_][jx0_].xytemp[k1][l0][i][j] - thePixelTemp_[index_id_].entry[iy0_][jx0_].xytemp[k0][l0][i][j]) - + adcota_*(thePixelTemp_[index_id_].entry[iy0_][jx1_].xytemp[k0][l0][i][j] - thePixelTemp_[index_id_].entry[iy0_][jx0_].xytemp[k0][l0][i][j]) - + adcotb_*(thePixelTemp_[index_id_].entry[iy1_][jx0_].xytemp[k0][l0][i][j] - thePixelTemp_[index_id_].entry[iy0_][jx0_].xytemp[k0][l0][i][j]); - if(tmpxy > 0.f) {xytemp_[m][n] = tmpxy;} else {xytemp_[m][n] = 0.f;} - } - } - } - - //combine rows and columns to simulate double pixels - - for(n=1; n 0.f) {template2d[m][n] += xytemp_[m][n];} - } - } - - return success_; -} // xytemp - - - -// ************************************************************************************************************************************* -//! Interpolate stored 2-D information for input angles and hit position to make a 2-D template -//! \param id - (input) the id of the template -//! \param cotalpha - (input) the cotangent of the alpha track angle (see CMS IN 2004/014) -//! \param cotbeta - (input) the cotangent of the beta track angle (see CMS IN 2004/014) -//! \param xhit - (input) x-position of hit relative to the lower left corner of pixel[1][1] (to allow for the "padding" of the two-d clusters in the splitter) -//! \param yhit - (input) y-position of hit relative to the lower left corner of pixel[1][1] -//! \param ydouble - (input) STL vector of 21 element array to flag a double-pixel starting at cluster[1][1] -//! \param xdouble - (input) STL vector of 11 element array to flag a double-pixel starting at cluster[1][1] -//! \param template2d - (output) 2d template of size matched to the cluster. Input must be zeroed since charge is added only. -// ************************************************************************************************************************************* - -bool SiPixelTemplate2D::xytemp(int id, float cotalpha, float cotbeta, float xhit, float yhit, std::vector& ydouble, std::vector& xdouble, float template2d[BXM2][BYM2]) -{ - // Interpolate for a new set of track angles - - // Local variables - float locBz = -1; - if(cotbeta < 0.f) {locBz = -locBz;} - - return SiPixelTemplate2D::xytemp(id, cotalpha, cotbeta, locBz, xhit, yhit, ydouble, xdouble, template2d); - -} // xytemp - - - -// ************************************************************************************************************ -//! Return y error (squared) for an input signal and yindex -//! Add large Q scaling for use in cluster splitting. -//! \param qpixel - (input) pixel charge -//! \param index - (input) y-index index of pixel -//! \param xysig2 - (output) square error -// ************************************************************************************************************ -void SiPixelTemplate2D::xysigma2(float qpixel, int index, float& xysig2) - -{ - // Interpolate using quantities already stored in the private variables - - // Local variables - float sigi, sigi2, sigi3, sigi4, qscale, err2, err00; - - // Make sure that input is OK - -#ifndef SI_PIXEL_TEMPLATE_STANDALONE - if(index < 2 || index >= BYM2) { - throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::ysigma2 called with index = " << index << std::endl; - } -#else - assert(index > 1 && index < BYM2); -#endif - - // Define the maximum signal to use in the parameterization - - // Evaluate pixel-by-pixel uncertainties (weights) for the templ analysis - - if(qpixel < sxymax_) { - sigi = qpixel; - qscale = 1.f; - } else { - sigi = sxymax_; - qscale = qpixel/sxymax_; - } - sigi2 = sigi*sigi; sigi3 = sigi2*sigi; sigi4 = sigi3*sigi; - if(index <= THXP1) { - err00 = xypary0x0_[0][0]+xypary0x0_[0][1]*sigi+xypary0x0_[0][2]*sigi2+xypary0x0_[0][3]*sigi3+xypary0x0_[0][4]*sigi4; - err2 = err00 - +adcota_*(xypary0x1_[0][0]+xypary0x1_[0][1]*sigi+xypary0x1_[0][2]*sigi2+xypary0x1_[0][3]*sigi3+xypary0x1_[0][4]*sigi4 - err00) - +adcotb_*(xypary1x0_[0][0]+xypary1x0_[0][1]*sigi+xypary1x0_[0][2]*sigi2+xypary1x0_[0][3]*sigi3+xypary1x0_[0][4]*sigi4 - err00); - } else { - err00 = xypary0x0_[1][0]+xypary0x0_[1][1]*sigi+xypary0x0_[1][2]*sigi2+xypary0x0_[1][3]*sigi3+xypary0x0_[1][4]*sigi4; - err2 = err00 - +adcota_*(xypary0x1_[1][0]+xypary0x1_[1][1]*sigi+xypary0x1_[1][2]*sigi2+xypary0x1_[1][3]*sigi3+xypary0x1_[1][4]*sigi4 - err00) - +adcotb_*(xypary1x0_[1][0]+xypary1x0_[1][1]*sigi+xypary1x0_[1][2]*sigi2+xypary1x0_[1][3]*sigi3+xypary1x0_[1][4]*sigi4 - err00); - } - xysig2 =qscale*err2; - if(xysig2 <= 0.f) {LOGERROR("SiPixelTemplate2D") << "neg y-error-squared, id = " << id_current_ << ", index = " << index_id_ << - ", cot(alpha) = " << cota_current_ << ", cot(beta) = " << cotb_current_ << ", sigi = " << sigi << ENDL;} - - return; - -} // End xysigma2 - - -// ************************************************************************************************************ -//! Return the Landau probability parameters for this set of cot(alpha, cot(beta) -// ************************************************************************************************************ -void SiPixelTemplate2D::landau_par(float lanpar[2][5]) - -{ - // Interpolate using quantities already stored in the private variables - - // Local variables - int i,j; - for(i=0; i<2; ++i) { - for(j=0; j<5; ++j) { - lanpar[i][j] = lanpar_[i][j]; - } - } - return; - -} // End lan_par - - - +// +// SiPixelTemplate2D.cc Version 2.35 +// +// Full 2-D templates for cluster splitting, simulated cluster reweighting, and improved cluster probability +// +// Created by Morris Swartz on 12/01/09. +// 2009 __TheJohnsHopkinsUniversity__. +// +// V1.01 - fix qavg_ filling +// V1.02 - Add locBz to test if FPix use is out of range +// V1.03 - Fix edge checking on final template to increase template size and to properly truncate cluster +// v2.00 - Major changes to accommodate 2D reconstruction +// v2.10 - Change chi2 and error scaling information to work with partially reconstructed clusters +// v2.20 - Add cluster charge probability information, side loading for template generation +// v2.21 - Double derivative interval [improves fit convergence] +// v2.25 - Resize template store to accommodate FPix Templates +// v2.30 - Fix bug found by P. Shuetze that compromises sqlite file loading +// v2.35 - Add directory path selection to the ascii pushfile method +// +// + +//#include +//#include +#ifndef SI_PIXEL_TEMPLATE_STANDALONE +//#include +#else +#include +#endif +#include +#include +//#include "boost/multi_array.hpp" +#include +#include +#include +#include + + +#ifndef SI_PIXEL_TEMPLATE_STANDALONE +#include "RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplate2D.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#define LOGERROR(x) LogError(x) +#define LOGINFO(x) LogInfo(x) +#define ENDL " " +#include "FWCore/Utilities/interface/Exception.h" +using namespace edm; +#else +#include "SiPixelTemplate2D.h" +#define LOGERROR(x) std::cout << x << ": " +#define LOGINFO(x) std::cout << x << ": " +#define ENDL std::endl +#endif + +//**************************************************************** +//! This routine initializes the global template structures from +//! an external file template_summary_zpNNNN where NNNN are four +//! digits of filenum. +//! \param filenum - an integer NNNN used in the filename template_summary_zpNNNN +//**************************************************************** +bool SiPixelTemplate2D::pushfile(int filenum, std::vector< SiPixelTemplateStore2D > & thePixelTemp_, std::string dir) +{ + // Add template stored in external file numbered filenum to theTemplateStore + + // Local variables + int i, j, k, l, iy, jx; + const char *tempfile; + // char title[80]; remove this + char c; + const int code_version={21}; + + + + // Create a filename for this run + + std::ostringstream tout; + + // Create different path in CMSSW than standalone + +#ifndef SI_PIXEL_TEMPLATE_STANDALONE + tout << dir << "template_summary2D_zp" + << std::setw(4) << std::setfill('0') << std::right << filenum << ".out" << std::ends; + std::string tempf = tout.str(); + edm::FileInPath file( tempf.c_str() ); + tempfile = (file.fullPath()).c_str(); +#else + tout << "template_summary2D_zp" << std::setw(4) << std::setfill('0') << std::right << filenum << ".out" << std::ends; + std::string tempf = tout.str(); + tempfile = tempf.c_str(); +#endif + + // open the template file + + std::ifstream in_file(tempfile, std::ios::in); + + if(in_file.is_open()) { + + // Create a local template storage entry + + SiPixelTemplateStore2D theCurrentTemp; + + // Read-in a header string first and print it + + for (i=0; (c=in_file.get()) != '\n'; ++i) { + if(i < 79) {theCurrentTemp.head.title[i] = c;} + } + if(i > 78) {i=78;} + theCurrentTemp.head.title[i+1] ='\0'; + LOGINFO("SiPixelTemplate2D") << "Loading Pixel Template File - " << theCurrentTemp.head.title << ENDL; + + // next, the header information + in_file >> theCurrentTemp.head.ID >> theCurrentTemp.head.templ_version >> theCurrentTemp.head.Bfield >> theCurrentTemp.head.NTy >> theCurrentTemp.head.NTyx >> theCurrentTemp.head.NTxx + >> theCurrentTemp.head.Dtype >> theCurrentTemp.head.Vbias >> theCurrentTemp.head.temperature >> theCurrentTemp.head.fluence >> theCurrentTemp.head.qscale + >> theCurrentTemp.head.s50 >> theCurrentTemp.head.lorywidth >> theCurrentTemp.head.lorxwidth >> theCurrentTemp.head.ysize >> theCurrentTemp.head.xsize >> theCurrentTemp.head.zsize; + + if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 0A, no template load" << ENDL; return false;} + + if(theCurrentTemp.head.templ_version > 17) { + in_file >> theCurrentTemp.head.ss50 >> theCurrentTemp.head.lorybias + >> theCurrentTemp.head.lorxbias >> theCurrentTemp.head.fbin[0] + >> theCurrentTemp.head.fbin[1] >> theCurrentTemp.head.fbin[2]; + + if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 0B, no template load" + << ENDL; return false;} + } else { + theCurrentTemp.head.ss50 = theCurrentTemp.head.s50; + theCurrentTemp.head.lorybias = theCurrentTemp.head.lorywidth/2.f; + theCurrentTemp.head.lorxbias = theCurrentTemp.head.lorxwidth/2.f; + theCurrentTemp.head.fbin[0] = 1.5f; + theCurrentTemp.head.fbin[1] = 1.00f; + theCurrentTemp.head.fbin[2] = 0.85f; + } + + LOGINFO("SiPixelTemplate2D") << "Template ID = " << theCurrentTemp.head.ID << ", Template Version " << theCurrentTemp.head.templ_version << ", Bfield = " << theCurrentTemp.head.Bfield + << ", NTy = " << theCurrentTemp.head.NTy << ", NTyx = " << theCurrentTemp.head.NTyx<< ", NTxx = " << theCurrentTemp.head.NTxx << ", Dtype = " << theCurrentTemp.head.Dtype + << ", Bias voltage " << theCurrentTemp.head.Vbias << ", temperature " + << theCurrentTemp.head.temperature << ", fluence " << theCurrentTemp.head.fluence << ", Q-scaling factor " << theCurrentTemp.head.qscale + << ", 1/2 multi dcol threshold " << theCurrentTemp.head.s50 << ", 1/2 single dcol threshold " << theCurrentTemp.head.ss50 + << ", y Lorentz Width " << theCurrentTemp.head.lorywidth << ", y Lorentz Bias " << theCurrentTemp.head.lorybias + << ", x Lorentz width " << theCurrentTemp.head.lorxwidth << ", x Lorentz Bias " << theCurrentTemp.head.lorxbias + << ", Q/Q_avg fractions for Qbin defs " << theCurrentTemp.head.fbin[0] << ", " << theCurrentTemp.head.fbin[1] + << ", " << theCurrentTemp.head.fbin[2] + << ", pixel x-size " << theCurrentTemp.head.xsize << ", y-size " << theCurrentTemp.head.ysize << ", zsize " << theCurrentTemp.head.zsize << ENDL; + + if(theCurrentTemp.head.templ_version < code_version) {LOGERROR("SiPixelTemplate2D") << "code expects version " << code_version << ", no template load" << ENDL; return false;} + + if(theCurrentTemp.head.NTy != 0) {LOGERROR("SiPixelTemplate2D") << "Trying to load 1-d template info into the 2-d template object, check your DB/global tag!" << ENDL; return false;} + + +#ifdef SI_PIXEL_TEMPLATE_USE_BOOST + + // next, layout the 2-d structure needed to store template + + theCurrentTemp.entry.resize(boost::extents[theCurrentTemp.head.NTyx][theCurrentTemp.head.NTxx]); + +#endif + + // Read in the file info + + for (iy=0; iy < theCurrentTemp.head.NTyx; ++iy) { + for(jx=0; jx < theCurrentTemp.head.NTxx; ++jx) { + + in_file >> theCurrentTemp.entry[iy][jx].runnum >> theCurrentTemp.entry[iy][jx].costrk[0] + >> theCurrentTemp.entry[iy][jx].costrk[1] >> theCurrentTemp.entry[iy][jx].costrk[2]; + + if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 1, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + // Calculate cot(alpha) and cot(beta) for this entry + + theCurrentTemp.entry[iy][jx].cotalpha = theCurrentTemp.entry[iy][jx].costrk[0]/theCurrentTemp.entry[iy][jx].costrk[2]; + + theCurrentTemp.entry[iy][jx].cotbeta = theCurrentTemp.entry[iy][jx].costrk[1]/theCurrentTemp.entry[iy][jx].costrk[2]; + + in_file >> theCurrentTemp.entry[iy][jx].qavg >> theCurrentTemp.entry[iy][jx].pixmax >> theCurrentTemp.entry[iy][jx].sxymax >> theCurrentTemp.entry[iy][jx].iymin + >> theCurrentTemp.entry[iy][jx].iymax >> theCurrentTemp.entry[iy][jx].jxmin >> theCurrentTemp.entry[iy][jx].jxmax; + + if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 2, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + for (k=0; k<2; ++k) { + + in_file >> theCurrentTemp.entry[iy][jx].xypar[k][0] >> theCurrentTemp.entry[iy][jx].xypar[k][1] + >> theCurrentTemp.entry[iy][jx].xypar[k][2] >> theCurrentTemp.entry[iy][jx].xypar[k][3] >> theCurrentTemp.entry[iy][jx].xypar[k][4]; + + if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 3, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + } + + for (k=0; k<2; ++k) { + + in_file >> theCurrentTemp.entry[iy][jx].lanpar[k][0] >> theCurrentTemp.entry[iy][jx].lanpar[k][1] + >> theCurrentTemp.entry[iy][jx].lanpar[k][2] >> theCurrentTemp.entry[iy][jx].lanpar[k][3] >> theCurrentTemp.entry[iy][jx].lanpar[k][4]; + + if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 4, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + } + + for (l=0; l<7; ++l) { + for (k=0; k<7; ++k) { + for (j=0; j> theCurrentTemp.entry[iy][jx].xytemp[k][l][i][j];} + + if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 5, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + } + } + } + + + in_file >> theCurrentTemp.entry[iy][jx].chi2ppix >> theCurrentTemp.entry[iy][jx].chi2scale >> theCurrentTemp.entry[iy][jx].offsetx[0] >> theCurrentTemp.entry[iy][jx].offsetx[1] + >> theCurrentTemp.entry[iy][jx].offsetx[2] >> theCurrentTemp.entry[iy][jx].offsetx[3]>> theCurrentTemp.entry[iy][jx].offsety[0] >> theCurrentTemp.entry[iy][jx].offsety[1] + >> theCurrentTemp.entry[iy][jx].offsety[2] >> theCurrentTemp.entry[iy][jx].offsety[3]; + + if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 6, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + in_file >> theCurrentTemp.entry[iy][jx].clsleny >> theCurrentTemp.entry[iy][jx].clslenx >> theCurrentTemp.entry[iy][jx].mpvvav >> theCurrentTemp.entry[iy][jx].sigmavav + >> theCurrentTemp.entry[iy][jx].kappavav >> theCurrentTemp.entry[iy][jx].scalexavg >> theCurrentTemp.entry[iy][jx].scaleyavg >> theCurrentTemp.entry[iy][jx].delyavg >> theCurrentTemp.entry[iy][jx].delysig >> theCurrentTemp.entry[iy][jx].spare[0]; + + if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 7, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + in_file >> theCurrentTemp.entry[iy][jx].scalex[0] >> theCurrentTemp.entry[iy][jx].scalex[1] >> theCurrentTemp.entry[iy][jx].scalex[2] >> theCurrentTemp.entry[iy][jx].scalex[3] + >> theCurrentTemp.entry[iy][jx].scaley[0] >> theCurrentTemp.entry[iy][jx].scaley[1] >> theCurrentTemp.entry[iy][jx].scaley[2] >> theCurrentTemp.entry[iy][jx].scaley[3] + >> theCurrentTemp.entry[iy][jx].spare[1] >> theCurrentTemp.entry[iy][jx].spare[2]; + + if(in_file.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 8, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + } + + } + + + in_file.close(); + + // Add this template to the store + + thePixelTemp_.push_back(theCurrentTemp); + + return true; + + } else { + + // If file didn't open, report this + + LOGERROR("SiPixelTemplate2D") << "Error opening File" << tempfile << ENDL; + return false; + + } + +} // TempInit + + +#ifndef SI_PIXEL_TEMPLATE_STANDALONE + +//**************************************************************** +//! This routine initializes the global template structures from an +//! external file template_summary_zpNNNN where NNNN are four digits +//! \param dbobject - db storing multiple template calibrations +//**************************************************************** +bool SiPixelTemplate2D::pushfile(const SiPixel2DTemplateDBObject& dbobject, std::vector< SiPixelTemplateStore2D > & thePixelTemp_) +{ + // Add template stored in external dbobject to theTemplateStore + + // Local variables + int i, j, k, l, iy, jx; + // const char *tempfile; + const int code_version={21}; + + // We must create a new object because dbobject must be a const and our stream must not be + SiPixel2DTemplateDBObject db = dbobject; + + // Create a local template storage entry + SiPixelTemplateStore2D theCurrentTemp; + + // Fill the template storage for each template calibration stored in the db + for(int m=0; m> theCurrentTemp.head.ID >> theCurrentTemp.head.templ_version >> theCurrentTemp.head.Bfield >> theCurrentTemp.head.NTy >> theCurrentTemp.head.NTyx >> theCurrentTemp.head.NTxx + >> theCurrentTemp.head.Dtype >> theCurrentTemp.head.Vbias >> theCurrentTemp.head.temperature >> theCurrentTemp.head.fluence >> theCurrentTemp.head.qscale + >> theCurrentTemp.head.s50 >> theCurrentTemp.head.lorywidth >> theCurrentTemp.head.lorxwidth >> theCurrentTemp.head.ysize >> theCurrentTemp.head.xsize >> theCurrentTemp.head.zsize; + + if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 0A, no template load" << ENDL; return false;} + + LOGINFO("SiPixelTemplate2D") << "Loading Pixel Template File - " << theCurrentTemp.head.title + <<" code version = "< 17) { + db >> theCurrentTemp.head.ss50 >> theCurrentTemp.head.lorybias >> theCurrentTemp.head.lorxbias >> theCurrentTemp.head.fbin[0] >> theCurrentTemp.head.fbin[1] >> theCurrentTemp.head.fbin[2]; + + if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 0B, no template load" + << ENDL; return false;} + } else { + theCurrentTemp.head.ss50 = theCurrentTemp.head.s50; + theCurrentTemp.head.lorybias = theCurrentTemp.head.lorywidth/2.f; + theCurrentTemp.head.lorxbias = theCurrentTemp.head.lorxwidth/2.f; + theCurrentTemp.head.fbin[0] = 1.50f; + theCurrentTemp.head.fbin[1] = 1.00f; + theCurrentTemp.head.fbin[2] = 0.85f; + //std::cout<<" set fbin "<< theCurrentTemp.head.fbin[0]<<" "<> theCurrentTemp.entry[iy][jx].runnum >> theCurrentTemp.entry[iy][jx].costrk[0] + >> theCurrentTemp.entry[iy][jx].costrk[1] >> theCurrentTemp.entry[iy][jx].costrk[2]; + + if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 1, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + // Calculate cot(alpha) and cot(beta) for this entry + + theCurrentTemp.entry[iy][jx].cotalpha = theCurrentTemp.entry[iy][jx].costrk[0]/theCurrentTemp.entry[iy][jx].costrk[2]; + + theCurrentTemp.entry[iy][jx].cotbeta = theCurrentTemp.entry[iy][jx].costrk[1]/theCurrentTemp.entry[iy][jx].costrk[2]; + + db >> theCurrentTemp.entry[iy][jx].qavg >> theCurrentTemp.entry[iy][jx].pixmax >> theCurrentTemp.entry[iy][jx].sxymax >> theCurrentTemp.entry[iy][jx].iymin + >> theCurrentTemp.entry[iy][jx].iymax >> theCurrentTemp.entry[iy][jx].jxmin >> theCurrentTemp.entry[iy][jx].jxmax; + + if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 2, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + for (k=0; k<2; ++k) { + + db >> theCurrentTemp.entry[iy][jx].xypar[k][0] >> theCurrentTemp.entry[iy][jx].xypar[k][1] + >> theCurrentTemp.entry[iy][jx].xypar[k][2] >> theCurrentTemp.entry[iy][jx].xypar[k][3] >> theCurrentTemp.entry[iy][jx].xypar[k][4]; + + if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 3, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + } + + for (k=0; k<2; ++k) { + + db >> theCurrentTemp.entry[iy][jx].lanpar[k][0] >> theCurrentTemp.entry[iy][jx].lanpar[k][1] + >> theCurrentTemp.entry[iy][jx].lanpar[k][2] >> theCurrentTemp.entry[iy][jx].lanpar[k][3] >> theCurrentTemp.entry[iy][jx].lanpar[k][4]; + + if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 4, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + } + + for (l=0; l<7; ++l) { + for (k=0; k<7; ++k) { + for (j=0; j> theCurrentTemp.entry[iy][jx].xytemp[k][l][i][j];} + + if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 5, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + } + } + } + + db >> theCurrentTemp.entry[iy][jx].chi2ppix >> theCurrentTemp.entry[iy][jx].chi2scale >> theCurrentTemp.entry[iy][jx].offsetx[0] >> theCurrentTemp.entry[iy][jx].offsetx[1] + >> theCurrentTemp.entry[iy][jx].offsetx[2] >> theCurrentTemp.entry[iy][jx].offsetx[3]>> theCurrentTemp.entry[iy][jx].offsety[0] >> theCurrentTemp.entry[iy][jx].offsety[1] + >> theCurrentTemp.entry[iy][jx].offsety[2] >> theCurrentTemp.entry[iy][jx].offsety[3]; + + if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 6, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + db >> theCurrentTemp.entry[iy][jx].clsleny >> theCurrentTemp.entry[iy][jx].clslenx >> theCurrentTemp.entry[iy][jx].mpvvav >> theCurrentTemp.entry[iy][jx].sigmavav + >> theCurrentTemp.entry[iy][jx].kappavav >> theCurrentTemp.entry[iy][jx].scalexavg >> theCurrentTemp.entry[iy][jx].scaleyavg >> theCurrentTemp.entry[iy][jx].delyavg >> theCurrentTemp.entry[iy][jx].delysig >> theCurrentTemp.entry[iy][jx].spare[0]; + + if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 7, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + db >> theCurrentTemp.entry[iy][jx].scalex[0] >> theCurrentTemp.entry[iy][jx].scalex[1] >> theCurrentTemp.entry[iy][jx].scalex[2] >> theCurrentTemp.entry[iy][jx].scalex[3] + >> theCurrentTemp.entry[iy][jx].scaley[0] >> theCurrentTemp.entry[iy][jx].scaley[1] >> theCurrentTemp.entry[iy][jx].scaley[2] >> theCurrentTemp.entry[iy][jx].scaley[3] + >> theCurrentTemp.entry[iy][jx].spare[1] >> theCurrentTemp.entry[iy][jx].spare[2]; + + if(db.fail()) {LOGERROR("SiPixelTemplate2D") << "Error reading file 8, no template load, run # " << theCurrentTemp.entry[iy][jx].runnum << ENDL; return false;} + + + } + } + +// Add this template to the store + + thePixelTemp_.push_back(theCurrentTemp); + + } + + + return true; + +} // TempInit + +#endif + + +// ************************************************************************************************************************************* +//! Interpolate stored 2-D information for input angles +//! \param id - (input) the id of the template +//! \param cotalpha - (input) the cotangent of the alpha track angle (see CMS IN 2004/014) +//! \param cotbeta - (input) the cotangent of the beta track angle (see CMS IN 2004/014) +//! \param locBz - (input) the sign of this quantity is used to determine whether to flip cot(beta)<0 quantities from cot(beta)>0 (FPix only) +//! for Phase 0 FPix IP-related tracks, locBz < 0 for cot(beta) > 0 and locBz > 0 for cot(beta) < 0 +//! for Phase 1 FPix IP-related tracks, see next comment +//! \param locBx - (input) the sign of this quantity is used to determine whether to flip cot(alpha/beta)<0 quantities from cot(alpha/beta)>0 (FPix only) +//! for Phase 1 FPix IP-related tracks, locBx/locBz > 0 for cot(alpha) > 0 and locBx/locBz < 0 for cot(alpha) < 0 +//! for Phase 1 FPix IP-related tracks, locBx > 0 for cot(beta) > 0 and locBx < 0 for cot(beta) < 0 +// ************************************************************************************************************************************* + +bool SiPixelTemplate2D::interpolate(int id, float cotalpha, float cotbeta, float locBz, float locBx) +{ + + + // Interpolate for a new set of track angles + + // Local variables + int i, j, imidx; + // int pixx, pixy, k0, k1, l0, l1, deltax, deltay, iflipy, jflipx, imin, imax, jmin, jmax; + // int m, n; + float acotb, dcota, dcotb; + + // Check to see if interpolation is valid + + if(id != id_current_ || cotalpha != cota_current_ || cotbeta != cotb_current_) { + + cota_current_ = cotalpha; cotb_current_ = cotbeta; success_ = true; + + if(id != id_current_) { + + // Find the index corresponding to id + + index_id_ = -1; + for(i=0; i<(int)thePixelTemp_.size(); ++i) { + + if(id == thePixelTemp_[i].head.ID) { + + index_id_ = i; + id_current_ = id; + + // Copy the charge scaling factor to the private variable + + Dtype_ = thePixelTemp_[index_id_].head.Dtype; + + // Copy the charge scaling factor to the private variable + + qscale_ = thePixelTemp_[index_id_].head.qscale; + + // Copy the pseudopixel signal size to the private variable + + s50_ = thePixelTemp_[index_id_].head.s50; + + // Copy Qbinning info to private variables + + for(j=0; j<3; ++j) {fbin_[j] = thePixelTemp_[index_id_].head.fbin[j];} + + // Copy the Lorentz widths to private variables + + lorywidth_ = thePixelTemp_[index_id_].head.lorywidth; + lorxwidth_ = thePixelTemp_[index_id_].head.lorxwidth; + + // Copy the pixel sizes private variables + + xsize_ = thePixelTemp_[index_id_].head.xsize; + ysize_ = thePixelTemp_[index_id_].head.ysize; + zsize_ = thePixelTemp_[index_id_].head.zsize; + + // Determine the size of this template + + Nyx_ = thePixelTemp_[index_id_].head.NTyx; + Nxx_ = thePixelTemp_[index_id_].head.NTxx; +#ifndef SI_PIXEL_TEMPLATE_STANDALONE + if(Nyx_ < 2 || Nxx_ < 2) { + throw cms::Exception("DataCorrupt") << "template ID = " << id_current_ << "has too few entries: Nyx/Nxx = " << Nyx_ << "/" << Nxx_ << std::endl; + } +#else + assert(Nyx_ > 1 && Nxx_ > 1); +#endif + imidx = Nxx_/2; + + cotalpha0_ = thePixelTemp_[index_id_].entry[0][0].cotalpha; + cotalpha1_ = thePixelTemp_[index_id_].entry[0][Nxx_-1].cotalpha; + deltacota_ = (cotalpha1_-cotalpha0_)/(float)(Nxx_-1); + + cotbeta0_ = thePixelTemp_[index_id_].entry[0][imidx].cotbeta; + cotbeta1_ = thePixelTemp_[index_id_].entry[Nyx_-1][imidx].cotbeta; + deltacotb_ = (cotbeta1_-cotbeta0_)/(float)(Nyx_-1); + + break; + } + } + } + } + +#ifndef SI_PIXEL_TEMPLATE_STANDALONE + if(index_id_ < 0 || index_id_ >= (int)thePixelTemp_.size()) { + throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::interpolate can't find needed template ID = " << id + << ", Are you using the correct global tag?" << std::endl; + } +#else + assert(index_id_ >= 0 && index_id_ < (int)thePixelTemp_.size()); +#endif + + // Check angle limits and et up interpolation parameters + + if(cotalpha < cotalpha0_) { + success_ = false; + jx0_ = 0; + jx1_ = 1; + adcota_ = 0.f; + } else if(cotalpha > cotalpha1_) { + success_ = false; + jx0_ = Nxx_ - 1; + jx1_ = jx0_ - 1; + adcota_ = 0.f; + } else { + jx0_ = (int)((cotalpha-cotalpha0_)/deltacota_+0.5f); + dcota = (cotalpha - (cotalpha0_ + jx0_*deltacota_))/deltacota_; + adcota_ = fabs(dcota); + if(dcota > 0.f) {jx1_ = jx0_ + 1;if(jx1_ > Nxx_-1) jx1_ = jx0_-1;} else {jx1_ = jx0_ - 1; if(jx1_ < 0) jx1_ = jx0_+1;} + } + + // Interpolate the absolute value of cot(beta) + + acotb = std::abs(cotbeta); + + if(acotb < cotbeta0_) { + success_ = false; + iy0_ = 0; + iy1_ = 1; + adcotb_ = 0.f; + } else if(acotb > cotbeta1_) { + success_ = false; + iy0_ = Nyx_ - 1; + iy1_ = iy0_ - 1; + adcotb_ = 0.f; + } else { + iy0_ = (int)((acotb-cotbeta0_)/deltacotb_+0.5f); + dcotb = (acotb - (cotbeta0_ + iy0_*deltacotb_))/deltacotb_; + adcotb_ = fabs(dcotb); + if(dcotb > 0.f) {iy1_ = iy0_ + 1; if(iy1_ > Nyx_-1) iy1_ = iy0_-1;} else {iy1_ = iy0_ - 1; if(iy1_ < 0) iy1_ = iy0_+1;} + } + + // This works only for IP-related tracks + + flip_x_ = false; + flip_y_ = false; + switch(Dtype_) { + case 0: + if(cotbeta < 0.f) {flip_y_ = true;} + break; + case 1: + if(locBz > 0.f) { + flip_y_ = true; + } + break; + case 2: + case 3: + case 4: + case 5: + if(locBx*locBz < 0.f) { + flip_x_ = true; + } + if(locBx < 0.f) { + flip_y_ = true; + } + break; + default: +#ifndef SI_PIXEL_TEMPLATE_STANDALONE + throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::illegal subdetector ID = " << thePixelTemp_[index_id_].head.Dtype << std::endl; +#else + std::cout << "SiPixelTemplate:2D:illegal subdetector ID = " << thePixelTemp_[index_id_].head.Dtype << std::endl; +#endif + } + + // Calculate signed quantities + + lorydrift_ = lorywidth_/2.; + if(flip_y_) lorydrift_ = -lorydrift_; + lorxdrift_ = lorxwidth_/2.; + if(flip_x_) lorxdrift_ = -lorxdrift_; + + // Use pointers to the three angle pairs used in the interpolation + + + entry00_ = &thePixelTemp_[index_id_].entry[iy0_][jx0_]; + entry10_ = &thePixelTemp_[index_id_].entry[iy1_][jx0_]; + entry01_ = &thePixelTemp_[index_id_].entry[iy0_][jx1_]; + + // Interpolate things in cot(alpha)-cot(beta) + + qavg_ = entry00_->qavg + +adcota_*(entry01_->qavg - entry00_->qavg) + +adcotb_*(entry10_->qavg - entry00_->qavg); + + pixmax_ = entry00_->pixmax + +adcota_*(entry01_->pixmax - entry00_->pixmax) + +adcotb_*(entry10_->pixmax - entry00_->pixmax); + + sxymax_ = entry00_->sxymax + +adcota_*(entry01_->sxymax - entry00_->sxymax) + +adcotb_*(entry10_->sxymax - entry00_->sxymax); + + chi2avgone_ = entry00_->chi2avgone + +adcota_*(entry01_->chi2avgone - entry00_->chi2avgone) + +adcotb_*(entry10_->chi2avgone - entry00_->chi2avgone); + + chi2minone_ = entry00_->chi2minone + +adcota_*(entry01_->chi2minone - entry00_->chi2minone) + +adcotb_*(entry10_->chi2minone - entry00_->chi2minone); + + clsleny_ = entry00_->clsleny + +adcota_*(entry01_->clsleny - entry00_->clsleny) + +adcotb_*(entry10_->clsleny - entry00_->clsleny); + + clslenx_ = entry00_->clslenx + +adcota_*(entry01_->clslenx - entry00_->clslenx) + +adcotb_*(entry10_->clslenx - entry00_->clslenx); + + + chi2ppix_ = entry00_->chi2ppix + +adcota_*(entry01_->chi2ppix - entry00_->chi2ppix) + +adcotb_*(entry10_->chi2ppix - entry00_->chi2ppix); + + chi2scale_ = entry00_->chi2scale + +adcota_*(entry01_->chi2scale - entry00_->chi2scale) + +adcotb_*(entry10_->chi2scale - entry00_->chi2scale); + + scaleyavg_ = entry00_->scaleyavg + +adcota_*(entry01_->scaleyavg - entry00_->scaleyavg) + +adcotb_*(entry10_->scaleyavg - entry00_->scaleyavg); + + scalexavg_ = entry00_->scalexavg + +adcota_*(entry01_->scalexavg - entry00_->scalexavg) + +adcotb_*(entry10_->scalexavg - entry00_->scalexavg); + + delyavg_ = entry00_->delyavg + +adcota_*(entry01_->delyavg - entry00_->delyavg) + +adcotb_*(entry10_->delyavg - entry00_->delyavg); + + delysig_ = entry00_->delysig + +adcota_*(entry01_->delysig - entry00_->delysig) + +adcotb_*(entry10_->delysig - entry00_->delysig); + + mpvvav_ = entry00_->mpvvav + +adcota_*(entry01_->mpvvav - entry00_->mpvvav) + +adcotb_*(entry10_->mpvvav - entry00_->mpvvav); + + sigmavav_ = entry00_->sigmavav + +adcota_*(entry01_->sigmavav - entry00_->sigmavav) + +adcotb_*(entry10_->sigmavav - entry00_->sigmavav); + + kappavav_ = entry00_->kappavav + +adcota_*(entry01_->kappavav - entry00_->kappavav) + +adcotb_*(entry10_->kappavav - entry00_->kappavav); + + for(i=0; i<4 ; ++i) { + scalex_[i] = entry00_->scalex[i] + +adcota_*(entry01_->scalex[i] - entry00_->scalex[i]) + +adcotb_*(entry10_->scalex[i] - entry00_->scalex[i]); + + scaley_[i] = entry00_->scaley[i] + +adcota_*(entry01_->scaley[i] - entry00_->scaley[i]) + +adcotb_*(entry10_->scaley[i] - entry00_->scaley[i]); + + offsetx_[i] = entry00_->offsetx[i] + +adcota_*(entry01_->offsetx[i] - entry00_->offsetx[i]) + +adcotb_*(entry10_->offsetx[i] - entry00_->offsetx[i]); + if(flip_x_) offsetx_[i] = -offsetx_[i]; + + offsety_[i] = entry00_->offsety[i] + +adcota_*(entry01_->offsety[i] - entry00_->offsety[i]) + +adcotb_*(entry10_->offsety[i] - entry00_->offsety[i]); + if(flip_y_) offsety_[i] = -offsety_[i]; + } + + for(i=0; i<2 ; ++i) { + for(j=0; j<5 ; ++j) { + // Charge loss switches sides when cot(beta) changes sign + if(flip_y_) { + xypary0x0_[1-i][j] = entry00_->xypar[i][j]; + xypary1x0_[1-i][j] = entry10_->xypar[i][j]; + xypary0x1_[1-i][j] = entry01_->xypar[i][j]; + lanpar_[1-i][j] = entry00_->lanpar[i][j] + +adcota_*(entry01_->lanpar[i][j] - entry00_->lanpar[i][j]) + +adcotb_*(entry10_->lanpar[i][j] - entry00_->lanpar[i][j]); + } else { + xypary0x0_[i][j] = entry00_->xypar[i][j]; + xypary1x0_[i][j] = entry10_->xypar[i][j]; + xypary0x1_[i][j] = entry01_->xypar[i][j]; + lanpar_[i][j] = entry00_->lanpar[i][j] + +adcota_*(entry01_->lanpar[i][j] - entry00_->lanpar[i][j]) + +adcotb_*(entry10_->lanpar[i][j] - entry00_->lanpar[i][j]); + } + } + } + + return success_; +} // interpolate + + +// ************************************************************************************************************************************* +//! Load template info for single angle point to invoke template reco for template generation +//! \param entry - (input) pointer to template entry +//! \param sizex - (input) pixel x-size +//! \param sizey - (input) pixel y-size +//! \param sizez - (input) pixel z-size +// ************************************************************************************************************************************* + +void SiPixelTemplate2D::sideload(SiPixelTemplateEntry2D* entry, int iDtype, float locBx, float locBz, float lorwdy, float lorwdx, float q50, float fbin[3], float xsize, float ysize, float zsize) +{ + + // Set class variables to the input parameters + + entry00_ = entry; + entry01_ = entry; + entry10_ = entry; + Dtype_ = iDtype; + lorywidth_ = lorwdy; + lorxwidth_ = lorwdx; + xsize_ = xsize; + ysize_ = ysize; + zsize_ = zsize; + s50_ = q50; + qscale_ = 1.f; + for(int i=0; i<3; ++i) {fbin_[i] = fbin[i];} + + // Set other class variables + + adcota_ = 0.f; + adcotb_ = 0.f; + + // Interpolate things in cot(alpha)-cot(beta) + + qavg_ = entry00_->qavg; + + pixmax_ = entry00_->pixmax; + + sxymax_ = entry00_->sxymax; + + clsleny_ = entry00_->clsleny; + + clslenx_ = entry00_->clslenx; + + scaleyavg_ = 1.f; + + scalexavg_ = 1.f; + + delyavg_ = 0.f; + + delysig_ = 0.f; + + for(int i=0; i<4 ; ++i) { + scalex_[i] = 1.f; + scaley_[i] = 1.f; + offsetx_[i] = 0.f; + offsety_[i] = 0.f; + } + + // This works only for IP-related tracks + + flip_x_ = false; + flip_y_ = false; + float cotbeta = entry00_->cotbeta; + switch(Dtype_) { + case 0: + if(cotbeta < 0.f) {flip_y_ = true;} + break; + case 1: + if(locBz > 0.f) { + flip_y_ = true; + } + break; + case 2: + case 3: + case 4: + case 5: + if(locBx*locBz < 0.f) { + flip_x_ = true; + } + if(locBx < 0.f) { + flip_y_ = true; + } + break; + default: +#ifndef SI_PIXEL_TEMPLATE_STANDALONE + throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::illegal subdetector ID = " << iDtype << std::endl; +#else + std::cout << "SiPixelTemplate:2D:illegal subdetector ID = " << iDtype << std::endl; +#endif + } + + // Calculate signed quantities + + lorydrift_ = lorywidth_/2.; + if(flip_y_) lorydrift_ = -lorydrift_; + lorxdrift_ = lorxwidth_/2.; + if(flip_x_) lorxdrift_ = -lorxdrift_; + + for(int i=0; i<2 ; ++i) { + for(int j=0; j<5 ; ++j) { + // Charge loss switches sides when cot(beta) changes sign + if(flip_y_) { + xypary0x0_[1-i][j] = entry00_->xypar[i][j]; + xypary1x0_[1-i][j] = entry00_->xypar[i][j]; + xypary0x1_[1-i][j] = entry00_->xypar[i][j]; + lanpar_[1-i][j] = entry00_->lanpar[i][j]; + } else { + xypary0x0_[i][j] = entry00_->xypar[i][j]; + xypary1x0_[i][j] = entry00_->xypar[i][j]; + xypary0x1_[i][j] = entry00_->xypar[i][j]; + lanpar_[i][j] = entry00_->lanpar[i][j]; + } + } + } + return; +} + + +// ************************************************************************************************************************************* +//! \param xhit - (input) x-position of hit relative to the lower left corner of pixel[1][1] (to allow for the "padding" of the two-d clusters in the splitter) +//! \param yhit - (input) y-position of hit relative to the lower left corner of pixel[1][1] +//! \param ydouble - (input) STL vector of 21 element array to flag a double-pixel starting at cluster[1][1] +//! \param xdouble - (input) STL vector of 11 element array to flag a double-pixel starting at cluster[1][1] +//! \param template2d - (output) 2d template of size matched to the cluster. Input must be zeroed since charge is added only. +// ************************************************************************************************************************************* + +bool SiPixelTemplate2D::xytemp(float xhit, float yhit, bool ydouble[BYM2], bool xdouble[BXM2], float template2d[BXM2][BYM2], bool derivatives, float dpdx2d[2][BXM2][BYM2], float& QTemplate) +{ + // Interpolate for a new set of track angles + + // Local variables + int i, j, k; + int pixx, pixy, k0, k1, l0, l1, deltax, deltay, iflipy, jflipx, imin, imax, jmin, jmax; + int m, n; + float dx, dy, ddx, ddy, adx, ady, tmpxy; +// const float deltaxy[2] = {8.33f, 12.5f}; + const float deltaxy[2] = {16.67f, 25.0f}; + + // Check to see if interpolation is valid + + + // next, determine the indices of the closest point in k (y-displacement), l (x-displacement) + // pixy and pixx are the indices of the struck pixel in the (Ty,Tx) system + // k0,k1 are the k-indices of the closest and next closest point + // l0,l1 are the l-indices of the closest and next closest point + + pixy = (int)floorf(yhit/ysize_); + dy = yhit-(pixy+0.5f)*ysize_; + if(flip_y_) {dy = -dy;} + k0 = (int)(dy/ysize_*6.f+3.5f); + if(k0 < 0) k0 = 0; + if(k0 > 6) k0 = 6; + ddy = 6.f*dy/ysize_ - (k0-3); + ady = fabs(ddy); + if(ddy > 0.f) {k1 = k0 + 1; if(k1 > 6) k1 = k0-1;} else {k1 = k0 - 1; if(k1 < 0) k1 = k0+1;} + pixx = (int)floorf(xhit/xsize_); + dx = xhit-(pixx+0.5f)*xsize_; + if(flip_x_) {dx = -dx;} + l0 = (int)(dx/xsize_*6.f+3.5f); + if(l0 < 0) l0 = 0; + if(l0 > 6) l0 = 6; + ddx = 6.f*dx/xsize_ - (l0-3); + adx = fabs(ddx); + if(ddx > 0.f) {l1 = l0 + 1; if(l1 > 6) l1 = l0-1;} else {l1 = l0 - 1; if(l1 < 0) l1 = l0+1;} + + // OK, lets do the template interpolation. + + // First find the limits of the indices for non-zero pixels + + imin = std::min(entry00_->iymin,entry10_->iymin); + imin_ = std::min(imin,entry01_->iymin); + + jmin = std::min(entry00_->jxmin,entry10_->jxmin); + jmin_ = std::min(jmin,entry01_->jxmin); + + imax = std::max(entry00_->iymax,entry10_->iymax); + imax_ = std::max(imax,entry01_->iymax); + + jmax = std::max(entry00_->jxmax,entry10_->jxmax); + jmax_ = std::max(jmax,entry01_->jxmax); + + // Calculate the x and y offsets to make the new template + + // First, shift the struck pixel coordinates to the (Ty+2, Tx+2) system + + ++pixy; ++pixx; + + // In the template store, the struck pixel is always (THy,THx) + + deltax = pixx - T2HX; + deltay = pixy - T2HY; + + // First zero the local 2-d template + + for(j=0; j=0 && m<=BXM3 && n>=0 && n<=BYM3) { + tmpxy = entry00_->xytemp[k0][l0][i][j] + + adx*(entry00_->xytemp[k0][l1][i][j] - entry00_->xytemp[k0][l0][i][j]) + + ady*(entry00_->xytemp[k1][l0][i][j] - entry00_->xytemp[k0][l0][i][j]) + + adcota_*(entry01_->xytemp[k0][l0][i][j] - entry00_->xytemp[k0][l0][i][j]) + + adcotb_*(entry10_->xytemp[k0][l0][i][j] - entry00_->xytemp[k0][l0][i][j]); + if(tmpxy > 0.f) { + xytemp_[m][n] = tmpxy; + } else { + xytemp_[m][n] = 0.f; + } + } + } + } + + //combine rows and columns to simulate double pixels + + for(n=1; n 0.f) {template2d[m][n] += xytemp_[m][n]; qtemptot += xytemp_[m][n];} + } + } + + QTemplate = qtemptot; + + if(derivatives) { + + float dxytempdx[2][BXM2][BYM2], dxytempdy[2][BXM2][BYM2]; + + // First do shifted +x template + + pixx = (int)floorf((xhit+deltaxy[0])/xsize_); + dx = (xhit+deltaxy[0])-(pixx+0.5f)*xsize_; + if(flip_x_) {dx = -dx;} + l0 = (int)(dx/xsize_*6.f+3.5f); + if(l0 < 0) l0 = 0; + if(l0 > 6) l0 = 6; + ddx = 6.f*dx/xsize_ - (l0-3); + adx = fabs(ddx); + if(ddx > 0.f) {l1 = l0 + 1; if(l1 > 6) l1 = l0-1;} else {l1 = l0 - 1; if(l1 < 0) l1 = l0+1;} + + // OK, lets do the template interpolation. + + // Calculate the x and y offsets to make the new template + + // First, shift the struck pixel coordinates to the (Ty+2, Tx+2) system + + ++pixx; + + // In the template store, the struck pixel is always (THy,THx) + + deltax = pixx - T2HX; + + // First zero the local 2-d template + + for(k=0; k<2; ++k) {for(j=0; j=0 && m<=BXM3 && n>=0 && n<=BYM3) { + tmpxy = entry00_->xytemp[k0][l0][i][j] + + adx*(entry00_->xytemp[k0][l1][i][j] - entry00_->xytemp[k0][l0][i][j]) + + ady*(entry00_->xytemp[k1][l0][i][j] - entry00_->xytemp[k0][l0][i][j]) + + adcota_*(entry01_->xytemp[k0][l0][i][j] - entry00_->xytemp[k0][l0][i][j]) + + adcotb_*(entry10_->xytemp[k0][l0][i][j] - entry00_->xytemp[k0][l0][i][j]); + if(tmpxy > 0.f) {dxytempdx[1][m][n] = tmpxy;} else {dxytempdx[1][m][n] = 0.f;} + } + } + } + + //combine rows and columns to simulate double pixels + + for(n=1; n 6) l0 = 6; + ddx = 6.f*dx/xsize_ - (l0-3); + adx = fabs(ddx); + if(ddx > 0.f) {l1 = l0 + 1; if(l1 > 6) l1 = l0-1;} else {l1 = l0 - 1; if(l1 < 0) l1 = l0+1;} + + // OK, lets do the template interpolation. + + // Calculate the x and y offsets to make the new template + + // First, shift the struck pixel coordinates to the (Ty+2, Tx+2) system + + ++pixx; + + // In the template store, the struck pixel is always (THy,THx) + + deltax = pixx - T2HX; + + // Loop over the non-zero part of the template index space and interpolate + + for(j=jmin_; j<=jmax_; ++j) { + // Flip indices as needed + if(flip_x_) {jflipx=T2XSIZE-1-j; m = deltax+jflipx;} else {m = deltax+j;} + for(i=imin_; i<=imax_; ++i) { + if(flip_y_) {iflipy=T2YSIZE-1-i; n = deltay+iflipy;} else {n = deltay+i;} + if(m>=0 && m<=BXM3 && n>=0 && n<=BYM3) { + tmpxy = entry00_->xytemp[k0][l0][i][j] + + adx*(entry00_->xytemp[k0][l1][i][j] - entry00_->xytemp[k0][l0][i][j]) + + ady*(entry00_->xytemp[k1][l0][i][j] - entry00_->xytemp[k0][l0][i][j]) + + adcota_*(entry01_->xytemp[k0][l0][i][j] - entry00_->xytemp[k0][l0][i][j]) + + adcotb_*(entry10_->xytemp[k0][l0][i][j] - entry00_->xytemp[k0][l0][i][j]); + if(tmpxy > 0.f) {dxytempdx[0][m][n] = tmpxy;} else {dxytempdx[0][m][n] = 0.f;} + } + } + } + + //combine rows and columns to simulate double pixels + + for(n=1; n 6) k0 = 6; + ddy = 6.f*dy/ysize_ - (k0-3); + ady = fabs(ddy); + if(ddy > 0.f) {k1 = k0 + 1; if(k1 > 6) k1 = k0-1;} else {k1 = k0 - 1; if(k1 < 0) k1 = k0+1;} + pixx = (int)floorf(xhit/xsize_); + dx = xhit-(pixx+0.5f)*xsize_; + if(flip_x_) {dx = -dx;} + l0 = (int)(dx/xsize_*6.f+3.5f); + if(l0 < 0) l0 = 0; + if(l0 > 6) l0 = 6; + ddx = 6.f*dx/xsize_ - (l0-3); + adx = fabs(ddx); + if(ddx > 0.f) {l1 = l0 + 1; if(l1 > 6) l1 = l0-1;} else {l1 = l0 - 1; if(l1 < 0) l1 = l0+1;} + + // OK, lets do the template interpolation. + + // Calculate the x and y offsets to make the new template + + // First, shift the struck pixel coordinates to the (Ty+2, Tx+2) system + + ++pixy; ++pixx; + + // In the template store, the struck pixel is always (THy,THx) + + deltax = pixx - T2HX; + deltay = pixy - T2HY; + + // First zero the local 2-d template + + for(k=0; k<2; ++k) {for(j=0; j=0 && m<=BXM3 && n>=0 && n<=BYM3) { + tmpxy = entry00_->xytemp[k0][l0][i][j] + + adx*(entry00_->xytemp[k0][l1][i][j] - entry00_->xytemp[k0][l0][i][j]) + + ady*(entry00_->xytemp[k1][l0][i][j] - entry00_->xytemp[k0][l0][i][j]) + + adcota_*(entry01_->xytemp[k0][l0][i][j] - entry00_->xytemp[k0][l0][i][j]) + + adcotb_*(entry10_->xytemp[k0][l0][i][j] - entry00_->xytemp[k0][l0][i][j]); + if(tmpxy > 0.f) {dxytempdy[1][m][n] = tmpxy;} else {dxytempdy[1][m][n] = 0.f;} + } + } + } + + //combine rows and columns to simulate double pixels + + for(n=1; n 6) k0 = 6; + ddy = 6.f*dy/ysize_ - (k0-3); + ady = fabs(ddy); + if(ddy > 0.f) {k1 = k0 + 1; if(k1 > 6) k1 = k0-1;} else {k1 = k0 - 1; if(k1 < 0) k1 = k0+1;} + + // OK, lets do the template interpolation. + + // Calculate the x and y offsets to make the new template + + // First, shift the struck pixel coordinates to the (Ty+2, Tx+2) system + + ++pixy; + + // In the template store, the struck pixel is always (THy,THx) + + deltay = pixy - T2HY; + + // Loop over the non-zero part of the template index space and interpolate + + for(j=jmin_; j<=jmax_; ++j) { + // Flip indices as needed + if(flip_x_) {jflipx=T2XSIZE-1-j; m = deltax+jflipx;} else {m = deltax+j;} + for(i=imin_; i<=imax_; ++i) { + if(flip_y_) {iflipy=T2YSIZE-1-i; n = deltay+iflipy;} else {n = deltay+i;} + if(m>=0 && m<=BXM3 && n>=0 && n<=BYM3) { + tmpxy = entry00_->xytemp[k0][l0][i][j] + + adx*(entry00_->xytemp[k0][l1][i][j] - entry00_->xytemp[k0][l0][i][j]) + + ady*(entry00_->xytemp[k1][l0][i][j] - entry00_->xytemp[k0][l0][i][j]) + + adcota_*(entry01_->xytemp[k0][l0][i][j] - entry00_->xytemp[k0][l0][i][j]) + + adcotb_*(entry10_->xytemp[k0][l0][i][j] - entry00_->xytemp[k0][l0][i][j]); + if(tmpxy > 0.f) {dxytempdy[0][m][n] = tmpxy;} else {dxytempdy[0][m][n] = 0.f;} + } + } + } + + //combine rows and columns to simulate double pixels + + for(n=1; n& ydouble, std::vector& xdouble, float template2d[BXM2][BYM2]) +{ + + // Local variables + + bool derivatives = false; + float dpdx2d[2][BXM2][BYM2]; + float QTemplate; + float locBx = 1.f; + if(cotbeta < 0.f) {locBx = -1.f;} + float locBz = locBx; + if(cotalpha < 0.f) {locBz = -locBx;} + + bool yd[BYM2], xd[BXM2]; + + yd[0] = false; yd[BYM2-1] = false; + for(int i=0; i= BYM2) { + throw cms::Exception("DataCorrupt") << "SiPixelTemplate2D::ysigma2 called with index = " << index << std::endl; + } +#else + assert(index > 0 && index < BYM2); +#endif + + // Define the maximum signal to use in the parameterization + + // Evaluate pixel-by-pixel uncertainties (weights) for the templ analysis + + if(qpixel < sxymax_) { + sigi = qpixel; + qscale = 1.f; + } else { + sigi = sxymax_; + qscale = qpixel/sxymax_; + } + sigi2 = sigi*sigi; sigi3 = sigi2*sigi; sigi4 = sigi3*sigi; + if(index <= T2HYP1) { + err00 = xypary0x0_[0][0]+xypary0x0_[0][1]*sigi+xypary0x0_[0][2]*sigi2+xypary0x0_[0][3]*sigi3+xypary0x0_[0][4]*sigi4; + err2 = err00 + +adcota_*(xypary0x1_[0][0]+xypary0x1_[0][1]*sigi+xypary0x1_[0][2]*sigi2+xypary0x1_[0][3]*sigi3+xypary0x1_[0][4]*sigi4 - err00) + +adcotb_*(xypary1x0_[0][0]+xypary1x0_[0][1]*sigi+xypary1x0_[0][2]*sigi2+xypary1x0_[0][3]*sigi3+xypary1x0_[0][4]*sigi4 - err00); + } else { + err00 = xypary0x0_[1][0]+xypary0x0_[1][1]*sigi+xypary0x0_[1][2]*sigi2+xypary0x0_[1][3]*sigi3+xypary0x0_[1][4]*sigi4; + err2 = err00 + +adcota_*(xypary0x1_[1][0]+xypary0x1_[1][1]*sigi+xypary0x1_[1][2]*sigi2+xypary0x1_[1][3]*sigi3+xypary0x1_[1][4]*sigi4 - err00) + +adcotb_*(xypary1x0_[1][0]+xypary1x0_[1][1]*sigi+xypary1x0_[1][2]*sigi2+xypary1x0_[1][3]*sigi3+xypary1x0_[1][4]*sigi4 - err00); + } + xysig2 =qscale*err2; + if(xysig2 <= 0.f) {LOGERROR("SiPixelTemplate2D") << "neg y-error-squared, id = " << id_current_ << ", index = " << index_id_ << + ", cot(alpha) = " << cota_current_ << ", cot(beta) = " << cotb_current_ << ", sigi = " << sigi << ENDL;} + + return; + +} // End xysigma2 + + +// ************************************************************************************************************ +//! Return the Landau probability parameters for this set of cot(alpha, cot(beta) +// ************************************************************************************************************ +void SiPixelTemplate2D::landau_par(float lanpar[2][5]) + +{ + // Interpolate using quantities already stored in the private variables + + // Local variables + int i,j; + for(i=0; i<2; ++i) { + for(j=0; j<5; ++j) { + lanpar[i][j] = lanpar_[i][j]; + } + } + return; + +} // End lan_par + + +