CMS 3D CMS Logo

SiPixelTemplate.cc
Go to the documentation of this file.
1 //
2 // SiPixelTemplate.cc Version 10.00
3 //
4 // Add goodness-of-fit info and spare entries to templates, version number in template header, more error checking
5 // Add correction for (Q_F-Q_L)/(Q_F+Q_L) bias
6 // Add cot(beta) reflection to reduce y-entries and more sophisticated x-interpolation
7 // Fix small index searching bug in interpolate method
8 // Change interpolation indexing to avoid complier complaining about possible un-initialized variables
9 // Replace containers with static arrays in calls to ysigma2 and xsigma2
10 // Add external threshold to calls to ysigma2 and xsigma2, fix parameter signal max for xsigma2
11 // Return to 5 pixel spanning but adjust boundaries to use only when needed
12 // Implement improved (faster) chi2min search that depends on pixel types
13 // Fill template arrays in single calls to this object
14 // Add qmin to the template
15 // Add qscale to match charge scales
16 // Small improvement to x-chisquare interpolation
17 // Enlarge SiPixelTemplateStore to accommodate larger templates and increased alpha acceptance (reduce PT threshold to ~200 MeV)
18 // Change output streams to conform to CMSSW info and error logging.
19 // Store x and y cluster sizes in fractional pixels to facilitate cluster splitting
20 // Add methods to return 3-d templates needed for cluster splitting
21 // Keep interpolated central 9 template bins in private storage and expand/shift in the getter functions (faster for speed=2/3) and easier to build 3d templates
22 // Store error and bias information for the simple chi^2 min position analysis (no interpolation or Q_{FB} corrections) to use in cluster splitting
23 // To save time, the gaussian centers and sigma are not interpolated right now (they aren't currently used). They can be restored by un-commenting lines in the interpolate method.
24 // Add a new method to calculate qbin for input cotbeta and cluster charge. To be used for error estimation of merged clusters in PixelCPEGeneric.
25 // Improve the charge estimation for larger cot(alpha) tracks
26 // Change interpolate method to return false boolean if track angles are outside of range
27 // Add template info and method for truncation information
28 // Change to allow template sizes to be changed at compile time
29 // Fix bug in track angle checking
30 // Accommodate Dave's new DB pushfile which overloads the old method (file input)
31 // Add CPEGeneric error information and expand qbin method to access useful info for PixelCPEGeneric
32 // Fix large cot(alpha) bug in qmin interpolation
33 // Add second qmin to allow a qbin=5 state
34 // Use interpolated chi^2 info for one-pixel clusters
35 // Fix DB pushfile version number checking bug.
36 // Remove assert from qbin method
37 // Replace asserts with exceptions in CMSSW
38 // Change calling sequence to interpolate method to handle cot(beta)<0 for FPix cosmics
39 // Add getter for pixelav Lorentz width estimates to qbin method
40 // Add check on template size to interpolate and qbin methods
41 // Add qbin population information, charge distribution information
42 //
43 //
44 // V7.00 - Decouple BPix and FPix information into separate templates
45 // Add methods to facilitate improved cluster splitting
46 // Fix small charge scaling bug (affects FPix only)
47 // Change y-slice used for the x-template to be closer to the actual cotalpha-cotbeta point
48 // (there is some weak breakdown of x-y factorization in the FPix after irradiation)
49 //
50 //
51 // V8.00 - Add method to calculate a simple 2D template
52 // Reorganize the interpolate method to extract header info only once per ID
53 // V8.01 - Improve simple template normalization
54 // V8.05 - Change qbin normalization to work better after irradiation
55 // V8.10 - Add Vavilov distribution interpolation
56 // V8.11 - Renormalize the x-templates for Guofan's cluster size calculation
57 // V8.12 - Technical fix to qavg issue.
58 // V8.13 - Fix qbin and fastsim interpolaters to avoid changing class variables
59 // V8.20 - Add methods to identify the central pixels in the x- and y-templates (to help align templates with clusters in radiation damaged detectors)
60 // Rename class variables from pxxxx (private xxxx) to xxxx_ to follow standard convention.
61 // Add compiler option to store the template entries in BOOST multiarrays of structs instead of simple c arrays
62 // (allows dynamic resizing template storage and has bounds checking but costs ~10% in execution time).
63 // V8.21 - Add new qbin method to use in cluster splitting
64 // V8.23 - Replace chi-min position errors with merged cluster chi2 probability info
65 // V8.25 - Incorporate VI's speed changes into the current version
66 // V8.26 - Modify the Vavilov lookups to work better with the FPix (offset y-templates)
67 // V8.30 - Change the splitting template generation and access to improve speed and eliminate triple index boost::multiarray
68 // V8.31 - Add correction factor: measured/true charge
69 // V8.31 - Fix version number bug in db object I/O (pushfile)
70 // V8.32 - Check for illegal qmin during loading
71 // V8.33 - Fix small type conversion warnings
72 // V8.40 - Incorporate V.I. optimizations
73 // V9.00 - Expand header to include multi and single dcol thresholds, LA biases, and (variable) Qbin definitions
74 // V9.01 - Protect against negative error squared
75 // V10.00 - Update to work with Phase 1 FPix. Fix some code problems introduced by other maintainers.
76 
77 
78 // Created by Morris Swartz on 10/27/06.
79 //
80 //
81 
82 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
83 #include <cmath>
84 #else
85 #include <math.h>
86 #endif
87 #include <algorithm>
88 #include <vector>
89 //#include "boost/multi_array.hpp"
90 #include <iostream>
91 #include <iomanip>
92 #include <sstream>
93 #include <fstream>
94 #include <list>
95 
96 
97 
98 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
103 #define LOGERROR(x) LogError(x)
104 #define LOGINFO(x) LogInfo(x)
105 #define LOGWARNING(x) LogWarning(x)
106 #define ENDL " "
108 using namespace edm;
109 #else
110 #include "SiPixelTemplate.h"
111 #include "SimplePixel.h"
112 #define LOGERROR(x) std::cout << x << ": "
113 #define LOGINFO(x) std::cout << x << ": "
114 #define ENDL std::endl
115 #endif
116 
117 //****************************************************************
122 //****************************************************************
123 bool SiPixelTemplate::pushfile(int filenum, std::vector< SiPixelTemplateStore > & thePixelTemp_)
124 {
125  // Add template stored in external file numbered filenum to theTemplateStore
126 
127  // Local variables
128  int i, j, k, l;
129  float qavg_avg;
130  const char *tempfile;
131  // char title[80]; remove this
132  char c;
133  const int code_version={17};
134 
135 
136 
137  // Create a filename for this run
138 
139  std::ostringstream tout;
140 
141  // Create different path in CMSSW than standalone
142 
143 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
144  tout << "CalibTracker/SiPixelESProducers/data/template_summary_zp"
145  << std::setw(4) << std::setfill('0') << std::right << filenum << ".out" << std::ends;
146  std::string tempf = tout.str();
147  edm::FileInPath file( tempf.c_str() );
148  tempfile = (file.fullPath()).c_str();
149 #else
150  tout << "template_summary_zp" << std::setw(4) << std::setfill('0') << std::right << filenum << ".out" << std::ends;
151  std::string tempf = tout.str();
152  tempfile = tempf.c_str();
153 #endif
154 
155  // open the template file
156 
157  std::ifstream in_file(tempfile, std::ios::in);
158 
159  if(in_file.is_open()) {
160 
161  // Create a local template storage entry
162 
163  SiPixelTemplateStore theCurrentTemp;
164 
165  // Read-in a header string first and print it
166 
167  for (i=0; (c=in_file.get()) != '\n'; ++i) {
168  if(i < 79) {theCurrentTemp.head.title[i] = c;}
169  }
170  if(i > 78) {i=78;}
171  theCurrentTemp.head.title[i+1] ='\0';
172  LOGINFO("SiPixelTemplate") << "Loading Pixel Template File - " << theCurrentTemp.head.title << ENDL;
173 
174  // next, the header information
175 
176  in_file >> theCurrentTemp.head.ID >> theCurrentTemp.head.templ_version >> theCurrentTemp.head.Bfield >> theCurrentTemp.head.NTy >> theCurrentTemp.head.NTyx >> theCurrentTemp.head.NTxx
177  >> theCurrentTemp.head.Dtype >> theCurrentTemp.head.Vbias >> theCurrentTemp.head.temperature >> theCurrentTemp.head.fluence >> theCurrentTemp.head.qscale
178  >> theCurrentTemp.head.s50 >> theCurrentTemp.head.lorywidth >> theCurrentTemp.head.lorxwidth >> theCurrentTemp.head.ysize >> theCurrentTemp.head.xsize >> theCurrentTemp.head.zsize;
179 
180  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 0A, no template load" << ENDL; return false;}
181 
182  if(theCurrentTemp.head.templ_version > 17) {
183  in_file >> theCurrentTemp.head.ss50 >> theCurrentTemp.head.lorybias
184  >> theCurrentTemp.head.lorxbias >> theCurrentTemp.head.fbin[0]
185  >> theCurrentTemp.head.fbin[1] >> theCurrentTemp.head.fbin[2];
186 
187  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 0B, no template load"
188  << ENDL; return false;}
189  } else {
190  theCurrentTemp.head.ss50 = theCurrentTemp.head.s50;
191  theCurrentTemp.head.lorybias = theCurrentTemp.head.lorywidth/2.f;
192  theCurrentTemp.head.lorxbias = theCurrentTemp.head.lorxwidth/2.f;
193  theCurrentTemp.head.fbin[0] = 1.5f;
194  theCurrentTemp.head.fbin[1] = 1.00f;
195  theCurrentTemp.head.fbin[2] = 0.85f;
196  }
197 
198  LOGINFO("SiPixelTemplate") << "Template ID = " << theCurrentTemp.head.ID << ", Template Version " << theCurrentTemp.head.templ_version << ", Bfield = " << theCurrentTemp.head.Bfield
199  << ", NTy = " << theCurrentTemp.head.NTy << ", NTyx = " << theCurrentTemp.head.NTyx<< ", NTxx = " << theCurrentTemp.head.NTxx << ", Dtype = " << theCurrentTemp.head.Dtype
200  << ", Bias voltage " << theCurrentTemp.head.Vbias << ", temperature "
201  << theCurrentTemp.head.temperature << ", fluence " << theCurrentTemp.head.fluence << ", Q-scaling factor " << theCurrentTemp.head.qscale
202  << ", 1/2 multi dcol threshold " << theCurrentTemp.head.s50 << ", 1/2 single dcol threshold " << theCurrentTemp.head.ss50
203  << ", y Lorentz Width " << theCurrentTemp.head.lorywidth << ", y Lorentz Bias " << theCurrentTemp.head.lorybias
204  << ", x Lorentz width " << theCurrentTemp.head.lorxwidth << ", x Lorentz Bias " << theCurrentTemp.head.lorxbias
205  << ", Q/Q_avg fractions for Qbin defs " << theCurrentTemp.head.fbin[0] << ", " << theCurrentTemp.head.fbin[1]
206  << ", " << theCurrentTemp.head.fbin[2]
207  << ", pixel x-size " << theCurrentTemp.head.xsize << ", y-size " << theCurrentTemp.head.ysize << ", zsize " << theCurrentTemp.head.zsize << ENDL;
208 
209 
210  if(theCurrentTemp.head.templ_version < code_version) {LOGERROR("SiPixelTemplate") << "code expects version " << code_version << " finds "<< theCurrentTemp.head.templ_version <<", no template load" << ENDL; return false;}
211 
212 #ifdef SI_PIXEL_TEMPLATE_USE_BOOST
213 
214  // next, layout the 1-d/2-d structures needed to store template
215 
216  theCurrentTemp.enty.resize(boost::extents[theCurrentTemp.head.NTy]);
217 
218  theCurrentTemp.entx.resize(boost::extents[theCurrentTemp.head.NTyx][theCurrentTemp.head.NTxx]);
219 
220 #endif
221 
222  // next, loop over all y-angle entries
223 
224  for (i=0; i < theCurrentTemp.head.NTy; ++i) {
225 
226  in_file >> theCurrentTemp.enty[i].runnum >> theCurrentTemp.enty[i].costrk[0]
227  >> theCurrentTemp.enty[i].costrk[1] >> theCurrentTemp.enty[i].costrk[2];
228 
229  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 1, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
230 
231  // Calculate the alpha, beta, and cot(beta) for this entry
232 
233  theCurrentTemp.enty[i].alpha = static_cast<float>(atan2((double)theCurrentTemp.enty[i].costrk[2], (double)theCurrentTemp.enty[i].costrk[0]));
234 
235  theCurrentTemp.enty[i].cotalpha = theCurrentTemp.enty[i].costrk[0]/theCurrentTemp.enty[i].costrk[2];
236 
237  theCurrentTemp.enty[i].beta = static_cast<float>(atan2((double)theCurrentTemp.enty[i].costrk[2], (double)theCurrentTemp.enty[i].costrk[1]));
238 
239  theCurrentTemp.enty[i].cotbeta = theCurrentTemp.enty[i].costrk[1]/theCurrentTemp.enty[i].costrk[2];
240 
241  in_file >> theCurrentTemp.enty[i].qavg >> theCurrentTemp.enty[i].pixmax >> theCurrentTemp.enty[i].symax >> theCurrentTemp.enty[i].dyone
242  >> theCurrentTemp.enty[i].syone >> theCurrentTemp.enty[i].sxmax >> theCurrentTemp.enty[i].dxone >> theCurrentTemp.enty[i].sxone;
243 
244  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 2, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
245 
246  in_file >> theCurrentTemp.enty[i].dytwo >> theCurrentTemp.enty[i].sytwo >> theCurrentTemp.enty[i].dxtwo
247  >> theCurrentTemp.enty[i].sxtwo >> theCurrentTemp.enty[i].qmin >> theCurrentTemp.enty[i].clsleny >> theCurrentTemp.enty[i].clslenx;
248 
249  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 3, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
250 
251 
252  if(theCurrentTemp.enty[i].qmin <= 0.) {LOGERROR("SiPixelTemplate") << "Error in template ID " << theCurrentTemp.head.ID << " qmin = " << theCurrentTemp.enty[i].qmin << ", run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
253 
254 
255  for (j=0; j<2; ++j) {
256 
257  in_file >> theCurrentTemp.enty[i].ypar[j][0] >> theCurrentTemp.enty[i].ypar[j][1]
258  >> theCurrentTemp.enty[i].ypar[j][2] >> theCurrentTemp.enty[i].ypar[j][3] >> theCurrentTemp.enty[i].ypar[j][4];
259 
260  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 4, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
261 
262  }
263 
264  for (j=0; j<9; ++j) {
265 
266  for (k=0; k<TYSIZE; ++k) {in_file >> theCurrentTemp.enty[i].ytemp[j][k];}
267 
268  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 5, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
269  }
270 
271  for (j=0; j<2; ++j) {
272 
273  in_file >> theCurrentTemp.enty[i].xpar[j][0] >> theCurrentTemp.enty[i].xpar[j][1]
274  >> theCurrentTemp.enty[i].xpar[j][2] >> theCurrentTemp.enty[i].xpar[j][3] >> theCurrentTemp.enty[i].xpar[j][4];
275 
276  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 6, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
277 
278  }
279 
280  qavg_avg = 0.f;
281  for (j=0; j<9; ++j) {
282 
283  for (k=0; k<TXSIZE; ++k) {in_file >> theCurrentTemp.enty[i].xtemp[j][k]; qavg_avg += theCurrentTemp.enty[i].xtemp[j][k];}
284 
285  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 7, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
286  }
287  theCurrentTemp.enty[i].qavg_avg = qavg_avg/9.;
288 
289  for (j=0; j<4; ++j) {
290 
291  in_file >> theCurrentTemp.enty[i].yavg[j] >> theCurrentTemp.enty[i].yrms[j] >> theCurrentTemp.enty[i].ygx0[j] >> theCurrentTemp.enty[i].ygsig[j];
292 
293  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 8, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
294  }
295 
296  for (j=0; j<4; ++j) {
297 
298  in_file >> theCurrentTemp.enty[i].yflpar[j][0] >> theCurrentTemp.enty[i].yflpar[j][1] >> theCurrentTemp.enty[i].yflpar[j][2]
299  >> theCurrentTemp.enty[i].yflpar[j][3] >> theCurrentTemp.enty[i].yflpar[j][4] >> theCurrentTemp.enty[i].yflpar[j][5];
300 
301  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 9, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
302  }
303 
304  for (j=0; j<4; ++j) {
305 
306  in_file >> theCurrentTemp.enty[i].xavg[j] >> theCurrentTemp.enty[i].xrms[j] >> theCurrentTemp.enty[i].xgx0[j] >> theCurrentTemp.enty[i].xgsig[j];
307 
308  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 10, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
309  }
310 
311  for (j=0; j<4; ++j) {
312 
313  in_file >> theCurrentTemp.enty[i].xflpar[j][0] >> theCurrentTemp.enty[i].xflpar[j][1] >> theCurrentTemp.enty[i].xflpar[j][2]
314  >> theCurrentTemp.enty[i].xflpar[j][3] >> theCurrentTemp.enty[i].xflpar[j][4] >> theCurrentTemp.enty[i].xflpar[j][5];
315 
316  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 11, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
317  }
318 
319  for (j=0; j<4; ++j) {
320 
321  in_file >> theCurrentTemp.enty[i].chi2yavg[j] >> theCurrentTemp.enty[i].chi2ymin[j] >> theCurrentTemp.enty[i].chi2xavg[j] >> theCurrentTemp.enty[i].chi2xmin[j];
322 
323  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 12, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
324  }
325 
326  for (j=0; j<4; ++j) {
327 
328  in_file >> theCurrentTemp.enty[i].yavgc2m[j] >> theCurrentTemp.enty[i].yrmsc2m[j] >> theCurrentTemp.enty[i].chi2yavgc2m[j] >> theCurrentTemp.enty[i].chi2yminc2m[j];
329 
330  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 13, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
331  }
332 
333  for (j=0; j<4; ++j) {
334 
335  in_file >> theCurrentTemp.enty[i].xavgc2m[j] >> theCurrentTemp.enty[i].xrmsc2m[j] >> theCurrentTemp.enty[i].chi2xavgc2m[j] >> theCurrentTemp.enty[i].chi2xminc2m[j];
336 
337  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 14, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
338  }
339 
340  for (j=0; j<4; ++j) {
341 
342  in_file >> theCurrentTemp.enty[i].yavggen[j] >> theCurrentTemp.enty[i].yrmsgen[j] >> theCurrentTemp.enty[i].ygx0gen[j] >> theCurrentTemp.enty[i].ygsiggen[j];
343 
344  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 14a, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
345  }
346 
347  for (j=0; j<4; ++j) {
348 
349  in_file >> theCurrentTemp.enty[i].xavggen[j] >> theCurrentTemp.enty[i].xrmsgen[j] >> theCurrentTemp.enty[i].xgx0gen[j] >> theCurrentTemp.enty[i].xgsiggen[j];
350 
351  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 14b, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
352  }
353 
354  in_file >> theCurrentTemp.enty[i].chi2yavgone >> theCurrentTemp.enty[i].chi2yminone >> theCurrentTemp.enty[i].chi2xavgone >> theCurrentTemp.enty[i].chi2xminone >> theCurrentTemp.enty[i].qmin2
355  >> theCurrentTemp.enty[i].mpvvav >> theCurrentTemp.enty[i].sigmavav >> theCurrentTemp.enty[i].kappavav >> theCurrentTemp.enty[i].r_qMeas_qTrue >> theCurrentTemp.enty[i].spare[0];
356 
357  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 15, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
358 
359  in_file >> theCurrentTemp.enty[i].mpvvav2 >> theCurrentTemp.enty[i].sigmavav2 >> theCurrentTemp.enty[i].kappavav2 >> theCurrentTemp.enty[i].qbfrac[0] >> theCurrentTemp.enty[i].qbfrac[1]
360  >> theCurrentTemp.enty[i].qbfrac[2] >> theCurrentTemp.enty[i].fracyone >> theCurrentTemp.enty[i].fracxone >> theCurrentTemp.enty[i].fracytwo >> theCurrentTemp.enty[i].fracxtwo;
361  // theCurrentTemp.enty[i].qbfrac[3] = 1. - theCurrentTemp.enty[i].qbfrac[0] - theCurrentTemp.enty[i].qbfrac[1] - theCurrentTemp.enty[i].qbfrac[2];
362 
363  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 16, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
364 
365  }
366 
367  // next, loop over all barrel x-angle entries
368 
369  for (k=0; k < theCurrentTemp.head.NTyx; ++k) {
370 
371  for (i=0; i < theCurrentTemp.head.NTxx; ++i) {
372 
373  in_file >> theCurrentTemp.entx[k][i].runnum >> theCurrentTemp.entx[k][i].costrk[0]
374  >> theCurrentTemp.entx[k][i].costrk[1] >> theCurrentTemp.entx[k][i].costrk[2];
375 
376  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 17, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
377 
378  // Calculate the alpha, beta, and cot(beta) for this entry
379 
380  theCurrentTemp.entx[k][i].alpha = static_cast<float>(atan2((double)theCurrentTemp.entx[k][i].costrk[2], (double)theCurrentTemp.entx[k][i].costrk[0]));
381 
382  theCurrentTemp.entx[k][i].cotalpha = theCurrentTemp.entx[k][i].costrk[0]/theCurrentTemp.entx[k][i].costrk[2];
383 
384  theCurrentTemp.entx[k][i].beta = static_cast<float>(atan2((double)theCurrentTemp.entx[k][i].costrk[2], (double)theCurrentTemp.entx[k][i].costrk[1]));
385 
386  theCurrentTemp.entx[k][i].cotbeta = theCurrentTemp.entx[k][i].costrk[1]/theCurrentTemp.entx[k][i].costrk[2];
387 
388  in_file >> theCurrentTemp.entx[k][i].qavg >> theCurrentTemp.entx[k][i].pixmax >> theCurrentTemp.entx[k][i].symax >> theCurrentTemp.entx[k][i].dyone
389  >> theCurrentTemp.entx[k][i].syone >> theCurrentTemp.entx[k][i].sxmax >> theCurrentTemp.entx[k][i].dxone >> theCurrentTemp.entx[k][i].sxone;
390 
391  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 18, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
392 
393  in_file >> theCurrentTemp.entx[k][i].dytwo >> theCurrentTemp.entx[k][i].sytwo >> theCurrentTemp.entx[k][i].dxtwo
394  >> theCurrentTemp.entx[k][i].sxtwo >> theCurrentTemp.entx[k][i].qmin >> theCurrentTemp.entx[k][i].clsleny >> theCurrentTemp.entx[k][i].clslenx;
395  // >> theCurrentTemp.entx[k][i].mpvvav >> theCurrentTemp.entx[k][i].sigmavav >> theCurrentTemp.entx[k][i].kappavav;
396 
397  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 19, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
398 
399  for (j=0; j<2; ++j) {
400 
401  in_file >> theCurrentTemp.entx[k][i].ypar[j][0] >> theCurrentTemp.entx[k][i].ypar[j][1]
402  >> theCurrentTemp.entx[k][i].ypar[j][2] >> theCurrentTemp.entx[k][i].ypar[j][3] >> theCurrentTemp.entx[k][i].ypar[j][4];
403 
404  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 20, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
405  }
406 
407  for (j=0; j<9; ++j) {
408 
409  for (l=0; l<TYSIZE; ++l) {in_file >> theCurrentTemp.entx[k][i].ytemp[j][l];}
410 
411  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 21, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
412  }
413 
414  for (j=0; j<2; ++j) {
415 
416  in_file >> theCurrentTemp.entx[k][i].xpar[j][0] >> theCurrentTemp.entx[k][i].xpar[j][1]
417  >> theCurrentTemp.entx[k][i].xpar[j][2] >> theCurrentTemp.entx[k][i].xpar[j][3] >> theCurrentTemp.entx[k][i].xpar[j][4];
418 
419 
420  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 22, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
421  }
422 
423  qavg_avg = 0.f;
424  for (j=0; j<9; ++j) {
425 
426  for (l=0; l<TXSIZE; ++l) {in_file >> theCurrentTemp.entx[k][i].xtemp[j][l]; qavg_avg += theCurrentTemp.entx[k][i].xtemp[j][l];}
427 
428  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 23, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
429  }
430  theCurrentTemp.entx[k][i].qavg_avg = qavg_avg/9.;
431 
432  for (j=0; j<4; ++j) {
433 
434  in_file >> theCurrentTemp.entx[k][i].yavg[j] >> theCurrentTemp.entx[k][i].yrms[j] >> theCurrentTemp.entx[k][i].ygx0[j] >> theCurrentTemp.entx[k][i].ygsig[j];
435 
436  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 24, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
437  }
438 
439  for (j=0; j<4; ++j) {
440 
441  in_file >> theCurrentTemp.entx[k][i].yflpar[j][0] >> theCurrentTemp.entx[k][i].yflpar[j][1] >> theCurrentTemp.entx[k][i].yflpar[j][2]
442  >> theCurrentTemp.entx[k][i].yflpar[j][3] >> theCurrentTemp.entx[k][i].yflpar[j][4] >> theCurrentTemp.entx[k][i].yflpar[j][5];
443 
444  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 25, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
445  }
446 
447  for (j=0; j<4; ++j) {
448 
449  in_file >> theCurrentTemp.entx[k][i].xavg[j] >> theCurrentTemp.entx[k][i].xrms[j] >> theCurrentTemp.entx[k][i].xgx0[j] >> theCurrentTemp.entx[k][i].xgsig[j];
450 
451  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 26, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
452  }
453 
454  for (j=0; j<4; ++j) {
455 
456  in_file >> theCurrentTemp.entx[k][i].xflpar[j][0] >> theCurrentTemp.entx[k][i].xflpar[j][1] >> theCurrentTemp.entx[k][i].xflpar[j][2]
457  >> theCurrentTemp.entx[k][i].xflpar[j][3] >> theCurrentTemp.entx[k][i].xflpar[j][4] >> theCurrentTemp.entx[k][i].xflpar[j][5];
458 
459  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 27, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
460  }
461 
462  for (j=0; j<4; ++j) {
463 
464  in_file >> theCurrentTemp.entx[k][i].chi2yavg[j] >> theCurrentTemp.entx[k][i].chi2ymin[j] >> theCurrentTemp.entx[k][i].chi2xavg[j] >> theCurrentTemp.entx[k][i].chi2xmin[j];
465 
466  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 28, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
467  }
468 
469  for (j=0; j<4; ++j) {
470 
471  in_file >> theCurrentTemp.entx[k][i].yavgc2m[j] >> theCurrentTemp.entx[k][i].yrmsc2m[j] >> theCurrentTemp.entx[k][i].chi2yavgc2m[j] >> theCurrentTemp.entx[k][i].chi2yminc2m[j];
472 
473  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 29, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
474  }
475 
476  for (j=0; j<4; ++j) {
477 
478  in_file >> theCurrentTemp.entx[k][i].xavgc2m[j] >> theCurrentTemp.entx[k][i].xrmsc2m[j] >> theCurrentTemp.entx[k][i].chi2xavgc2m[j] >> theCurrentTemp.entx[k][i].chi2xminc2m[j];
479 
480  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 30, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
481  }
482 
483  for (j=0; j<4; ++j) {
484 
485  in_file >> theCurrentTemp.entx[k][i].yavggen[j] >> theCurrentTemp.entx[k][i].yrmsgen[j] >> theCurrentTemp.entx[k][i].ygx0gen[j] >> theCurrentTemp.entx[k][i].ygsiggen[j];
486 
487  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 30a, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
488  }
489 
490  for (j=0; j<4; ++j) {
491 
492  in_file >> theCurrentTemp.entx[k][i].xavggen[j] >> theCurrentTemp.entx[k][i].xrmsgen[j] >> theCurrentTemp.entx[k][i].xgx0gen[j] >> theCurrentTemp.entx[k][i].xgsiggen[j];
493 
494  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 30b, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
495  }
496 
497  in_file >> theCurrentTemp.entx[k][i].chi2yavgone >> theCurrentTemp.entx[k][i].chi2yminone >> theCurrentTemp.entx[k][i].chi2xavgone >> theCurrentTemp.entx[k][i].chi2xminone >> theCurrentTemp.entx[k][i].qmin2
498  >> theCurrentTemp.entx[k][i].mpvvav >> theCurrentTemp.entx[k][i].sigmavav >> theCurrentTemp.entx[k][i].kappavav >> theCurrentTemp.entx[k][i].r_qMeas_qTrue >> theCurrentTemp.entx[k][i].spare[0];
499 
500  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 31, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
501 
502  in_file >> theCurrentTemp.entx[k][i].mpvvav2 >> theCurrentTemp.entx[k][i].sigmavav2 >> theCurrentTemp.entx[k][i].kappavav2 >> theCurrentTemp.entx[k][i].qbfrac[0] >> theCurrentTemp.entx[k][i].qbfrac[1]
503  >> theCurrentTemp.entx[k][i].qbfrac[2] >> theCurrentTemp.entx[k][i].fracyone >> theCurrentTemp.entx[k][i].fracxone >> theCurrentTemp.entx[k][i].fracytwo >> theCurrentTemp.entx[k][i].fracxtwo;
504  // theCurrentTemp.entx[k][i].qbfrac[3] = 1. - theCurrentTemp.entx[k][i].qbfrac[0] - theCurrentTemp.entx[k][i].qbfrac[1] - theCurrentTemp.entx[k][i].qbfrac[2];
505 
506  if(in_file.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 32, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
507 
508  }
509  }
510 
511 
512  in_file.close();
513 
514  // Add this template to the store
515 
516  thePixelTemp_.push_back(theCurrentTemp);
517 
518  postInit(thePixelTemp_);
519  return true;
520 
521  } else {
522 
523  // If file didn't open, report this
524 
525  LOGERROR("SiPixelTemplate") << "Error opening File" << tempfile << ENDL;
526  return false;
527 
528  }
529 
530 } // TempInit
531 
532 
533 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
534 
535 
536 //****************************************************************
540 //****************************************************************
541 bool SiPixelTemplate::pushfile(const SiPixelTemplateDBObject& dbobject, std::vector< SiPixelTemplateStore > & thePixelTemp_)
542 {
543  // Add template stored in external dbobject to theTemplateStore
544 
545  // Local variables
546  int i, j, k, l;
547  float qavg_avg;
548  // const char *tempfile;
549  const int code_version={17};
550 
551  // We must create a new object because dbobject must be a const and our stream must not be
552  auto db(dbobject.reader());
553 
554  // Create a local template storage entry
555  SiPixelTemplateStore theCurrentTemp;
556 
557  // Fill the template storage for each template calibration stored in the db
558  for(int m=0; m<db.numOfTempl(); ++m) {
559 
560  // Read-in a header string first and print it
561 
563  for (i=0; i<20; ++i) {
564  temp.f = db.sVector()[db.index()];
565  theCurrentTemp.head.title[4*i] = temp.c[0];
566  theCurrentTemp.head.title[4*i+1] = temp.c[1];
567  theCurrentTemp.head.title[4*i+2] = temp.c[2];
568  theCurrentTemp.head.title[4*i+3] = temp.c[3];
569  db.incrementIndex(1);
570  }
571  theCurrentTemp.head.title[79] = '\0';
572  LOGINFO("SiPixelTemplate") << "Loading Pixel Template File - " << theCurrentTemp.head.title << ENDL;
573 
574  // next, the header information
575 
576  db >> theCurrentTemp.head.ID >> theCurrentTemp.head.templ_version >> theCurrentTemp.head.Bfield >> theCurrentTemp.head.NTy >> theCurrentTemp.head.NTyx >> theCurrentTemp.head.NTxx
577  >> theCurrentTemp.head.Dtype >> theCurrentTemp.head.Vbias >> theCurrentTemp.head.temperature >> theCurrentTemp.head.fluence >> theCurrentTemp.head.qscale
578  >> theCurrentTemp.head.s50 >> theCurrentTemp.head.lorywidth >> theCurrentTemp.head.lorxwidth >> theCurrentTemp.head.ysize >> theCurrentTemp.head.xsize >> theCurrentTemp.head.zsize;
579 
580  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 0A, no template load" << ENDL; return false;}
581 
582  LOGINFO("SiPixelTemplate") << "Loading Pixel Template File - " << theCurrentTemp.head.title
583  <<" code version = "<<code_version
584  <<" object version "<<theCurrentTemp.head.templ_version
585  << ENDL;
586 
587  if(theCurrentTemp.head.templ_version > 17) {
588  db >> theCurrentTemp.head.ss50 >> theCurrentTemp.head.lorybias >> theCurrentTemp.head.lorxbias >> theCurrentTemp.head.fbin[0] >> theCurrentTemp.head.fbin[1] >> theCurrentTemp.head.fbin[2];
589 
590  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 0B, no template load"
591  << ENDL; return false;}
592  } else {
593  theCurrentTemp.head.ss50 = theCurrentTemp.head.s50;
594  theCurrentTemp.head.lorybias = theCurrentTemp.head.lorywidth/2.f;
595  theCurrentTemp.head.lorxbias = theCurrentTemp.head.lorxwidth/2.f;
596  theCurrentTemp.head.fbin[0] = 1.50f;
597  theCurrentTemp.head.fbin[1] = 1.00f;
598  theCurrentTemp.head.fbin[2] = 0.85f;
599  //std::cout<<" set fbin "<< theCurrentTemp.head.fbin[0]<<" "<<theCurrentTemp.head.fbin[1]<<" "
600  // <<theCurrentTemp.head.fbin[2]<<std::endl;
601  }
602 
603  LOGINFO("SiPixelTemplate")
604  << "Template ID = " << theCurrentTemp.head.ID << ", Template Version "
605  << theCurrentTemp.head.templ_version << ", Bfield = "
606  << theCurrentTemp.head.Bfield<< ", NTy = " << theCurrentTemp.head.NTy << ", NTyx = "
607  << theCurrentTemp.head.NTyx<< ", NTxx = " << theCurrentTemp.head.NTxx << ", Dtype = "
608  << theCurrentTemp.head.Dtype<< ", Bias voltage " << theCurrentTemp.head.Vbias << ", temperature "
609  << theCurrentTemp.head.temperature << ", fluence " << theCurrentTemp.head.fluence
610  << ", Q-scaling factor " << theCurrentTemp.head.qscale
611  << ", 1/2 multi dcol threshold " << theCurrentTemp.head.s50 << ", 1/2 single dcol threshold "
612  << theCurrentTemp.head.ss50<< ", y Lorentz Width " << theCurrentTemp.head.lorywidth
613  << ", y Lorentz Bias " << theCurrentTemp.head.lorybias
614  << ", x Lorentz width " << theCurrentTemp.head.lorxwidth
615  << ", x Lorentz Bias " << theCurrentTemp.head.lorxbias
616  << ", Q/Q_avg fractions for Qbin defs " << theCurrentTemp.head.fbin[0]
617  << ", " << theCurrentTemp.head.fbin[1]
618  << ", " << theCurrentTemp.head.fbin[2]
619  << ", pixel x-size " << theCurrentTemp.head.xsize
620  << ", y-size " << theCurrentTemp.head.ysize << ", zsize " << theCurrentTemp.head.zsize << ENDL;
621 
622  if(theCurrentTemp.head.templ_version < code_version) {
623  LOGINFO("SiPixelTemplate") << "code expects version "<< code_version << " finds "
624  << theCurrentTemp.head.templ_version <<", load anyway " << ENDL;
625  //return false; // dk
626  }
627 
628 
629 #ifdef SI_PIXEL_TEMPLATE_USE_BOOST
630 
631  // next, layout the 1-d/2-d structures needed to store template
632  theCurrentTemp.enty.resize(boost::extents[theCurrentTemp.head.NTy]);
633  theCurrentTemp.entx.resize(boost::extents[theCurrentTemp.head.NTyx][theCurrentTemp.head.NTxx]);
634 
635 #endif
636 
637  // next, loop over all barrel y-angle entries
638 
639  for (i=0; i < theCurrentTemp.head.NTy; ++i) {
640 
641  db >> theCurrentTemp.enty[i].runnum >> theCurrentTemp.enty[i].costrk[0]
642  >> theCurrentTemp.enty[i].costrk[1] >> theCurrentTemp.enty[i].costrk[2];
643 
644  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 1, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
645 
646  // Calculate the alpha, beta, and cot(beta) for this entry
647 
648  theCurrentTemp.enty[i].alpha = static_cast<float>(atan2((double)theCurrentTemp.enty[i].costrk[2], (double)theCurrentTemp.enty[i].costrk[0]));
649 
650  theCurrentTemp.enty[i].cotalpha = theCurrentTemp.enty[i].costrk[0]/theCurrentTemp.enty[i].costrk[2];
651 
652  theCurrentTemp.enty[i].beta = static_cast<float>(atan2((double)theCurrentTemp.enty[i].costrk[2], (double)theCurrentTemp.enty[i].costrk[1]));
653 
654  theCurrentTemp.enty[i].cotbeta = theCurrentTemp.enty[i].costrk[1]/theCurrentTemp.enty[i].costrk[2];
655 
656  db >> theCurrentTemp.enty[i].qavg >> theCurrentTemp.enty[i].pixmax >> theCurrentTemp.enty[i].symax >> theCurrentTemp.enty[i].dyone
657  >> theCurrentTemp.enty[i].syone >> theCurrentTemp.enty[i].sxmax >> theCurrentTemp.enty[i].dxone >> theCurrentTemp.enty[i].sxone;
658 
659  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 2, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
660 
661  db >> theCurrentTemp.enty[i].dytwo >> theCurrentTemp.enty[i].sytwo >> theCurrentTemp.enty[i].dxtwo
662  >> theCurrentTemp.enty[i].sxtwo >> theCurrentTemp.enty[i].qmin >> theCurrentTemp.enty[i].clsleny >> theCurrentTemp.enty[i].clslenx;
663  // >> theCurrentTemp.enty[i].mpvvav >> theCurrentTemp.enty[i].sigmavav >> theCurrentTemp.enty[i].kappavav;
664 
665  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 3, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
666 
667  if(theCurrentTemp.enty[i].qmin <= 0.) {LOGERROR("SiPixelTemplate") << "Error in template ID " << theCurrentTemp.head.ID << " qmin = " << theCurrentTemp.enty[i].qmin << ", run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
668 
669  for (j=0; j<2; ++j) {
670 
671  db >> theCurrentTemp.enty[i].ypar[j][0] >> theCurrentTemp.enty[i].ypar[j][1]
672  >> theCurrentTemp.enty[i].ypar[j][2] >> theCurrentTemp.enty[i].ypar[j][3] >> theCurrentTemp.enty[i].ypar[j][4];
673 
674  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 4, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
675 
676  }
677 
678  for (j=0; j<9; ++j) {
679 
680  for (k=0; k<TYSIZE; ++k) {db >> theCurrentTemp.enty[i].ytemp[j][k];}
681 
682  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 5, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
683  }
684 
685  for (j=0; j<2; ++j) {
686 
687  db >> theCurrentTemp.enty[i].xpar[j][0] >> theCurrentTemp.enty[i].xpar[j][1]
688  >> theCurrentTemp.enty[i].xpar[j][2] >> theCurrentTemp.enty[i].xpar[j][3] >> theCurrentTemp.enty[i].xpar[j][4];
689 
690  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 6, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
691 
692  }
693 
694  qavg_avg = 0.f;
695  for (j=0; j<9; ++j) {
696 
697  for (k=0; k<TXSIZE; ++k) {db >> theCurrentTemp.enty[i].xtemp[j][k]; qavg_avg += theCurrentTemp.enty[i].xtemp[j][k];}
698 
699  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 7, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
700  }
701  theCurrentTemp.enty[i].qavg_avg = qavg_avg/9.;
702 
703  for (j=0; j<4; ++j) {
704 
705  db >> theCurrentTemp.enty[i].yavg[j] >> theCurrentTemp.enty[i].yrms[j] >> theCurrentTemp.enty[i].ygx0[j] >> theCurrentTemp.enty[i].ygsig[j];
706 
707  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 8, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
708  }
709 
710  for (j=0; j<4; ++j) {
711 
712  db >> theCurrentTemp.enty[i].yflpar[j][0] >> theCurrentTemp.enty[i].yflpar[j][1] >> theCurrentTemp.enty[i].yflpar[j][2]
713  >> theCurrentTemp.enty[i].yflpar[j][3] >> theCurrentTemp.enty[i].yflpar[j][4] >> theCurrentTemp.enty[i].yflpar[j][5];
714 
715  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 9, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
716  }
717 
718  for (j=0; j<4; ++j) {
719 
720  db >> theCurrentTemp.enty[i].xavg[j] >> theCurrentTemp.enty[i].xrms[j] >> theCurrentTemp.enty[i].xgx0[j] >> theCurrentTemp.enty[i].xgsig[j];
721 
722  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 10, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
723  }
724 
725  for (j=0; j<4; ++j) {
726 
727  db >> theCurrentTemp.enty[i].xflpar[j][0] >> theCurrentTemp.enty[i].xflpar[j][1] >> theCurrentTemp.enty[i].xflpar[j][2]
728  >> theCurrentTemp.enty[i].xflpar[j][3] >> theCurrentTemp.enty[i].xflpar[j][4] >> theCurrentTemp.enty[i].xflpar[j][5];
729 
730  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 11, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
731  }
732 
733  for (j=0; j<4; ++j) {
734 
735  db >> theCurrentTemp.enty[i].chi2yavg[j] >> theCurrentTemp.enty[i].chi2ymin[j] >> theCurrentTemp.enty[i].chi2xavg[j] >> theCurrentTemp.enty[i].chi2xmin[j];
736 
737  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 12, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
738  }
739 
740  for (j=0; j<4; ++j) {
741 
742  db >> theCurrentTemp.enty[i].yavgc2m[j] >> theCurrentTemp.enty[i].yrmsc2m[j] >> theCurrentTemp.enty[i].chi2yavgc2m[j] >> theCurrentTemp.enty[i].chi2yminc2m[j];
743 
744  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 13, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
745  }
746 
747  for (j=0; j<4; ++j) {
748 
749  db >> theCurrentTemp.enty[i].xavgc2m[j] >> theCurrentTemp.enty[i].xrmsc2m[j] >> theCurrentTemp.enty[i].chi2xavgc2m[j] >> theCurrentTemp.enty[i].chi2xminc2m[j];
750 
751  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 14, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
752  }
753 
754  for (j=0; j<4; ++j) {
755 
756  db >> theCurrentTemp.enty[i].yavggen[j] >> theCurrentTemp.enty[i].yrmsgen[j] >> theCurrentTemp.enty[i].ygx0gen[j] >> theCurrentTemp.enty[i].ygsiggen[j];
757 
758  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 14a, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
759  }
760 
761  for (j=0; j<4; ++j) {
762 
763  db >> theCurrentTemp.enty[i].xavggen[j] >> theCurrentTemp.enty[i].xrmsgen[j] >> theCurrentTemp.enty[i].xgx0gen[j] >> theCurrentTemp.enty[i].xgsiggen[j];
764 
765  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 14b, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
766  }
767 
768 
769  db >> theCurrentTemp.enty[i].chi2yavgone >> theCurrentTemp.enty[i].chi2yminone >> theCurrentTemp.enty[i].chi2xavgone >> theCurrentTemp.enty[i].chi2xminone >> theCurrentTemp.enty[i].qmin2
770  >> theCurrentTemp.enty[i].mpvvav >> theCurrentTemp.enty[i].sigmavav >> theCurrentTemp.enty[i].kappavav >> theCurrentTemp.enty[i].r_qMeas_qTrue >> theCurrentTemp.enty[i].spare[0];
771 
772  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 15, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
773 
774  db >> theCurrentTemp.enty[i].mpvvav2 >> theCurrentTemp.enty[i].sigmavav2 >> theCurrentTemp.enty[i].kappavav2 >> theCurrentTemp.enty[i].qbfrac[0] >> theCurrentTemp.enty[i].qbfrac[1]
775  >> theCurrentTemp.enty[i].qbfrac[2] >> theCurrentTemp.enty[i].fracyone >> theCurrentTemp.enty[i].fracxone >> theCurrentTemp.enty[i].fracytwo >> theCurrentTemp.enty[i].fracxtwo;
776  // theCurrentTemp.enty[i].qbfrac[3] = 1. - theCurrentTemp.enty[i].qbfrac[0] - theCurrentTemp.enty[i].qbfrac[1] - theCurrentTemp.enty[i].qbfrac[2];
777 
778  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 16, no template load, run # " << theCurrentTemp.enty[i].runnum << ENDL; return false;}
779 
780  }
781 
782  // next, loop over all barrel x-angle entries
783 
784  for (k=0; k < theCurrentTemp.head.NTyx; ++k) {
785 
786  for (i=0; i < theCurrentTemp.head.NTxx; ++i) {
787 
788  db >> theCurrentTemp.entx[k][i].runnum >> theCurrentTemp.entx[k][i].costrk[0]
789  >> theCurrentTemp.entx[k][i].costrk[1] >> theCurrentTemp.entx[k][i].costrk[2];
790 
791  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 17, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
792 
793  // Calculate the alpha, beta, and cot(beta) for this entry
794 
795  theCurrentTemp.entx[k][i].alpha = static_cast<float>(atan2((double)theCurrentTemp.entx[k][i].costrk[2], (double)theCurrentTemp.entx[k][i].costrk[0]));
796 
797  theCurrentTemp.entx[k][i].cotalpha = theCurrentTemp.entx[k][i].costrk[0]/theCurrentTemp.entx[k][i].costrk[2];
798 
799  theCurrentTemp.entx[k][i].beta = static_cast<float>(atan2((double)theCurrentTemp.entx[k][i].costrk[2], (double)theCurrentTemp.entx[k][i].costrk[1]));
800 
801  theCurrentTemp.entx[k][i].cotbeta = theCurrentTemp.entx[k][i].costrk[1]/theCurrentTemp.entx[k][i].costrk[2];
802 
803  db >> theCurrentTemp.entx[k][i].qavg >> theCurrentTemp.entx[k][i].pixmax >> theCurrentTemp.entx[k][i].symax >> theCurrentTemp.entx[k][i].dyone
804  >> theCurrentTemp.entx[k][i].syone >> theCurrentTemp.entx[k][i].sxmax >> theCurrentTemp.entx[k][i].dxone >> theCurrentTemp.entx[k][i].sxone;
805 
806  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 18, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
807 
808  db >> theCurrentTemp.entx[k][i].dytwo >> theCurrentTemp.entx[k][i].sytwo >> theCurrentTemp.entx[k][i].dxtwo
809  >> theCurrentTemp.entx[k][i].sxtwo >> theCurrentTemp.entx[k][i].qmin >> theCurrentTemp.entx[k][i].clsleny >> theCurrentTemp.entx[k][i].clslenx;
810  // >> theCurrentTemp.entx[k][i].mpvvav >> theCurrentTemp.entx[k][i].sigmavav >> theCurrentTemp.entx[k][i].kappavav;
811 
812  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 19, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
813 
814  for (j=0; j<2; ++j) {
815 
816  db >> theCurrentTemp.entx[k][i].ypar[j][0] >> theCurrentTemp.entx[k][i].ypar[j][1]
817  >> theCurrentTemp.entx[k][i].ypar[j][2] >> theCurrentTemp.entx[k][i].ypar[j][3] >> theCurrentTemp.entx[k][i].ypar[j][4];
818 
819  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 20, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
820  }
821 
822  for (j=0; j<9; ++j) {
823 
824  for (l=0; l<TYSIZE; ++l) {db >> theCurrentTemp.entx[k][i].ytemp[j][l];}
825 
826  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 21, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
827  }
828 
829 
830 
831  for (j=0; j<2; ++j) {
832 
833  db >> theCurrentTemp.entx[k][i].xpar[j][0] >> theCurrentTemp.entx[k][i].xpar[j][1]
834  >> theCurrentTemp.entx[k][i].xpar[j][2] >> theCurrentTemp.entx[k][i].xpar[j][3] >> theCurrentTemp.entx[k][i].xpar[j][4];
835 
836 
837  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 22, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
838  }
839 
840  qavg_avg = 0.f;
841  for (j=0; j<9; ++j) {
842 
843  for (l=0; l<TXSIZE; ++l) {db >> theCurrentTemp.entx[k][i].xtemp[j][l]; qavg_avg += theCurrentTemp.entx[k][i].xtemp[j][l];}
844 
845  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 23, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
846  }
847  theCurrentTemp.entx[k][i].qavg_avg = qavg_avg/9.;
848 
849  for (j=0; j<4; ++j) {
850 
851  db >> theCurrentTemp.entx[k][i].yavg[j] >> theCurrentTemp.entx[k][i].yrms[j] >> theCurrentTemp.entx[k][i].ygx0[j] >> theCurrentTemp.entx[k][i].ygsig[j];
852 
853  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 24, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
854  }
855 
856  for (j=0; j<4; ++j) {
857 
858  db >> theCurrentTemp.entx[k][i].yflpar[j][0] >> theCurrentTemp.entx[k][i].yflpar[j][1] >> theCurrentTemp.entx[k][i].yflpar[j][2]
859  >> theCurrentTemp.entx[k][i].yflpar[j][3] >> theCurrentTemp.entx[k][i].yflpar[j][4] >> theCurrentTemp.entx[k][i].yflpar[j][5];
860 
861  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 25, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
862  }
863 
864  for (j=0; j<4; ++j) {
865 
866  db >> theCurrentTemp.entx[k][i].xavg[j] >> theCurrentTemp.entx[k][i].xrms[j] >> theCurrentTemp.entx[k][i].xgx0[j] >> theCurrentTemp.entx[k][i].xgsig[j];
867 
868  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 26, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
869  }
870 
871  for (j=0; j<4; ++j) {
872 
873  db >> theCurrentTemp.entx[k][i].xflpar[j][0] >> theCurrentTemp.entx[k][i].xflpar[j][1] >> theCurrentTemp.entx[k][i].xflpar[j][2]
874  >> theCurrentTemp.entx[k][i].xflpar[j][3] >> theCurrentTemp.entx[k][i].xflpar[j][4] >> theCurrentTemp.entx[k][i].xflpar[j][5];
875 
876  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 27, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
877  }
878 
879  for (j=0; j<4; ++j) {
880 
881  db >> theCurrentTemp.entx[k][i].chi2yavg[j] >> theCurrentTemp.entx[k][i].chi2ymin[j] >> theCurrentTemp.entx[k][i].chi2xavg[j] >> theCurrentTemp.entx[k][i].chi2xmin[j];
882 
883  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 28, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
884  }
885 
886  for (j=0; j<4; ++j) {
887 
888  db >> theCurrentTemp.entx[k][i].yavgc2m[j] >> theCurrentTemp.entx[k][i].yrmsc2m[j] >> theCurrentTemp.entx[k][i].chi2yavgc2m[j] >> theCurrentTemp.entx[k][i].chi2yminc2m[j];
889 
890  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 29, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
891  }
892 
893  for (j=0; j<4; ++j) {
894 
895  db >> theCurrentTemp.entx[k][i].xavgc2m[j] >> theCurrentTemp.entx[k][i].xrmsc2m[j] >> theCurrentTemp.entx[k][i].chi2xavgc2m[j] >> theCurrentTemp.entx[k][i].chi2xminc2m[j];
896 
897  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 30, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
898  }
899 
900  for (j=0; j<4; ++j) {
901 
902  db >> theCurrentTemp.entx[k][i].yavggen[j] >> theCurrentTemp.entx[k][i].yrmsgen[j] >> theCurrentTemp.entx[k][i].ygx0gen[j] >> theCurrentTemp.entx[k][i].ygsiggen[j];
903 
904  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 30a, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
905  }
906 
907  for (j=0; j<4; ++j) {
908 
909  db >> theCurrentTemp.entx[k][i].xavggen[j] >> theCurrentTemp.entx[k][i].xrmsgen[j] >> theCurrentTemp.entx[k][i].xgx0gen[j] >> theCurrentTemp.entx[k][i].xgsiggen[j];
910 
911  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 30b, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
912  }
913 
914 
915  db >> theCurrentTemp.entx[k][i].chi2yavgone >> theCurrentTemp.entx[k][i].chi2yminone >> theCurrentTemp.entx[k][i].chi2xavgone >> theCurrentTemp.entx[k][i].chi2xminone >> theCurrentTemp.entx[k][i].qmin2
916  >> theCurrentTemp.entx[k][i].mpvvav >> theCurrentTemp.entx[k][i].sigmavav >> theCurrentTemp.entx[k][i].kappavav >> theCurrentTemp.entx[k][i].r_qMeas_qTrue >> theCurrentTemp.entx[k][i].spare[0];
917 
918  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 31, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
919 
920  db >> theCurrentTemp.entx[k][i].mpvvav2 >> theCurrentTemp.entx[k][i].sigmavav2 >> theCurrentTemp.entx[k][i].kappavav2 >> theCurrentTemp.entx[k][i].qbfrac[0] >> theCurrentTemp.entx[k][i].qbfrac[1]
921  >> theCurrentTemp.entx[k][i].qbfrac[2] >> theCurrentTemp.entx[k][i].fracyone >> theCurrentTemp.entx[k][i].fracxone >> theCurrentTemp.entx[k][i].fracytwo >> theCurrentTemp.entx[k][i].fracxtwo;
922  // theCurrentTemp.entx[k][i].qbfrac[3] = 1. - theCurrentTemp.entx[k][i].qbfrac[0] - theCurrentTemp.entx[k][i].qbfrac[1] - theCurrentTemp.entx[k][i].qbfrac[2];
923 
924  if(db.fail()) {LOGERROR("SiPixelTemplate") << "Error reading file 32, no template load, run # " << theCurrentTemp.entx[k][i].runnum << ENDL; return false;}
925 
926  }
927  }
928 
929 
930  // Add this template to the store
931 
932  thePixelTemp_.push_back(theCurrentTemp);
933 
934  }
935  postInit(thePixelTemp_);
936  return true;
937 
938 } // TempInit
939 
940 #endif
941 
942 
943 void SiPixelTemplate::postInit(std::vector< SiPixelTemplateStore > & thePixelTemp_) {
944  /*
945  std::cout << "SiPixelTemplate size " << thePixelTemp_.size() << std::endl;
946  #ifndef SI_PIXEL_TEMPLATE_USE_BOOST
947  std::cout <<"uses C arrays" << std::endl;
948  #endif
949 
950  int i=0;
951  for (auto & templ : thePixelTemp_) {
952  std::cout << i <<':' << templ.head.ID << ' ' << templ.head.NTy <<','<< templ.head.NTyx <<','<< templ.head.NTxx << std::endl;
953  for ( auto iy=1; iy<templ.head.NTy; ++iy ) { auto & ent = templ.enty[iy]; std::cout << ent.cotbeta <<',' << ent.cotbeta-templ.enty[iy-1].cotbeta << ' '; }
954  std::cout << std::endl;
955  for ( auto ix=1; ix<templ.head.NTxx; ++ix ){ auto & ent = templ.entx[0][ix]; std::cout << ent.cotalpha <<','<< ent.cotalpha-templ.entx[0][ix-1].cotalpha << ' ';}
956  std::cout << std::endl;
957  ++i;
958  }
959  */
960 
961  for (auto & templ : thePixelTemp_) {
962  for ( auto iy=0; iy<templ.head.NTy; ++iy ) templ.cotbetaY[iy]=templ.enty[iy].cotbeta;
963  for ( auto iy=0; iy<templ.head.NTyx; ++iy ) templ.cotbetaX[iy]= templ.entx[iy][0].cotbeta;
964  for ( auto ix=0; ix<templ.head.NTxx; ++ix ) templ.cotalphaX[ix]=templ.entx[0][ix].cotalpha;
965  }
966 
967 }
968 
969 
970 
971 
972 // ************************************************************************************************************
983 // ************************************************************************************************************
984 bool SiPixelTemplate::interpolate(int id, float cotalpha, float cotbeta, float locBz, float locBx){
985  // Interpolate for a new set of track angles
986 
987  // Local variables
988  int i, j;
989  int ilow, ihigh, iylow, iyhigh, Ny, Nxx, Nyx, imidy, imaxx;
990  float yratio, yxratio, xxratio, sxmax, qcorrect, qxtempcor, symax, chi2xavgone, chi2xminone, cota, cotb, cotalpha0, cotbeta0;
991  bool flip_x, flip_y;
992  // std::vector <float> xrms(4), xgsig(4), xrmsc2m(4);
993  float chi2xavg[4], chi2xmin[4], chi2xavgc2m[4], chi2xminc2m[4];
994 
995 
996  // Check to see if interpolation is valid
997  if(id != id_current_ || cotalpha != cota_current_ || cotbeta != cotb_current_) {
998 
999  cota_current_ = cotalpha; cotb_current_ = cotbeta; success_ = true;
1000 
1001  if(id != id_current_) {
1002 
1003  // Find the index corresponding to id
1004 
1005  index_id_ = -1;
1006  for(i=0; i<(int)thePixelTemp_.size(); ++i) {
1007 
1008  //std::cout<<i<<" "<<id<<" "<<thePixelTemp_[i].head.ID<<std::endl;
1009 
1010  if(id == thePixelTemp_[i].head.ID) {
1011 
1012  index_id_ = i;
1013  id_current_ = id;
1014 
1015  // Copy the charge scaling factor to the private variable
1016 
1017  qscale_ = thePixelTemp_[index_id_].head.qscale;
1018 
1019  // Copy the pseudopixel signal size to the private variable
1020 
1021  s50_ = thePixelTemp_[index_id_].head.s50;
1022 
1023  // Copy Qbinning info to private variables
1024 
1025  for(j=0; j<3; ++j) {fbin_[j] = thePixelTemp_[index_id_].head.fbin[j];}
1026  //std::cout<<" set fbin "<< fbin_[0]<<" "<<fbin_[1]<<" "<<fbin_[2]<<std::endl;
1027 
1028  // Pixel sizes to the private variables
1029 
1030  xsize_ = thePixelTemp_[index_id_].head.xsize;
1031  ysize_ = thePixelTemp_[index_id_].head.ysize;
1032  zsize_ = thePixelTemp_[index_id_].head.zsize;
1033 
1034  break;
1035  }
1036  }
1037  }
1038 
1039 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1040  if(index_id_ < 0 || index_id_ >= (int)thePixelTemp_.size()) {
1041  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::interpolate can't find needed template ID = " << id << std::endl;
1042  }
1043 #else
1044  assert(index_id_ >= 0 && index_id_ < (int)thePixelTemp_.size());
1045 #endif
1046 
1047  // Interpolate the absolute value of cot(beta)
1048 
1049  abs_cotb_ = std::abs(cotbeta);
1050 
1051  // qcorrect corrects the cot(alpha)=0 cluster charge for non-zero cot(alpha)
1052 
1053  cotalpha0 = thePixelTemp_[index_id_].enty[0].cotalpha;
1054  qcorrect=std::sqrt((1.f+cotbeta*cotbeta+cotalpha*cotalpha)/(1.f+cotbeta*cotbeta+cotalpha0*cotalpha0));
1055 
1056  // for some cosmics, the ususal gymnastics are incorrect
1057  cota = cotalpha;
1058  cotb = abs_cotb_;
1059  flip_x = false;
1060  flip_y = false;
1061  switch(thePixelTemp_[index_id_].head.Dtype) {
1062  case 0:
1063  if(cotbeta < 0.f) {flip_y = true;}
1064  break;
1065  case 1:
1066  if(locBz < 0.f) {
1067  cotb = cotbeta;
1068  } else {
1069  cotb = -cotbeta;
1070  flip_y = true;
1071  }
1072  break;
1073  case 2:
1074  case 3:
1075  case 4:
1076  if(locBx*locBz < 0.f) {
1077  cota = -cotalpha;
1078  flip_x = true;
1079  }
1080  if(locBx > 0.f) {
1081  cotb = cotbeta;
1082  } else {
1083  cotb = -cotbeta;
1084  flip_y = true;
1085  }
1086  break;
1087  default:
1088 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1089  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::illegal subdetector ID = " << thePixelTemp_[index_id_].head.Dtype << std::endl;
1090 #else
1091  std::cout << "SiPixelTemplate::illegal subdetector ID = " << thePixelTemp_[index_id_].head.Dtype << std::endl;
1092 #endif
1093  }
1094 
1095  Ny = thePixelTemp_[index_id_].head.NTy;
1096  Nyx = thePixelTemp_[index_id_].head.NTyx;
1097  Nxx = thePixelTemp_[index_id_].head.NTxx;
1098 
1099 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1100  if(Ny < 2 || Nyx < 1 || Nxx < 2) {
1101  throw cms::Exception("DataCorrupt") << "template ID = " << id_current_ << "has too few entries: Ny/Nyx/Nxx = " << Ny << "/" << Nyx << "/" << Nxx << std::endl;
1102  }
1103 #else
1104  assert(Ny > 1 && Nyx > 0 && Nxx > 1);
1105 #endif
1106  imaxx = Nyx - 1;
1107  imidy = Nxx/2;
1108 
1109  // next, loop over all y-angle entries
1110 
1111  ilow = 0;
1112  yratio = 0.f;
1113 
1114  if(cotb >= thePixelTemp_[index_id_].enty[Ny-1].cotbeta) {
1115 
1116  ilow = Ny-2;
1117  yratio = 1.;
1118  success_ = false;
1119 
1120  } else {
1121 
1122  if(cotb >= thePixelTemp_[index_id_].enty[0].cotbeta) {
1123 
1124  for (i=0; i<Ny-1; ++i) {
1125 
1126  if( thePixelTemp_[index_id_].enty[i].cotbeta <= cotb && cotb < thePixelTemp_[index_id_].enty[i+1].cotbeta) {
1127 
1128  ilow = i;
1129  yratio = (cotb - thePixelTemp_[index_id_].enty[i].cotbeta)/(thePixelTemp_[index_id_].enty[i+1].cotbeta - thePixelTemp_[index_id_].enty[i].cotbeta);
1130  break;
1131  }
1132  }
1133  } else { success_ = false; }
1134  }
1135 
1136  ihigh=ilow + 1;
1137 
1138  // Interpolate/store all y-related quantities (flip displacements when flip_y)
1139 
1140  yratio_ = yratio;
1141  qavg_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].qavg + yratio*thePixelTemp_[index_id_].enty[ihigh].qavg;
1142  qavg_ *= qcorrect;
1143  symax = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].symax + yratio*thePixelTemp_[index_id_].enty[ihigh].symax;
1144  syparmax_ = symax;
1145  sxmax = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].sxmax + yratio*thePixelTemp_[index_id_].enty[ihigh].sxmax;
1146  dyone_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].dyone + yratio*thePixelTemp_[index_id_].enty[ihigh].dyone;
1147  if(flip_y) {dyone_ = -dyone_;}
1148  syone_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].syone + yratio*thePixelTemp_[index_id_].enty[ihigh].syone;
1149  dytwo_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].dytwo + yratio*thePixelTemp_[index_id_].enty[ihigh].dytwo;
1150  if(flip_y) {dytwo_ = -dytwo_;}
1151  sytwo_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].sytwo + yratio*thePixelTemp_[index_id_].enty[ihigh].sytwo;
1152  qmin_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].qmin + yratio*thePixelTemp_[index_id_].enty[ihigh].qmin;
1153  qmin_ *= qcorrect;
1154  qmin2_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].qmin2 + yratio*thePixelTemp_[index_id_].enty[ihigh].qmin2;
1155  qmin2_ *= qcorrect;
1156  mpvvav_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].mpvvav + yratio*thePixelTemp_[index_id_].enty[ihigh].mpvvav;
1157  mpvvav_ *= qcorrect;
1158  sigmavav_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].sigmavav + yratio*thePixelTemp_[index_id_].enty[ihigh].sigmavav;
1159  kappavav_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].kappavav + yratio*thePixelTemp_[index_id_].enty[ihigh].kappavav;
1160  mpvvav2_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].mpvvav2 + yratio*thePixelTemp_[index_id_].enty[ihigh].mpvvav2;
1161  mpvvav2_ *= qcorrect;
1162  sigmavav2_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].sigmavav2 + yratio*thePixelTemp_[index_id_].enty[ihigh].sigmavav2;
1163  kappavav2_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].kappavav2 + yratio*thePixelTemp_[index_id_].enty[ihigh].kappavav2;
1164  clsleny_ = fminf(thePixelTemp_[index_id_].enty[ilow].clsleny, thePixelTemp_[index_id_].enty[ihigh].clsleny);
1165  qavg_avg_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].qavg_avg + yratio*thePixelTemp_[index_id_].enty[ihigh].qavg_avg;
1166  qavg_avg_ *= qcorrect;
1167  for(i=0; i<2 ; ++i) {
1168  for(j=0; j<5 ; ++j) {
1169  // Charge loss switches sides when cot(beta) changes sign
1170  if(flip_y) {
1171  yparl_[1-i][j] = thePixelTemp_[index_id_].enty[ilow].ypar[i][j];
1172  yparh_[1-i][j] = thePixelTemp_[index_id_].enty[ihigh].ypar[i][j];
1173  } else {
1174  yparl_[i][j] = thePixelTemp_[index_id_].enty[ilow].ypar[i][j];
1175  yparh_[i][j] = thePixelTemp_[index_id_].enty[ihigh].ypar[i][j];
1176  }
1177  if(flip_x) {
1178  xparly0_[1-i][j] = thePixelTemp_[index_id_].enty[ilow].xpar[i][j];
1179  xparhy0_[1-i][j] = thePixelTemp_[index_id_].enty[ihigh].xpar[i][j];
1180  } else {
1181  xparly0_[i][j] = thePixelTemp_[index_id_].enty[ilow].xpar[i][j];
1182  xparhy0_[i][j] = thePixelTemp_[index_id_].enty[ihigh].xpar[i][j];
1183  }
1184  }
1185  }
1186 
1187  for(i=0; i<4; ++i) {
1188  yavg_[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].yavg[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].yavg[i];
1189  if(flip_y) {yavg_[i] = -yavg_[i];}
1190  yrms_[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].yrms[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].yrms[i];
1191  // ygx0_[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].ygx0[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].ygx0[i];
1192  // if(flip_y) {ygx0_[i] = -ygx0_[i];}
1193  // ygsig_[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].ygsig[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].ygsig[i];
1194  // xrms[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].xrms[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].xrms[i];
1195  // xgsig[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].xgsig[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].xgsig[i];
1196  chi2yavg_[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].chi2yavg[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].chi2yavg[i];
1197  chi2ymin_[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].chi2ymin[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].chi2ymin[i];
1198  chi2xavg[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].chi2xavg[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].chi2xavg[i];
1199  chi2xmin[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].chi2xmin[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].chi2xmin[i];
1200  yavgc2m_[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].yavgc2m[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].yavgc2m[i];
1201  if(flip_y) {yavgc2m_[i] = -yavgc2m_[i];}
1202  yrmsc2m_[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].yrmsc2m[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].yrmsc2m[i];
1203  chi2yavgc2m_[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].chi2yavgc2m[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].chi2yavgc2m[i];
1204  // if(flip_y) {chi2yavgc2m_[i] = -chi2yavgc2m_[i];}
1205  chi2yminc2m_[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].chi2yminc2m[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].chi2yminc2m[i];
1206  // xrmsc2m[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].xrmsc2m[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].xrmsc2m[i];
1207  chi2xavgc2m[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].chi2xavgc2m[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].chi2xavgc2m[i];
1208  chi2xminc2m[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].chi2xminc2m[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].chi2xminc2m[i];
1209  for(j=0; j<6 ; ++j) {
1210  yflparl_[i][j] = thePixelTemp_[index_id_].enty[ilow].yflpar[i][j];
1211  yflparh_[i][j] = thePixelTemp_[index_id_].enty[ihigh].yflpar[i][j];
1212 
1213  // Since Q_fl is odd under cotbeta, it flips qutomatically, change only even terms
1214 
1215  if(flip_y && (j == 0 || j == 2 || j == 4)) {
1216  yflparl_[i][j] = - yflparl_[i][j];
1217  yflparh_[i][j] = - yflparh_[i][j];
1218  }
1219  }
1220  }
1221 
1223 
1224  chi2yavgone_=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].chi2yavgone + yratio*thePixelTemp_[index_id_].enty[ihigh].chi2yavgone;
1225  chi2yminone_=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].chi2yminone + yratio*thePixelTemp_[index_id_].enty[ihigh].chi2yminone;
1226  chi2xavgone=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].chi2xavgone + yratio*thePixelTemp_[index_id_].enty[ihigh].chi2xavgone;
1227  chi2xminone=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].chi2xminone + yratio*thePixelTemp_[index_id_].enty[ihigh].chi2xminone;
1228  // for(i=0; i<10; ++i) {
1229  // pyspare[i]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].yspare[i] + yratio*thePixelTemp_[index_id_].enty[ihigh].yspare[i];
1230  // }
1231 
1232  // Interpolate and build the y-template
1233 
1234  for(i=0; i<9; ++i) {
1235  ytemp_[i][0] = 0.f;
1236  ytemp_[i][1] = 0.f;
1237  ytemp_[i][BYM2] = 0.f;
1238  ytemp_[i][BYM1] = 0.f;
1239  for(j=0; j<TYSIZE; ++j) {
1240 
1241  // Flip the basic y-template when the cotbeta is negative
1242 
1243  if(flip_y) {
1244  ytemp_[8-i][BYM3-j]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].ytemp[i][j] + yratio*thePixelTemp_[index_id_].enty[ihigh].ytemp[i][j];
1245  } else {
1246  ytemp_[i][j+2]=(1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].ytemp[i][j] + yratio*thePixelTemp_[index_id_].enty[ihigh].ytemp[i][j];
1247  }
1248  }
1249  }
1250 
1251  // next, loop over all x-angle entries, first, find relevant y-slices
1252 
1253  iylow = 0;
1254  yxratio = 0.f;
1255 
1256  if(abs_cotb_ >= thePixelTemp_[index_id_].entx[Nyx-1][0].cotbeta) {
1257 
1258  iylow = Nyx-2;
1259  yxratio = 1.f;
1260 
1261  } else if(abs_cotb_ >= thePixelTemp_[index_id_].entx[0][0].cotbeta) {
1262 
1263  for (i=0; i<Nyx-1; ++i) {
1264 
1265  if( thePixelTemp_[index_id_].entx[i][0].cotbeta <= abs_cotb_ && abs_cotb_ < thePixelTemp_[index_id_].entx[i+1][0].cotbeta) {
1266 
1267  iylow = i;
1268  yxratio = (abs_cotb_ - thePixelTemp_[index_id_].entx[i][0].cotbeta)/(thePixelTemp_[index_id_].entx[i+1][0].cotbeta - thePixelTemp_[index_id_].entx[i][0].cotbeta);
1269  break;
1270  }
1271  }
1272  }
1273 
1274  iyhigh=iylow + 1;
1275 
1276  ilow = 0;
1277  xxratio = 0.f;
1278 
1279  if(cota >= thePixelTemp_[index_id_].entx[0][Nxx-1].cotalpha) {
1280 
1281  ilow = Nxx-2;
1282  xxratio = 1.f;
1283  success_ = false;
1284 
1285  } else {
1286 
1287  if(cota >= thePixelTemp_[index_id_].entx[0][0].cotalpha) {
1288 
1289  for (i=0; i<Nxx-1; ++i) {
1290 
1291  if( thePixelTemp_[index_id_].entx[0][i].cotalpha <= cota && cota < thePixelTemp_[index_id_].entx[0][i+1].cotalpha) {
1292 
1293  ilow = i;
1294  xxratio = (cota - thePixelTemp_[index_id_].entx[0][i].cotalpha)/(thePixelTemp_[index_id_].entx[0][i+1].cotalpha - thePixelTemp_[index_id_].entx[0][i].cotalpha);
1295  break;
1296  }
1297  }
1298  } else { success_ = false; }
1299  }
1300 
1301  ihigh=ilow + 1;
1302 
1303  // Interpolate/store all x-related quantities
1304 
1305  yxratio_ = yxratio;
1306  xxratio_ = xxratio;
1307 
1308  // sxparmax defines the maximum charge for which the parameters xpar are defined (not rescaled by cotbeta)
1309 
1310  sxparmax_ = (1.f - xxratio)*thePixelTemp_[index_id_].entx[imaxx][ilow].sxmax + xxratio*thePixelTemp_[index_id_].entx[imaxx][ihigh].sxmax;
1311  sxmax_ = sxparmax_;
1312  if(thePixelTemp_[index_id_].entx[imaxx][imidy].sxmax != 0.f) {sxmax_=sxmax_/thePixelTemp_[index_id_].entx[imaxx][imidy].sxmax*sxmax;}
1313  symax_ = (1.f - xxratio)*thePixelTemp_[index_id_].entx[imaxx][ilow].symax + xxratio*thePixelTemp_[index_id_].entx[imaxx][ihigh].symax;
1314  if(thePixelTemp_[index_id_].entx[imaxx][imidy].symax != 0.f) {symax_=symax_/thePixelTemp_[index_id_].entx[imaxx][imidy].symax*symax;}
1315  dxone_ = (1.f - xxratio)*thePixelTemp_[index_id_].entx[0][ilow].dxone + xxratio*thePixelTemp_[index_id_].entx[0][ihigh].dxone;
1316  if(flip_x) {dxone_ = -dxone_;}
1317  sxone_ = (1.f - xxratio)*thePixelTemp_[index_id_].entx[0][ilow].sxone + xxratio*thePixelTemp_[index_id_].entx[0][ihigh].sxone;
1318  dxtwo_ = (1.f - xxratio)*thePixelTemp_[index_id_].entx[0][ilow].dxtwo + xxratio*thePixelTemp_[index_id_].entx[0][ihigh].dxtwo;
1319  if(flip_x) {dxtwo_ = -dxtwo_;}
1320  sxtwo_ = (1.f - xxratio)*thePixelTemp_[index_id_].entx[0][ilow].sxtwo + xxratio*thePixelTemp_[index_id_].entx[0][ihigh].sxtwo;
1321  clslenx_ = fminf(thePixelTemp_[index_id_].entx[0][ilow].clslenx, thePixelTemp_[index_id_].entx[0][ihigh].clslenx);
1322 
1323  for(i=0; i<2 ; ++i) {
1324  for(j=0; j<5 ; ++j) {
1325  // Charge loss switches sides when cot(alpha) changes sign
1326  if(flip_x) {
1327  xpar0_[1-i][j] = thePixelTemp_[index_id_].entx[imaxx][imidy].xpar[i][j];
1328  xparl_[1-i][j] = thePixelTemp_[index_id_].entx[imaxx][ilow].xpar[i][j];
1329  xparh_[1-i][j] = thePixelTemp_[index_id_].entx[imaxx][ihigh].xpar[i][j];
1330  } else {
1331  xpar0_[i][j] = thePixelTemp_[index_id_].entx[imaxx][imidy].xpar[i][j];
1332  xparl_[i][j] = thePixelTemp_[index_id_].entx[imaxx][ilow].xpar[i][j];
1333  xparh_[i][j] = thePixelTemp_[index_id_].entx[imaxx][ihigh].xpar[i][j];
1334  }
1335  }
1336  }
1337 
1338  // pixmax is the maximum allowed pixel charge (used for truncation)
1339 
1340  pixmax_=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iylow][ilow].pixmax + xxratio*thePixelTemp_[index_id_].entx[iylow][ihigh].pixmax)
1341  +yxratio*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].pixmax + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].pixmax);
1342 
1343 
1344  r_qMeas_qTrue_=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iylow][ilow].r_qMeas_qTrue + xxratio*thePixelTemp_[index_id_].entx[iylow][ihigh].r_qMeas_qTrue)
1345  +yxratio*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].r_qMeas_qTrue + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].r_qMeas_qTrue);
1346 
1347 
1348  for(i=0; i<4; ++i) {
1349  xavg_[i]=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iylow][ilow].xavg[i] + xxratio*thePixelTemp_[index_id_].entx[iylow][ihigh].xavg[i])
1350  +yxratio*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].xavg[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].xavg[i]);
1351  if(flip_x) {xavg_[i] = -xavg_[i];}
1352 
1353  xrms_[i]=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iylow][ilow].xrms[i] + xxratio*thePixelTemp_[index_id_].entx[iylow][ihigh].xrms[i])
1354  +yxratio*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].xrms[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].xrms[i]);
1355 
1356  // xgx0_[i]=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iylow][ilow].xgx0[i] + xxratio*thePixelTemp_[index_id_].entx[iylow][ihigh].xgx0[i])
1357  // +yxratio*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].xgx0[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].xgx0[i]);
1358 
1359  // xgsig_[i]=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iylow][ilow].xgsig[i] + xxratio*thePixelTemp_[index_id_].entx[iylow][ihigh].xgsig[i])
1360  // +yxratio*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].xgsig[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].xgsig[i]);
1361 
1362  xavgc2m_[i]=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iylow][ilow].xavgc2m[i] + xxratio*thePixelTemp_[index_id_].entx[iylow][ihigh].xavgc2m[i])
1363  +yxratio*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].xavgc2m[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].xavgc2m[i]);
1364  if(flip_x) {xavgc2m_[i] = -xavgc2m_[i];}
1365 
1366  xrmsc2m_[i]=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iylow][ilow].xrmsc2m[i] + xxratio*thePixelTemp_[index_id_].entx[iylow][ihigh].xrmsc2m[i])
1367  +yxratio*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].xrmsc2m[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].xrmsc2m[i]);
1368 
1369  // chi2xavgc2m_[i]=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iylow][ilow].chi2xavgc2m[i] + xxratio*thePixelTemp_[index_id_].entx[iylow][ihigh].chi2xavgc2m[i])
1370  // +yxratio*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].chi2xavgc2m[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].chi2xavgc2m[i]);
1371 
1372  // chi2xminc2m_[i]=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iylow][ilow].chi2xminc2m[i] + xxratio*thePixelTemp_[index_id_].entx[iylow][ihigh].chi2xminc2m[i])
1373  // +yxratio*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].chi2xminc2m[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].chi2xminc2m[i]);
1374  //
1375  // Try new interpolation scheme
1376  //
1377  // chi2xavg_[i]=((1.f - xxratio)*thePixelTemp_[index_id_].entx[imaxx][ilow].chi2xavg[i] + xxratio*thePixelTemp_[index_id_].entx[imaxx][ihigh].chi2xavg[i]);
1378  // if(thePixelTemp_[index_id_].entx[imaxx][imidy].chi2xavg[i] != 0.f) {chi2xavg_[i]=chi2xavg_[i]/thePixelTemp_[index_id_].entx[imaxx][imidy].chi2xavg[i]*chi2xavg[i];}
1379  //
1380  // chi2xmin_[i]=((1.f - xxratio)*thePixelTemp_[index_id_].entx[imaxx][ilow].chi2xmin[i] + xxratio*thePixelTemp_[index_id_].entx[imaxx][ihigh].chi2xmin[i]);
1381  // if(thePixelTemp_[index_id_].entx[imaxx][imidy].chi2xmin[i] != 0.f) {chi2xmin_[i]=chi2xmin_[i]/thePixelTemp_[index_id_].entx[imaxx][imidy].chi2xmin[i]*chi2xmin[i];}
1382  //
1383  chi2xavg_[i]=((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].chi2xavg[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].chi2xavg[i]);
1384  if(thePixelTemp_[index_id_].entx[iyhigh][imidy].chi2xavg[i] != 0.f) {chi2xavg_[i]=chi2xavg_[i]/thePixelTemp_[index_id_].entx[iyhigh][imidy].chi2xavg[i]*chi2xavg[i];}
1385 
1386  chi2xmin_[i]=((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].chi2xmin[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].chi2xmin[i]);
1387  if(thePixelTemp_[index_id_].entx[iyhigh][imidy].chi2xmin[i] != 0.f) {chi2xmin_[i]=chi2xmin_[i]/thePixelTemp_[index_id_].entx[iyhigh][imidy].chi2xmin[i]*chi2xmin[i];}
1388 
1389  chi2xavgc2m_[i]=((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].chi2xavgc2m[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].chi2xavgc2m[i]);
1390  if(thePixelTemp_[index_id_].entx[iyhigh][imidy].chi2xavgc2m[i] != 0.f) {chi2xavgc2m_[i]=chi2xavgc2m_[i]/thePixelTemp_[index_id_].entx[iyhigh][imidy].chi2xavgc2m[i]*chi2xavgc2m[i];}
1391 
1392  chi2xminc2m_[i]=((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].chi2xminc2m[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].chi2xminc2m[i]);
1393  if(thePixelTemp_[index_id_].entx[iyhigh][imidy].chi2xminc2m[i] != 0.f) {chi2xminc2m_[i]=chi2xminc2m_[i]/thePixelTemp_[index_id_].entx[iyhigh][imidy].chi2xminc2m[i]*chi2xminc2m[i];}
1394 
1395  for(j=0; j<6 ; ++j) {
1396  xflparll_[i][j] = thePixelTemp_[index_id_].entx[iylow][ilow].xflpar[i][j];
1397  xflparlh_[i][j] = thePixelTemp_[index_id_].entx[iylow][ihigh].xflpar[i][j];
1398  xflparhl_[i][j] = thePixelTemp_[index_id_].entx[iyhigh][ilow].xflpar[i][j];
1399  xflparhh_[i][j] = thePixelTemp_[index_id_].entx[iyhigh][ihigh].xflpar[i][j];
1400  // Since Q_fl is odd under cotalpha, it flips qutomatically, change only even terms
1401  if(flip_x && (j == 0 || j == 2 || j == 4)) {
1402  xflparll_[i][j] = -xflparll_[i][j];
1403  xflparlh_[i][j] = -xflparlh_[i][j];
1404  xflparhl_[i][j] = -xflparhl_[i][j];
1405  xflparhh_[i][j] = -xflparhh_[i][j];
1406  }
1407  }
1408  }
1409 
1410 
1411  // Do the spares next
1412 
1413  chi2xavgone_=((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].chi2xavgone + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].chi2xavgone);
1414  if(thePixelTemp_[index_id_].entx[iyhigh][imidy].chi2xavgone != 0.f) {chi2xavgone_=chi2xavgone_/thePixelTemp_[index_id_].entx[iyhigh][imidy].chi2xavgone*chi2xavgone;}
1415 
1416  chi2xminone_=((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].chi2xminone + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].chi2xminone);
1417  if(thePixelTemp_[index_id_].entx[iyhigh][imidy].chi2xminone != 0.f) {chi2xminone_=chi2xminone_/thePixelTemp_[index_id_].entx[iyhigh][imidy].chi2xminone*chi2xminone;}
1418  // for(i=0; i<10; ++i) {
1419  // pxspare[i]=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iylow][ilow].xspare[i] + xxratio*thePixelTemp_[index_id_].entx[iylow][ihigh].xspare[i])
1420  // +yxratio*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].xspare[i] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].xspare[i]);
1421  // }
1422 
1423  // Interpolate and build the x-template
1424 
1425  // qxtempcor corrects the total charge to the actual track angles (not actually needed for the template fits, but useful for Guofan)
1426 
1427  cotbeta0 = thePixelTemp_[index_id_].entx[iyhigh][0].cotbeta;
1428  qxtempcor=std::sqrt((1.f+cotbeta*cotbeta+cotalpha*cotalpha)/(1.f+cotbeta0*cotbeta0+cotalpha*cotalpha));
1429 
1430  for(i=0; i<9; ++i) {
1431  xtemp_[i][0] = 0.f;
1432  xtemp_[i][1] = 0.f;
1433  xtemp_[i][BXM2] = 0.f;
1434  xtemp_[i][BXM1] = 0.f;
1435  for(j=0; j<TXSIZE; ++j) {
1436  // Take next largest x-slice for the x-template (it reduces bias in the forward direction after irradiation)
1437  // xtemp_[i][j+2]=(1.f - xxratio)*thePixelTemp_[index_id_].entx[imaxx][ilow].xtemp[i][j] + xxratio*thePixelTemp_[index_id_].entx[imaxx][ihigh].xtemp[i][j];
1438  // xtemp_[i][j+2]=(1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].xtemp[i][j] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].xtemp[i][j];
1439  if(flip_x) {
1440  xtemp_[8-i][BXM3-j]=qxtempcor*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].xtemp[i][j] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].xtemp[i][j]);
1441  } else {
1442  xtemp_[i][j+2]=qxtempcor*((1.f - xxratio)*thePixelTemp_[index_id_].entx[iyhigh][ilow].xtemp[i][j] + xxratio*thePixelTemp_[index_id_].entx[iyhigh][ihigh].xtemp[i][j]);
1443  }
1444  }
1445  }
1446 
1447  lorywidth_ = thePixelTemp_[index_id_].head.lorywidth;
1448  lorxwidth_ = thePixelTemp_[index_id_].head.lorxwidth;
1449  lorybias_ = thePixelTemp_[index_id_].head.lorybias;
1450  lorxbias_ = thePixelTemp_[index_id_].head.lorxbias;
1451  if(flip_x) {lorxwidth_ = -lorxwidth_; lorxbias_ = -lorxbias_;}
1452  if(flip_y) {lorywidth_ = -lorywidth_; lorybias_ = -lorybias_;}
1453 
1454 
1455  }
1456 
1457  return success_;
1458 } // interpolate
1459 
1460 
1461 
1462 
1463 
1464 // ************************************************************************************************************
1470 // ************************************************************************************************************
1471 bool SiPixelTemplate::interpolate(int id, float cotalpha, float cotbeta)
1472 {
1473  // Interpolate for a new set of track angles
1474 
1475  // Local variables
1476  float locBx, locBz;
1477  locBx = 1.f;
1478  if(cotbeta < 0.f) {locBx = -1.f;}
1479  locBz = locBx;
1480  if(cotalpha < 0.f) {locBz = -locBx;}
1481  return SiPixelTemplate::interpolate(id, cotalpha, cotbeta, locBz, locBx);
1482 }
1483 
1484 
1485 
1486 // ************************************************************************************************************
1492 // ************************************************************************************************************
1493 bool SiPixelTemplate::interpolate(int id, float cotalpha, float cotbeta, float locBz)
1494 {
1495  // Interpolate for a new set of track angles
1496 
1497  // Local variables
1498  float locBx;
1499  locBx = 1.f;
1500  return SiPixelTemplate::interpolate(id, cotalpha, cotbeta, locBz, locBx);
1501 }
1502 
1503 
1504 // ************************************************************************************************************
1512 // ************************************************************************************************************
1513 void SiPixelTemplate::ysigma2(int fypix, int lypix, float sythr, float ysum[25], float ysig2[25])
1514 
1515 {
1516  // Interpolate using quantities already stored in the private variables
1517 
1518  // Local variables
1519  int i;
1520  float sigi, sigi2, sigi3, sigi4, symax, qscale;
1521 
1522  // Make sure that input is OK
1523 
1524 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1525  if(fypix < 2 || fypix >= BYM2) {
1526  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::ysigma2 called with fypix = " << fypix << std::endl;
1527  }
1528 #else
1529  assert(fypix > 1 && fypix < BYM2);
1530 #endif
1531 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1532  if(lypix < fypix || lypix >= BYM2) {
1533  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::ysigma2 called with lypix/fypix = " << lypix << "/" << fypix << std::endl;
1534  }
1535 #else
1536  assert(lypix >= fypix && lypix < BYM2);
1537 #endif
1538 
1539  // Define the maximum signal to use in the parameterization
1540 
1541  symax = symax_;
1542  if(symax_ > syparmax_) {symax = syparmax_;}
1543 
1544  // Evaluate pixel-by-pixel uncertainties (weights) for the templ analysis
1545 
1546  for(i=fypix-2; i<=lypix+2; ++i) {
1547  if(i < fypix || i > lypix) {
1548 
1549  // Nearest pseudopixels have uncertainties of 50% of threshold, next-nearest have 10% of threshold
1550 
1551  ysig2[i] = s50_*s50_;
1552  } else {
1553  if(ysum[i] < symax) {
1554  sigi = ysum[i];
1555  qscale = 1.f;
1556  } else {
1557  sigi = symax;
1558  qscale = ysum[i]/symax;
1559  }
1560  sigi2 = sigi*sigi; sigi3 = sigi2*sigi; sigi4 = sigi3*sigi;
1561  if(i <= BHY) {
1562  ysig2[i] = (1.f-yratio_)*
1563  (yparl_[0][0]+yparl_[0][1]*sigi+yparl_[0][2]*sigi2+yparl_[0][3]*sigi3+yparl_[0][4]*sigi4)
1564  + yratio_*
1565  (yparh_[0][0]+yparh_[0][1]*sigi+yparh_[0][2]*sigi2+yparh_[0][3]*sigi3+yparh_[0][4]*sigi4);
1566  } else {
1567  ysig2[i] = (1.f-yratio_)*
1568  (yparl_[1][0]+yparl_[1][1]*sigi+yparl_[1][2]*sigi2+yparl_[1][3]*sigi3+yparl_[1][4]*sigi4)
1569  + yratio_*
1570  (yparh_[1][0]+yparh_[1][1]*sigi+yparh_[1][2]*sigi2+yparh_[1][3]*sigi3+yparh_[1][4]*sigi4);
1571  }
1572  ysig2[i] *=qscale;
1573  if(ysum[i] > sythr) {ysig2[i] = 1.e8;}
1574  if(ysig2[i] <= 0.f) {LOGERROR("SiPixelTemplate") << "neg y-error-squared, id = " << id_current_ << ", index = " << index_id_ <<
1575  ", cot(alpha) = " << cota_current_ << ", cot(beta) = " << cotb_current_ << ", sigi = " << sigi << ENDL;}
1576  }
1577  }
1578 
1579  return;
1580 
1581 } // End ysigma2
1582 
1583 
1584 // ************************************************************************************************************
1590 // ************************************************************************************************************
1591 void SiPixelTemplate::ysigma2(float qpixel, int index, float& ysig2)
1592 
1593 {
1594  // Interpolate using quantities already stored in the private variables
1595 
1596  // Local variables
1597  float sigi, sigi2, sigi3, sigi4, symax, qscale, err2;
1598 
1599  // Make sure that input is OK
1600 
1601 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1602  if(index < 2 || index >= BYM2) {
1603  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::ysigma2 called with index = " << index << std::endl;
1604  }
1605 #else
1606  assert(index > 1 && index < BYM2);
1607 #endif
1608 
1609  // Define the maximum signal to use in the parameterization
1610 
1611  symax = symax_;
1612  if(symax_ > syparmax_) {symax = syparmax_;}
1613 
1614  // Evaluate pixel-by-pixel uncertainties (weights) for the templ analysis
1615 
1616  if(qpixel < symax) {
1617  sigi = qpixel;
1618  qscale = 1.f;
1619  } else {
1620  sigi = symax;
1621  qscale = qpixel/symax;
1622  }
1623  sigi2 = sigi*sigi; sigi3 = sigi2*sigi; sigi4 = sigi3*sigi;
1624  if(index <= BHY) {
1625  err2 = (1.f-yratio_)*
1626  (yparl_[0][0]+yparl_[0][1]*sigi+yparl_[0][2]*sigi2+yparl_[0][3]*sigi3+yparl_[0][4]*sigi4)
1627  + yratio_*
1628  (yparh_[0][0]+yparh_[0][1]*sigi+yparh_[0][2]*sigi2+yparh_[0][3]*sigi3+yparh_[0][4]*sigi4);
1629  } else {
1630  err2 = (1.f-yratio_)*
1631  (yparl_[1][0]+yparl_[1][1]*sigi+yparl_[1][2]*sigi2+yparl_[1][3]*sigi3+yparl_[1][4]*sigi4)
1632  + yratio_*
1633  (yparh_[1][0]+yparh_[1][1]*sigi+yparh_[1][2]*sigi2+yparh_[1][3]*sigi3+yparh_[1][4]*sigi4);
1634  }
1635  ysig2 =qscale*err2;
1636  if(ysig2 <= 0.f) {LOGERROR("SiPixelTemplate") << "neg y-error-squared, id = " << id_current_ << ", index = " << index_id_ <<
1637  ", cot(alpha) = " << cota_current_ << ", cot(beta) = " << cotb_current_ << ", sigi = " << sigi << ENDL;}
1638 
1639  return;
1640 
1641 } // End ysigma2
1642 
1643 
1644 
1645 
1646 
1647 // ************************************************************************************************************
1655 // ************************************************************************************************************
1656 void SiPixelTemplate::xsigma2(int fxpix, int lxpix, float sxthr, float xsum[11], float xsig2[11])
1657 
1658 {
1659  // Interpolate using quantities already stored in the private variables
1660 
1661  // Local variables
1662  int i;
1663  float sigi, sigi2, sigi3, sigi4, yint, sxmax, x0, qscale;
1664 
1665  // Make sure that input is OK
1666 
1667 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1668  if(fxpix < 2 || fxpix >= BXM2) {
1669  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::xsigma2 called with fxpix = " << fxpix << std::endl;
1670  }
1671 #else
1672  assert(fxpix > 1 && fxpix < BXM2);
1673 #endif
1674 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1675  if(lxpix < fxpix || lxpix >= BXM2) {
1676  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::xsigma2 called with lxpix/fxpix = " << lxpix << "/" << fxpix << std::endl;
1677  }
1678 #else
1679  assert(lxpix >= fxpix && lxpix < BXM2);
1680 #endif
1681 
1682  // Define the maximum signal to use in the parameterization
1683 
1684  sxmax = sxmax_;
1685  if(sxmax_ > sxparmax_) {sxmax = sxparmax_;}
1686 
1687  // Evaluate pixel-by-pixel uncertainties (weights) for the templ analysis
1688 
1689  for(i=fxpix-2; i<=lxpix+2; ++i) {
1690  if(i < fxpix || i > lxpix) {
1691 
1692  // Nearest pseudopixels have uncertainties of 50% of threshold, next-nearest have 10% of threshold
1693 
1694  xsig2[i] = s50_*s50_;
1695  } else {
1696  if(xsum[i] < sxmax) {
1697  sigi = xsum[i];
1698  qscale = 1.f;
1699  } else {
1700  sigi = sxmax;
1701  qscale = xsum[i]/sxmax;
1702  }
1703  sigi2 = sigi*sigi; sigi3 = sigi2*sigi; sigi4 = sigi3*sigi;
1704 
1705  // First, do the cotbeta interpolation
1706 
1707  if(i <= BHX) {
1708  yint = (1.f-yratio_)*
1709  (xparly0_[0][0]+xparly0_[0][1]*sigi+xparly0_[0][2]*sigi2+xparly0_[0][3]*sigi3+xparly0_[0][4]*sigi4)
1710  + yratio_*
1711  (xparhy0_[0][0]+xparhy0_[0][1]*sigi+xparhy0_[0][2]*sigi2+xparhy0_[0][3]*sigi3+xparhy0_[0][4]*sigi4);
1712  } else {
1713  yint = (1.f-yratio_)*
1714  (xparly0_[1][0]+xparly0_[1][1]*sigi+xparly0_[1][2]*sigi2+xparly0_[1][3]*sigi3+xparly0_[1][4]*sigi4)
1715  + yratio_*
1716  (xparhy0_[1][0]+xparhy0_[1][1]*sigi+xparhy0_[1][2]*sigi2+xparhy0_[1][3]*sigi3+xparhy0_[1][4]*sigi4);
1717  }
1718 
1719  // Next, do the cotalpha interpolation
1720 
1721  if(i <= BHX) {
1722  xsig2[i] = (1.f-xxratio_)*
1723  (xparl_[0][0]+xparl_[0][1]*sigi+xparl_[0][2]*sigi2+xparl_[0][3]*sigi3+xparl_[0][4]*sigi4)
1724  + xxratio_*
1725  (xparh_[0][0]+xparh_[0][1]*sigi+xparh_[0][2]*sigi2+xparh_[0][3]*sigi3+xparh_[0][4]*sigi4);
1726  } else {
1727  xsig2[i] = (1.f-xxratio_)*
1728  (xparl_[1][0]+xparl_[1][1]*sigi+xparl_[1][2]*sigi2+xparl_[1][3]*sigi3+xparl_[1][4]*sigi4)
1729  + xxratio_*
1730  (xparh_[1][0]+xparh_[1][1]*sigi+xparh_[1][2]*sigi2+xparh_[1][3]*sigi3+xparh_[1][4]*sigi4);
1731  }
1732 
1733  // Finally, get the mid-point value of the cotalpha function
1734 
1735  if(i <= BHX) {
1736  x0 = xpar0_[0][0]+xpar0_[0][1]*sigi+xpar0_[0][2]*sigi2+xpar0_[0][3]*sigi3+xpar0_[0][4]*sigi4;
1737  } else {
1738  x0 = xpar0_[1][0]+xpar0_[1][1]*sigi+xpar0_[1][2]*sigi2+xpar0_[1][3]*sigi3+xpar0_[1][4]*sigi4;
1739  }
1740 
1741  // Finally, rescale the yint value for cotalpha variation
1742 
1743  if(x0 != 0.f) {xsig2[i] = xsig2[i]/x0 * yint;}
1744  xsig2[i] *=qscale;
1745  if(xsum[i] > sxthr) {xsig2[i] = 1.e8;}
1746  if(xsig2[i] <= 0.f) {LOGERROR("SiPixelTemplate") << "neg x-error-squared, id = " << id_current_ << ", index = " << index_id_ <<
1747  ", cot(alpha) = " << cota_current_ << ", cot(beta) = " << cotb_current_ << ", sigi = " << sigi << ENDL;}
1748  }
1749  }
1750 
1751  return;
1752 
1753 } // End xsigma2
1754 
1755 
1756 
1757 
1758 
1759 
1760 // ************************************************************************************************************
1764 // ************************************************************************************************************
1765 float SiPixelTemplate::yflcorr(int binq, float qfly)
1766 
1767 {
1768  // Interpolate using quantities already stored in the private variables
1769 
1770  // Local variables
1771  float qfl, qfl2, qfl3, qfl4, qfl5, dy;
1772 
1773  // Make sure that input is OK
1774 
1775 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1776  if(binq < 0 || binq > 3) {
1777  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::yflcorr called with binq = " << binq << std::endl;
1778  }
1779 #else
1780  assert(binq >= 0 && binq < 4);
1781 #endif
1782 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1783  if(fabs((double)qfly) > 1.) {
1784  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::yflcorr called with qfly = " << qfly << std::endl;
1785  }
1786 #else
1787  assert(fabs((double)qfly) <= 1.);
1788 #endif
1789 
1790  // Define the maximum signal to allow before de-weighting a pixel
1791 
1792  qfl = qfly;
1793 
1794  if(qfl < -0.9f) {qfl = -0.9f;}
1795  if(qfl > 0.9f) {qfl = 0.9f;}
1796 
1797  // Interpolate between the two polynomials
1798 
1799  qfl2 = qfl*qfl; qfl3 = qfl2*qfl; qfl4 = qfl3*qfl; qfl5 = qfl4*qfl;
1800  dy = (1.f-yratio_)*(yflparl_[binq][0]+yflparl_[binq][1]*qfl+yflparl_[binq][2]*qfl2+yflparl_[binq][3]*qfl3+yflparl_[binq][4]*qfl4+yflparl_[binq][5]*qfl5)
1801  + yratio_*(yflparh_[binq][0]+yflparh_[binq][1]*qfl+yflparh_[binq][2]*qfl2+yflparh_[binq][3]*qfl3+yflparh_[binq][4]*qfl4+yflparh_[binq][5]*qfl5);
1802 
1803  return dy;
1804 
1805 } // End yflcorr
1806 
1807 
1808 
1809 
1810 
1811 
1812 // ************************************************************************************************************
1816 // ************************************************************************************************************
1817 float SiPixelTemplate::xflcorr(int binq, float qflx)
1818 
1819 {
1820  // Interpolate using quantities already stored in the private variables
1821 
1822  // Local variables
1823  float qfl, qfl2, qfl3, qfl4, qfl5, dx;
1824 
1825  // Make sure that input is OK
1826 
1827 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1828  if(binq < 0 || binq > 3) {
1829  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::xflcorr called with binq = " << binq << std::endl;
1830  }
1831 #else
1832  assert(binq >= 0 && binq < 4);
1833 #endif
1834 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1835  if(fabs((double)qflx) > 1.) {
1836  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::xflcorr called with qflx = " << qflx << std::endl;
1837  }
1838 #else
1839  assert(fabs((double)qflx) <= 1.);
1840 #endif
1841 
1842  // Define the maximum signal to allow before de-weighting a pixel
1843 
1844  qfl = qflx;
1845 
1846  if(qfl < -0.9f) {qfl = -0.9f;}
1847  if(qfl > 0.9f) {qfl = 0.9f;}
1848 
1849  // Interpolate between the two polynomials
1850 
1851  qfl2 = qfl*qfl; qfl3 = qfl2*qfl; qfl4 = qfl3*qfl; qfl5 = qfl4*qfl;
1852  dx = (1.f - yxratio_)*((1.f-xxratio_)*(xflparll_[binq][0]+xflparll_[binq][1]*qfl+xflparll_[binq][2]*qfl2+xflparll_[binq][3]*qfl3+xflparll_[binq][4]*qfl4+xflparll_[binq][5]*qfl5)
1853  + xxratio_*(xflparlh_[binq][0]+xflparlh_[binq][1]*qfl+xflparlh_[binq][2]*qfl2+xflparlh_[binq][3]*qfl3+xflparlh_[binq][4]*qfl4+xflparlh_[binq][5]*qfl5))
1854  + yxratio_*((1.f-xxratio_)*(xflparhl_[binq][0]+xflparhl_[binq][1]*qfl+xflparhl_[binq][2]*qfl2+xflparhl_[binq][3]*qfl3+xflparhl_[binq][4]*qfl4+xflparhl_[binq][5]*qfl5)
1855  + xxratio_*(xflparhh_[binq][0]+xflparhh_[binq][1]*qfl+xflparhh_[binq][2]*qfl2+xflparhh_[binq][3]*qfl3+xflparhh_[binq][4]*qfl4+xflparhh_[binq][5]*qfl5));
1856 
1857  return dx;
1858 
1859 } // End xflcorr
1860 
1861 
1862 
1863 // ************************************************************************************************************
1868 // ************************************************************************************************************
1869 void SiPixelTemplate::ytemp(int fybin, int lybin, float ytemplate[41][BYSIZE])
1870 
1871 {
1872  // Retrieve already interpolated quantities
1873 
1874  // Local variables
1875  int i, j;
1876 
1877  // Verify that input parameters are in valid range
1878 
1879 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1880  if(fybin < 0 || fybin > 40) {
1881  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::ytemp called with fybin = " << fybin << std::endl;
1882  }
1883 #else
1884  assert(fybin >= 0 && fybin < 41);
1885 #endif
1886 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1887  if(lybin < 0 || lybin > 40) {
1888  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::ytemp called with lybin = " << lybin << std::endl;
1889  }
1890 #else
1891  assert(lybin >= 0 && lybin < 41);
1892 #endif
1893 
1894  // Build the y-template, the central 25 bins are here in all cases
1895 
1896  for(i=0; i<9; ++i) {
1897  for(j=0; j<BYSIZE; ++j) {
1898  ytemplate[i+16][j]=ytemp_[i][j];
1899  }
1900  }
1901  for(i=0; i<8; ++i) {
1902  ytemplate[i+8][BYM1] = 0.f;
1903  for(j=0; j<BYM1; ++j) {
1904  ytemplate[i+8][j]=ytemp_[i][j+1];
1905  }
1906  }
1907  for(i=1; i<9; ++i) {
1908  ytemplate[i+24][0] = 0.f;
1909  for(j=0; j<BYM1; ++j) {
1910  ytemplate[i+24][j+1]=ytemp_[i][j];
1911  }
1912  }
1913 
1914  // Add more bins if needed
1915 
1916  if(fybin < 8) {
1917  for(i=0; i<8; ++i) {
1918  ytemplate[i][BYM2] = 0.f;
1919  ytemplate[i][BYM1] = 0.f;
1920  for(j=0; j<BYM2; ++j) {
1921  ytemplate[i][j]=ytemp_[i][j+2];
1922  }
1923  }
1924  }
1925  if(lybin > 32) {
1926  for(i=1; i<9; ++i) {
1927  ytemplate[i+32][0] = 0.f;
1928  ytemplate[i+32][1] = 0.f;
1929  for(j=0; j<BYM2; ++j) {
1930  ytemplate[i+32][j+2]=ytemp_[i][j];
1931  }
1932  }
1933  }
1934 
1935  return;
1936 
1937 } // End ytemp
1938 
1939 
1940 
1941 // ************************************************************************************************************
1946 // ************************************************************************************************************
1947 void SiPixelTemplate::xtemp(int fxbin, int lxbin, float xtemplate[41][BXSIZE])
1948 
1949 {
1950  // Retrieve already interpolated quantities
1951 
1952  // Local variables
1953  int i, j;
1954 
1955  // Verify that input parameters are in valid range
1956 
1957 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1958  if(fxbin < 0 || fxbin > 40) {
1959  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::xtemp called with fxbin = " << fxbin << std::endl;
1960  }
1961 #else
1962  assert(fxbin >= 0 && fxbin < 41);
1963 #endif
1964 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
1965  if(lxbin < 0 || lxbin > 40) {
1966  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::xtemp called with lxbin = " << lxbin << std::endl;
1967  }
1968 #else
1969  assert(lxbin >= 0 && lxbin < 41);
1970 #endif
1971 
1972  // Build the x-template, the central 25 bins are here in all cases
1973 
1974  for(i=0; i<9; ++i) {
1975  for(j=0; j<BXSIZE; ++j) {
1976  xtemplate[i+16][j]=xtemp_[i][j];
1977  }
1978  }
1979  for(i=0; i<8; ++i) {
1980  xtemplate[i+8][BXM1] = 0.f;
1981  for(j=0; j<BXM1; ++j) {
1982  xtemplate[i+8][j]=xtemp_[i][j+1];
1983  }
1984  }
1985  for(i=1; i<9; ++i) {
1986  xtemplate[i+24][0] = 0.f;
1987  for(j=0; j<BXM1; ++j) {
1988  xtemplate[i+24][j+1]=xtemp_[i][j];
1989  }
1990  }
1991 
1992  // Add more bins if needed
1993 
1994  if(fxbin < 8) {
1995  for(i=0; i<8; ++i) {
1996  xtemplate[i][BXM2] = 0.f;
1997  xtemplate[i][BXM1] = 0.f;
1998  for(j=0; j<BXM2; ++j) {
1999  xtemplate[i][j]=xtemp_[i][j+2];
2000  }
2001  }
2002  }
2003  if(lxbin > 32) {
2004  for(i=1; i<9; ++i) {
2005  xtemplate[i+32][0] = 0.f;
2006  xtemplate[i+32][1] = 0.f;
2007  for(j=0; j<BXM2; ++j) {
2008  xtemplate[i+32][j+2]=xtemp_[i][j];
2009  }
2010  }
2011  }
2012 
2013  return;
2014 
2015 } // End xtemp
2016 
2017 
2018 // ************************************************************************************************************
2020 // ************************************************************************************************************
2022 
2023 {
2024  // Retrieve already interpolated quantities
2025 
2026  // Local variables
2027  int j;
2028 
2029  // Analyze only pixels along the central entry
2030  // First, find the maximum signal and then work out to the edges
2031 
2032  float sigmax = 0.f;
2033  float qedge = 2.*s50_;
2034  int jmax = -1;
2035 
2036  for(j=0; j<BYSIZE; ++j) {
2037  if(ytemp_[4][j] > sigmax) {
2038  sigmax = ytemp_[4][j];
2039  jmax = j;
2040  }
2041  }
2042  if(sigmax < qedge) {qedge = s50_;}
2043  if(sigmax < qedge || jmax<1 || jmax>BYM2) {return -1;}
2044 
2045  // Now search forward and backward
2046 
2047  int jend = jmax;
2048 
2049  for(j=jmax+1; j<BYM1; ++j) {
2050  if(ytemp_[4][j] < qedge) break;
2051  jend = j;
2052  }
2053 
2054  int jbeg = jmax;
2055 
2056  for(j=jmax-1; j>0; --j) {
2057  if(ytemp_[4][j] < qedge) break;
2058  jbeg = j;
2059  }
2060 
2061  return (jbeg+jend)/2;
2062 
2063 } // End cytemp
2064 
2065 
2066 
2067 // ************************************************************************************************************
2069 // ************************************************************************************************************
2071 
2072 {
2073  // Retrieve already interpolated quantities
2074 
2075  // Local variables
2076  int j;
2077 
2078  // Analyze only pixels along the central entry
2079  // First, find the maximum signal and then work out to the edges
2080 
2081  float sigmax = 0.f;
2082  float qedge = 2.*s50_;
2083  int jmax = -1;
2084 
2085  for(j=0; j<BXSIZE; ++j) {
2086  if(xtemp_[4][j] > sigmax) {
2087  sigmax = xtemp_[4][j];
2088  jmax = j;
2089  }
2090  }
2091  if(sigmax < qedge) {qedge = s50_;}
2092  if(sigmax < qedge || jmax<1 || jmax>BXM2) {return -1;}
2093 
2094  // Now search forward and backward
2095 
2096  int jend = jmax;
2097 
2098  for(j=jmax+1; j<BXM1; ++j) {
2099  if(xtemp_[4][j] < qedge) break;
2100  jend = j;
2101  }
2102 
2103  int jbeg = jmax;
2104 
2105  for(j=jmax-1; j>0; --j) {
2106  if(xtemp_[4][j] < qedge) break;
2107  jbeg = j;
2108  }
2109 
2110  return (jbeg+jend)/2;
2111 
2112 } // End cxtemp
2113 
2114 
2115 // ************************************************************************************************************
2119 // ************************************************************************************************************
2120 void SiPixelTemplate::ytemp3d_int(int nypix, int& nybins)
2121 
2122 {
2123 
2124  // Retrieve already interpolated quantities
2125 
2126  // Local variables
2127  int i, j, k;
2128  int ioff0, ioffp, ioffm;
2129 
2130  // Verify that input parameters are in valid range
2131 
2132 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
2133  if(nypix < 1 || nypix >= BYM3) {
2134  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::ytemp3d called with nypix = " << nypix << std::endl;
2135  }
2136 #else
2137  assert(nypix > 0 && nypix < BYM3);
2138 #endif
2139 
2140  // Calculate the size of the shift in pixels needed to span the entire cluster
2141 
2142  float diff = fabsf(nypix - clsleny_)/2. + 1.f;
2143  int nshift = (int)diff;
2144  if((diff - nshift) > 0.5f) {++nshift;}
2145 
2146  // Calculate the number of bins needed to specify each hit range
2147 
2148  nybins_ = 9 + 16*nshift;
2149 
2150  // Create a 2-d working template with the correct size
2151 
2152  temp2dy_.resize(boost::extents[nybins_][BYSIZE]);
2153 
2154  // The 9 central bins are copied from the interpolated private store
2155 
2156  ioff0 = 8*nshift;
2157 
2158  for(i=0; i<9; ++i) {
2159  for(j=0; j<BYSIZE; ++j) {
2160  temp2dy_[i+ioff0][j]=ytemp_[i][j];
2161  }
2162  }
2163 
2164  // Add the +- shifted templates
2165 
2166  for(k=1; k<=nshift; ++k) {
2167  ioffm=ioff0-k*8;
2168  for(i=0; i<8; ++i) {
2169  for(j=0; j<k; ++j) {
2170  temp2dy_[i+ioffm][BYM1-j] = 0.f;
2171  }
2172  for(j=0; j<BYSIZE-k; ++j) {
2173  temp2dy_[i+ioffm][j]=ytemp_[i][j+k];
2174  }
2175  }
2176  ioffp=ioff0+k*8;
2177  for(i=1; i<9; ++i) {
2178  for(j=0; j<k; ++j) {
2179  temp2dy_[i+ioffp][j] = 0.f;
2180  }
2181  for(j=0; j<BYSIZE-k; ++j) {
2182  temp2dy_[i+ioffp][j+k]=ytemp_[i][j];
2183  }
2184  }
2185  }
2186 
2187  nybins = nybins_;
2188  return;
2189 
2190 } // End ytemp3d_int
2191 
2192 
2193 // ************************************************************************************************************
2197 // ************************************************************************************************************
2198 void SiPixelTemplate::ytemp3d(int i, int j, std::vector<float>& ytemplate)
2199 
2200 {
2201  // Sum two 2-d templates to make the 3-d template
2202  if(i >= 0 && i < nybins_ && j <= i) {
2203  for(int k=0; k<BYSIZE; ++k) {
2204  ytemplate[k]=temp2dy_[i][k]+temp2dy_[j][k];
2205  }
2206  } else {
2207  for(int k=0; k<BYSIZE; ++k) {
2208  ytemplate[k]=0.;
2209  }
2210  }
2211 
2212  return;
2213 
2214 } // End ytemp3d
2215 
2216 
2217 // ************************************************************************************************************
2221 // ************************************************************************************************************
2222 void SiPixelTemplate::xtemp3d_int(int nxpix, int& nxbins)
2223 
2224 {
2225  // Retrieve already interpolated quantities
2226 
2227  // Local variables
2228  int i, j, k;
2229  int ioff0, ioffp, ioffm;
2230 
2231  // Verify that input parameters are in valid range
2232 
2233 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
2234  if(nxpix < 1 || nxpix >= BXM3) {
2235  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::xtemp3d called with nxpix = " << nxpix << std::endl;
2236  }
2237 #else
2238  assert(nxpix > 0 && nxpix < BXM3);
2239 #endif
2240 
2241  // Calculate the size of the shift in pixels needed to span the entire cluster
2242 
2243  float diff = fabsf(nxpix - clslenx_)/2.f + 1.f;
2244  int nshift = (int)diff;
2245  if((diff - nshift) > 0.5f) {++nshift;}
2246 
2247  // Calculate the number of bins needed to specify each hit range
2248 
2249  nxbins_ = 9 + 16*nshift;
2250 
2251  // Create a 2-d working template with the correct size
2252 
2253  temp2dx_.resize(boost::extents[nxbins_][BXSIZE]);
2254 
2255  // The 9 central bins are copied from the interpolated private store
2256 
2257  ioff0 = 8*nshift;
2258 
2259  for(i=0; i<9; ++i) {
2260  for(j=0; j<BXSIZE; ++j) {
2261  temp2dx_[i+ioff0][j]=xtemp_[i][j];
2262  }
2263  }
2264 
2265  // Add the +- shifted templates
2266 
2267  for(k=1; k<=nshift; ++k) {
2268  ioffm=ioff0-k*8;
2269  for(i=0; i<8; ++i) {
2270  for(j=0; j<k; ++j) {
2271  temp2dx_[i+ioffm][BXM1-j] = 0.f;
2272  }
2273  for(j=0; j<BXSIZE-k; ++j) {
2274  temp2dx_[i+ioffm][j]=xtemp_[i][j+k];
2275  }
2276  }
2277  ioffp=ioff0+k*8;
2278  for(i=1; i<9; ++i) {
2279  for(j=0; j<k; ++j) {
2280  temp2dx_[i+ioffp][j] = 0.f;
2281  }
2282  for(j=0; j<BXSIZE-k; ++j) {
2283  temp2dx_[i+ioffp][j+k]=xtemp_[i][j];
2284  }
2285  }
2286  }
2287 
2288  nxbins = nxbins_;
2289 
2290  return;
2291 
2292 } // End xtemp3d_int
2293 
2294 
2295 
2296 // ************************************************************************************************************
2300 // ************************************************************************************************************
2301 void SiPixelTemplate::xtemp3d(int i, int j, std::vector<float>& xtemplate)
2302 
2303 {
2304  // Sum two 2-d templates to make the 3-d template
2305  if(i >= 0 && i < nxbins_ && j <= i) {
2306  for(int k=0; k<BXSIZE; ++k) {
2307  xtemplate[k]=temp2dx_[i][k]+temp2dx_[j][k];
2308  }
2309  } else {
2310  for(int k=0; k<BXSIZE; ++k) {
2311  xtemplate[k]=0.;
2312  }
2313  }
2314 
2315  return;
2316 
2317 } // End xtemp3d
2318 
2319 
2320 // ************************************************************************************************************
2348 // ************************************************************************************************************
2349 int SiPixelTemplate::qbin(int id, float cotalpha, float cotbeta, float locBz, float locBx, float qclus, float& pixmx,
2350  float& sigmay, float& deltay, float& sigmax, float& deltax,float& sy1, float& dy1, float& sy2,
2351  float& dy2, float& sx1, float& dx1, float& sx2, float& dx2) // float& lorywidth, float& lorxwidth)
2352 {
2353  // Interpolate for a new set of track angles
2354 
2355 
2356  // Find the index corresponding to id
2357 
2358  int index = -1;
2359  for( int i=0; i<(int)thePixelTemp_.size(); ++i) {
2360  if(id == thePixelTemp_[i].head.ID) {
2361  index = i;
2362  break;
2363  }
2364  }
2365 
2366 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
2367  if(index < 0 || index >= (int)thePixelTemp_.size()) {
2368  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::qbin can't find needed template ID = " << id << std::endl;
2369  }
2370 #else
2371  assert(index >= 0 && index < (int)thePixelTemp_.size());
2372 #endif
2373 
2374  //
2375 
2376 
2377  auto const & templ = thePixelTemp_[index];
2378 
2379  // Interpolate the absolute value of cot(beta)
2380 
2381  auto acotb = std::abs(cotbeta);
2382 
2383  // qcorrect corrects the cot(alpha)=0 cluster charge for non-zero cot(alpha)
2384 
2385  auto cotalpha0 = thePixelTemp_[index].enty[0].cotalpha;
2386  auto qcorrect=std::sqrt((1.f+cotbeta*cotbeta+cotalpha*cotalpha)/(1.f+cotbeta*cotbeta+cotalpha0*cotalpha0));
2387 
2388  // for some cosmics, the ususal gymnastics are incorrect
2389 
2390  float cota = cotalpha;
2391  float cotb = abs_cotb_;
2392  bool flip_x = false;
2393  bool flip_y = false;
2394  switch(thePixelTemp_[index_id_].head.Dtype) {
2395  case 0:
2396  if(cotbeta < 0.f) {flip_y = true;}
2397  break;
2398  case 1:
2399  if(locBz < 0.f) {
2400  cotb = cotbeta;
2401  } else {
2402  cotb = -cotbeta;
2403  flip_y = true;
2404  }
2405  break;
2406  case 2:
2407  case 3:
2408  case 4:
2409  if(locBx*locBz < 0.f) {
2410  cota = -cotalpha;
2411  flip_x = true;
2412  }
2413  if(locBx > 0.f) {
2414  cotb = cotbeta;
2415  } else {
2416  cotb = -cotbeta;
2417  flip_y = true;
2418  }
2419  break;
2420  default:
2421 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
2422  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::illegal subdetector ID = " << thePixelTemp_[index_id_].head.Dtype << std::endl;
2423 #else
2424  std::cout << "SiPixelTemplate::illegal subdetector ID = " << thePixelTemp_[index_id_].head.Dtype << std::endl;
2425 #endif
2426  }
2427 
2428 
2429  // Copy the charge scaling factor to the private variable
2430 
2431 
2432  auto qscale = thePixelTemp_[index].head.qscale;
2433 
2434 
2435  /*
2436  lorywidth = thePixelTemp_[index].head.lorywidth;
2437  if(locBz > 0.f) {lorywidth = -lorywidth;}
2438  lorxwidth = thePixelTemp_[index].head.lorxwidth;
2439  */
2440 
2441 
2442  auto Ny = thePixelTemp_[index].head.NTy;
2443  auto Nyx = thePixelTemp_[index].head.NTyx;
2444  auto Nxx = thePixelTemp_[index].head.NTxx;
2445 
2446 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
2447  if(Ny < 2 || Nyx < 1 || Nxx < 2) {
2448  throw cms::Exception("DataCorrupt") << "template ID = " << id_current_ << "has too few entries: Ny/Nyx/Nxx = " << Ny << "/" << Nyx << "/" << Nxx << std::endl;
2449  }
2450 #else
2451  assert(Ny > 1 && Nyx > 0 && Nxx > 1);
2452 #endif
2453 
2454  // next, loop over all y-angle entries
2455 
2456  auto ilow = 0;
2457  auto ihigh = 0;
2458  auto yratio = 0.f;
2459 
2460  {
2461  auto j = std::lower_bound(templ.cotbetaY,templ.cotbetaY+Ny,cotb);
2462  if (j==templ.cotbetaY+Ny) { --j; yratio = 1.f; }
2463  else if (j==templ.cotbetaY) { ++j; yratio = 0.f;}
2464  else { yratio = (cotb - (*(j-1)) )/( (*j) - (*(j-1)) ) ; }
2465 
2466  ihigh = j-templ.cotbetaY;
2467  ilow = ihigh-1;
2468  }
2469 
2470 
2471 
2472  // Interpolate/store all y-related quantities (flip displacements when flip_y)
2473 
2474  dy1 = (1.f - yratio)*thePixelTemp_[index].enty[ilow].dyone + yratio*thePixelTemp_[index].enty[ihigh].dyone;
2475  if(flip_y) {dy1 = -dy1;}
2476  sy1 = (1.f - yratio)*thePixelTemp_[index].enty[ilow].syone + yratio*thePixelTemp_[index].enty[ihigh].syone;
2477  dy2 = (1.f - yratio)*thePixelTemp_[index].enty[ilow].dytwo + yratio*thePixelTemp_[index].enty[ihigh].dytwo;
2478  if(flip_y) {dy2 = -dy2;}
2479  sy2 = (1.f - yratio)*thePixelTemp_[index].enty[ilow].sytwo + yratio*thePixelTemp_[index].enty[ihigh].sytwo;
2480 
2481  auto qavg = (1.f - yratio)*thePixelTemp_[index].enty[ilow].qavg + yratio*thePixelTemp_[index].enty[ihigh].qavg;
2482  qavg *= qcorrect;
2483  auto qmin = (1.f - yratio)*thePixelTemp_[index].enty[ilow].qmin + yratio*thePixelTemp_[index].enty[ihigh].qmin;
2484  qmin *= qcorrect;
2485  auto qmin2 = (1.f - yratio)*thePixelTemp_[index].enty[ilow].qmin2 + yratio*thePixelTemp_[index].enty[ihigh].qmin2;
2486  qmin2 *= qcorrect;
2487 
2488 
2489 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
2490  if(qavg <= 0.f || qmin <= 0.f) {
2491  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::qbin, qavg or qmin <= 0,"
2492  << " Probably someone called the generic pixel reconstruction with an illegal trajectory state" << std::endl;
2493  }
2494 #else
2495  assert(qavg > 0.f && qmin > 0.f);
2496 #endif
2497 
2498  // Scale the input charge to account for differences between pixelav and CMSSW simulation or data
2499 
2500  auto qtotal = qscale*qclus;
2501 
2502  // uncertainty and final corrections depend upon total charge bin
2503  auto fq = qtotal/qavg;
2504  int binq;
2505 
2506  if(fq > fbin_[0]) {
2507  binq=0;
2508  //std::cout<<" fq "<<fq<<" "<<qtotal<<" "<<qavg<<" "<<qclus<<" "<<qscale<<" "
2509  // <<fbin_[0]<<" "<<fbin_[1]<<" "<<fbin_[2]<<std::endl;
2510  } else {
2511  if(fq > fbin_[1]) {
2512  binq=1;
2513  } else {
2514  if(fq > fbin_[2]) {
2515  binq=2;
2516  } else {
2517  binq=3;
2518  }
2519  }
2520  }
2521 
2522  auto yavggen =(1.f - yratio)*thePixelTemp_[index].enty[ilow].yavggen[binq] + yratio*thePixelTemp_[index].enty[ihigh].yavggen[binq];
2523  if(flip_y) {yavggen = -yavggen;}
2524  auto yrmsgen =(1.f - yratio)*thePixelTemp_[index].enty[ilow].yrmsgen[binq] + yratio*thePixelTemp_[index].enty[ihigh].yrmsgen[binq];
2525 
2526 
2527  // next, loop over all x-angle entries, first, find relevant y-slices
2528 
2529  auto iylow = 0;
2530  auto iyhigh = 0;
2531  auto yxratio = 0.f;
2532 
2533 
2534  {
2535  auto j = std::lower_bound(templ.cotbetaX,templ.cotbetaX+Nyx,acotb);
2536  if (j==templ.cotbetaX+Nyx) { --j; yxratio = 1.f; }
2537  else if (j==templ.cotbetaX) { ++j; yxratio = 0.f;}
2538  else { yxratio = (acotb - (*(j-1)) )/( (*j) - (*(j-1)) ) ; }
2539 
2540  iyhigh = j-templ.cotbetaX;
2541  iylow = iyhigh -1;
2542  }
2543 
2544 
2545 
2546  ilow = ihigh = 0;
2547  auto xxratio = 0.f;
2548 
2549  {
2550  auto j = std::lower_bound(templ.cotalphaX,templ.cotalphaX+Nxx,cotalpha);
2551  if (j==templ.cotalphaX+Nxx) { --j; xxratio = 1.f; }
2552  else if (j==templ.cotalphaX) { ++j; xxratio = 0.f;}
2553  else { xxratio = (cota - (*(j-1)) )/( (*j) - (*(j-1)) ) ; }
2554 
2555  ihigh = j-templ.cotalphaX;
2556  ilow = ihigh-1;
2557  }
2558 
2559 
2560 
2561  dx1 = (1.f - xxratio)*thePixelTemp_[index].entx[0][ilow].dxone + xxratio*thePixelTemp_[index].entx[0][ihigh].dxone;
2562  if(flip_x) {dx1 = -dx1;}
2563  sx1 = (1.f - xxratio)*thePixelTemp_[index].entx[0][ilow].sxone + xxratio*thePixelTemp_[index].entx[0][ihigh].sxone;
2564  dx2 = (1.f - xxratio)*thePixelTemp_[index].entx[0][ilow].dxtwo + xxratio*thePixelTemp_[index].entx[0][ihigh].dxtwo;
2565  if(flip_x) {dx2 = -dx2;}
2566  sx2 = (1.f - xxratio)*thePixelTemp_[index].entx[0][ilow].sxtwo + xxratio*thePixelTemp_[index].entx[0][ihigh].sxtwo;
2567 
2568  // pixmax is the maximum allowed pixel charge (used for truncation)
2569 
2570  pixmx=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index].entx[iylow][ilow].pixmax + xxratio*thePixelTemp_[index].entx[iylow][ihigh].pixmax)
2571  +yxratio*((1.f - xxratio)*thePixelTemp_[index].entx[iyhigh][ilow].pixmax + xxratio*thePixelTemp_[index].entx[iyhigh][ihigh].pixmax);
2572 
2573  auto xavggen = (1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index].entx[iylow][ilow].xavggen[binq] + xxratio*thePixelTemp_[index].entx[iylow][ihigh].xavggen[binq])
2574  +yxratio*((1.f - xxratio)*thePixelTemp_[index].entx[iyhigh][ilow].xavggen[binq] + xxratio*thePixelTemp_[index].entx[iyhigh][ihigh].xavggen[binq]);
2575  if(flip_x) {xavggen = -xavggen;}
2576 
2577  auto xrmsgen = (1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index].entx[iylow][ilow].xrmsgen[binq] + xxratio*thePixelTemp_[index].entx[iylow][ihigh].xrmsgen[binq])
2578  +yxratio*((1.f - xxratio)*thePixelTemp_[index].entx[iyhigh][ilow].xrmsgen[binq] + xxratio*thePixelTemp_[index].entx[iyhigh][ihigh].xrmsgen[binq]);
2579 
2580 
2581 
2582  // Take the errors and bias from the correct charge bin
2583 
2584  sigmay = yrmsgen; deltay = yavggen;
2585 
2586  sigmax = xrmsgen; deltax = xavggen;
2587 
2588  // If the charge is too small (then flag it)
2589 
2590  if(qtotal < 0.95f*qmin) {binq = 5;} else {if(qtotal < 0.95f*qmin2) {binq = 4;}}
2591 
2592  return binq;
2593 
2594 } // qbin
2595 
2596 
2597 // ************************************************************************************************************
2625 // ************************************************************************************************************
2626 int SiPixelTemplate::qbin(int id, float cotalpha, float cotbeta, float locBz, float qclus, float& pixmx,
2627  float& sigmay, float& deltay, float& sigmax, float& deltax,float& sy1, float& dy1, float& sy2,
2628  float& dy2, float& sx1, float& dx1, float& sx2, float& dx2) // float& lorywidth, float& lorxwidth)
2629 {
2630  // Interpolate for a new set of track angles
2631 
2632  // Local variables
2633  float locBx; // lorywidth, lorxwidth;
2634  // Local variables
2635  locBx = 1.f;
2636 
2637  return SiPixelTemplate::qbin(id, cotalpha, cotbeta, locBz, locBx, qclus, pixmx, sigmay, deltay, sigmax, deltax,
2638  sy1, dy1, sy2, dy2, sx1, dx1, sx2, dx2); // , lorywidth, lorxwidth);
2639 
2640 } // qbin
2641 
2642 // ************************************************************************************************************
2664 // ************************************************************************************************************
2665 /*
2666  int SiPixelTemplate::qbin(int id, float cotalpha, float cotbeta, float locBz, float qclus, float& pixmx, float& sigmay, float& deltay, float& sigmax, float& deltax,
2667  float& sy1, float& dy1, float& sy2, float& dy2, float& sx1, float& dx1, float& sx2, float& dx2)
2668 
2669  {
2670  float lorywidth, lorxwidth;
2671  return SiPixelTemplate::qbin(id, cotalpha, cotbeta, locBz, qclus, pixmx, sigmay, deltay, sigmax, deltax,
2672  sy1, dy1, sy2, dy2, sx1, dx1, sx2, dx2, lorywidth, lorxwidth);
2673 
2674  } // qbin
2675  */
2676 
2677 // ************************************************************************************************************
2684 // ************************************************************************************************************
2685 int SiPixelTemplate::qbin(int id, float cotalpha, float cotbeta, float qclus)
2686 {
2687  // Interpolate for a new set of track angles
2688 
2689  // Local variables
2690  float pixmx, sigmay, deltay, sigmax, deltax, sy1, dy1, sy2, dy2, sx1, dx1, sx2, dx2, locBz, locBx; // lorywidth, lorxwidth;
2691  // Local variables
2692  locBx = 1.f;
2693  if(cotbeta < 0.f) {locBx = -1.f;}
2694  locBz = locBx;
2695  if(cotalpha < 0.f) {locBz = -locBx;}
2696 
2697  return SiPixelTemplate::qbin(id, cotalpha, cotbeta, locBz, locBx, qclus, pixmx, sigmay, deltay, sigmax, deltax,
2698  sy1, dy1, sy2, dy2, sx1, dx1, sx2, dx2); // , lorywidth, lorxwidth);
2699 
2700 } // qbin
2701 
2702 // ************************************************************************************************************
2708 // ************************************************************************************************************
2709 int SiPixelTemplate::qbin(int id, float cotbeta, float qclus)
2710 {
2711  // Interpolate for a new set of track angles
2712 
2713  // Local variables
2714  float pixmx, sigmay, deltay, sigmax, deltax, sy1, dy1, sy2, dy2, sx1, dx1, sx2, dx2, locBz, locBx; //, lorywidth, lorxwidth;
2715  const float cotalpha = 0.f;
2716  locBx = 1.f;
2717  if(cotbeta < 0.f) {locBx = -1.f;}
2718  locBz = locBx;
2719  if(cotalpha < 0.f) {locBz = -locBx;}
2720  return SiPixelTemplate::qbin(id, cotalpha, cotbeta, locBz, locBx, qclus, pixmx, sigmay, deltay, sigmax, deltax,
2721  sy1, dy1, sy2, dy2, sx1, dx1, sx2, dx2); // , lorywidth, lorxwidth);
2722 
2723 } // qbin
2724 
2725 
2726 
2727 
2728 // ************************************************************************************************************
2740 // ************************************************************************************************************
2741 void SiPixelTemplate::temperrors(int id, float cotalpha, float cotbeta, int qBin, float& sigmay, float& sigmax, float& sy1, float& sy2, float& sx1, float& sx2)
2742 
2743 {
2744  // Interpolate for a new set of track angles
2745 
2746  // Local variables
2747  int i;
2748  int ilow, ihigh, iylow, iyhigh, Ny, Nxx, Nyx, index;
2749  float yratio, yxratio, xxratio;
2750  float acotb, cotb;
2751  float yrms, xrms;
2752  //bool flip_y;
2753 
2754 
2755  // Find the index corresponding to id
2756 
2757  index = -1;
2758  for(i=0; i<(int)thePixelTemp_.size(); ++i) {
2759 
2760  if(id == thePixelTemp_[i].head.ID) {
2761 
2762  index = i;
2763  break;
2764  }
2765  }
2766 
2767 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
2768  if(index < 0 || index >= (int)thePixelTemp_.size()) {
2769  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::temperrors can't find needed template ID = " << id << std::endl;
2770  }
2771 #else
2772  assert(index >= 0 && index < (int)thePixelTemp_.size());
2773 #endif
2774 
2775 
2776 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
2777  if(qBin < 0 || qBin > 5) {
2778  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::temperrors called with illegal qBin = " << qBin << std::endl;
2779  }
2780 #else
2781  assert(qBin >= 0 && qBin < 6);
2782 #endif
2783 
2784  // The error information for qBin > 3 is taken to be the same as qBin=3
2785 
2786  if(qBin > 3) {qBin = 3;}
2787  //
2788 
2789  // Interpolate the absolute value of cot(beta)
2790 
2791  acotb = fabs((double)cotbeta);
2792  cotb = cotbeta;
2793 
2794  // for some cosmics, the ususal gymnastics are incorrect
2795 
2796  // if(thePixelTemp_[index].head.Dtype == 0) {
2797  cotb = acotb;
2798  //flip_y = false;
2799  //if(cotbeta < 0.f) {flip_y = true;}
2800  // } else {
2801  // if(locBz < 0.f) {
2802  // cotb = cotbeta;
2803  // flip_y = false;
2804  // } else {
2805  // cotb = -cotbeta;
2806  // flip_y = true;
2807  // }
2808  // }
2809 
2810  // Copy the charge scaling factor to the private variable
2811 
2812  Ny = thePixelTemp_[index].head.NTy;
2813  Nyx = thePixelTemp_[index].head.NTyx;
2814  Nxx = thePixelTemp_[index].head.NTxx;
2815 
2816 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
2817  if(Ny < 2 || Nyx < 1 || Nxx < 2) {
2818  throw cms::Exception("DataCorrupt") << "template ID = " << id_current_ << "has too few entries: Ny/Nyx/Nxx = " << Ny << "/" << Nyx << "/" << Nxx << std::endl;
2819  }
2820 #else
2821  assert(Ny > 1 && Nyx > 0 && Nxx > 1);
2822 #endif
2823 
2824  // next, loop over all y-angle entries
2825 
2826  ilow = 0;
2827  yratio = 0.f;
2828 
2829  if(cotb >= thePixelTemp_[index].enty[Ny-1].cotbeta) {
2830 
2831  ilow = Ny-2;
2832  yratio = 1.f;
2833 
2834  } else {
2835 
2836  if(cotb >= thePixelTemp_[index].enty[0].cotbeta) {
2837 
2838  for (i=0; i<Ny-1; ++i) {
2839 
2840  if( thePixelTemp_[index].enty[i].cotbeta <= cotb && cotb < thePixelTemp_[index].enty[i+1].cotbeta) {
2841 
2842  ilow = i;
2843  yratio = (cotb - thePixelTemp_[index].enty[i].cotbeta)/(thePixelTemp_[index].enty[i+1].cotbeta - thePixelTemp_[index].enty[i].cotbeta);
2844  break;
2845  }
2846  }
2847  }
2848  }
2849 
2850  ihigh=ilow + 1;
2851 
2852  // Interpolate/store all y-related quantities (flip displacements when flip_y)
2853 
2854  sy1 = (1.f - yratio)*thePixelTemp_[index].enty[ilow].syone + yratio*thePixelTemp_[index].enty[ihigh].syone;
2855  sy2 = (1.f - yratio)*thePixelTemp_[index].enty[ilow].sytwo + yratio*thePixelTemp_[index].enty[ihigh].sytwo;
2856  yrms=(1.f - yratio)*thePixelTemp_[index].enty[ilow].yrms[qBin] + yratio*thePixelTemp_[index].enty[ihigh].yrms[qBin];
2857 
2858 
2859  // next, loop over all x-angle entries, first, find relevant y-slices
2860 
2861  iylow = 0;
2862  yxratio = 0.f;
2863 
2864  if(acotb >= thePixelTemp_[index].entx[Nyx-1][0].cotbeta) {
2865 
2866  iylow = Nyx-2;
2867  yxratio = 1.f;
2868 
2869  } else if(acotb >= thePixelTemp_[index].entx[0][0].cotbeta) {
2870 
2871  for (i=0; i<Nyx-1; ++i) {
2872 
2873  if( thePixelTemp_[index].entx[i][0].cotbeta <= acotb && acotb < thePixelTemp_[index].entx[i+1][0].cotbeta) {
2874 
2875  iylow = i;
2876  yxratio = (acotb - thePixelTemp_[index].entx[i][0].cotbeta)/(thePixelTemp_[index].entx[i+1][0].cotbeta - thePixelTemp_[index].entx[i][0].cotbeta);
2877  break;
2878  }
2879  }
2880  }
2881 
2882  iyhigh=iylow + 1;
2883 
2884  ilow = 0;
2885  xxratio = 0.f;
2886 
2887  if(cotalpha >= thePixelTemp_[index].entx[0][Nxx-1].cotalpha) {
2888 
2889  ilow = Nxx-2;
2890  xxratio = 1.f;
2891 
2892  } else {
2893 
2894  if(cotalpha >= thePixelTemp_[index].entx[0][0].cotalpha) {
2895 
2896  for (i=0; i<Nxx-1; ++i) {
2897 
2898  if( thePixelTemp_[index].entx[0][i].cotalpha <= cotalpha && cotalpha < thePixelTemp_[index].entx[0][i+1].cotalpha) {
2899 
2900  ilow = i;
2901  xxratio = (cotalpha - thePixelTemp_[index].entx[0][i].cotalpha)/(thePixelTemp_[index].entx[0][i+1].cotalpha - thePixelTemp_[index].entx[0][i].cotalpha);
2902  break;
2903  }
2904  }
2905  }
2906  }
2907 
2908  ihigh=ilow + 1;
2909 
2910  sx1 = (1.f - xxratio)*thePixelTemp_[index].entx[0][ilow].sxone + xxratio*thePixelTemp_[index].entx[0][ihigh].sxone;
2911  sx2 = (1.f - xxratio)*thePixelTemp_[index].entx[0][ilow].sxtwo + xxratio*thePixelTemp_[index].entx[0][ihigh].sxtwo;
2912 
2913  xrms=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index].entx[iylow][ilow].xrms[qBin] + xxratio*thePixelTemp_[index].entx[iylow][ihigh].xrms[qBin])
2914  +yxratio*((1.f - xxratio)*thePixelTemp_[index].entx[iyhigh][ilow].xrms[qBin] + xxratio*thePixelTemp_[index].entx[iyhigh][ihigh].xrms[qBin]);
2915 
2916 
2917 
2918 
2919  // Take the errors and bias from the correct charge bin
2920 
2921  sigmay = yrms;
2922 
2923  sigmax = xrms;
2924 
2925  return;
2926 
2927 } // temperrors
2928 
2929 // ************************************************************************************************************
2939 // ************************************************************************************************************
2940 void SiPixelTemplate::qbin_dist(int id, float cotalpha, float cotbeta, float qbin_frac[4], float& ny1_frac, float& ny2_frac, float& nx1_frac, float& nx2_frac)
2941 
2942 {
2943  // Interpolate for a new set of track angles
2944 
2945  // Local variables
2946  int i;
2947  int ilow, ihigh, iylow, iyhigh, Ny, Nxx, Nyx, index;
2948  float yratio, yxratio, xxratio;
2949  float acotb, cotb;
2950  float qfrac[4];
2951  //bool flip_y;
2952 
2953  // Find the index corresponding to id
2954 
2955  index = -1;
2956  for(i=0; i<(int)thePixelTemp_.size(); ++i) {
2957 
2958  if(id == thePixelTemp_[i].head.ID) {
2959 
2960  index = i;
2961  // id_current_ = id;
2962  break;
2963  }
2964  }
2965 
2966 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
2967  if(index < 0 || index >= (int)thePixelTemp_.size()) {
2968  throw cms::Exception("DataCorrupt") << "SiPixelTemplate::temperrors can't find needed template ID = " << id << std::endl;
2969  }
2970 #else
2971  assert(index >= 0 && index < (int)thePixelTemp_.size());
2972 #endif
2973 
2974  //
2975 
2976  // Interpolate the absolute value of cot(beta)
2977 
2978  acotb = fabs((double)cotbeta);
2979  cotb = cotbeta;
2980 
2981 
2982  // for some cosmics, the ususal gymnastics are incorrect
2983 
2984  // if(thePixelTemp_[index].head.Dtype == 0) {
2985  cotb = acotb;
2986  //flip_y = false;
2987  //if(cotbeta < 0.f) {flip_y = true;}
2988  // } else {
2989  // if(locBz < 0.f) {
2990  // cotb = cotbeta;
2991  // flip_y = false;
2992  // } else {
2993  // cotb = -cotbeta;
2994  // flip_y = true;
2995  // }
2996  // }
2997 
2998  // Copy the charge scaling factor to the private variable
2999 
3000  Ny = thePixelTemp_[index].head.NTy;
3001  Nyx = thePixelTemp_[index].head.NTyx;
3002  Nxx = thePixelTemp_[index].head.NTxx;
3003 
3004 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
3005  if(Ny < 2 || Nyx < 1 || Nxx < 2) {
3006  throw cms::Exception("DataCorrupt") << "template ID = " << id_current_ << "has too few entries: Ny/Nyx/Nxx = " << Ny << "/" << Nyx << "/" << Nxx << std::endl;
3007  }
3008 #else
3009  assert(Ny > 1 && Nyx > 0 && Nxx > 1);
3010 #endif
3011 
3012  // next, loop over all y-angle entries
3013 
3014  ilow = 0;
3015  yratio = 0.f;
3016 
3017  if(cotb >= thePixelTemp_[index].enty[Ny-1].cotbeta) {
3018 
3019  ilow = Ny-2;
3020  yratio = 1.f;
3021 
3022  } else {
3023 
3024  if(cotb >= thePixelTemp_[index].enty[0].cotbeta) {
3025 
3026  for (i=0; i<Ny-1; ++i) {
3027 
3028  if( thePixelTemp_[index].enty[i].cotbeta <= cotb && cotb < thePixelTemp_[index].enty[i+1].cotbeta) {
3029 
3030  ilow = i;
3031  yratio = (cotb - thePixelTemp_[index].enty[i].cotbeta)/(thePixelTemp_[index].enty[i+1].cotbeta - thePixelTemp_[index].enty[i].cotbeta);
3032  break;
3033  }
3034  }
3035  }
3036  }
3037 
3038  ihigh=ilow + 1;
3039 
3040  // Interpolate/store all y-related quantities (flip displacements when flip_y)
3041  ny1_frac = (1.f - yratio)*thePixelTemp_[index].enty[ilow].fracyone + yratio*thePixelTemp_[index].enty[ihigh].fracyone;
3042  ny2_frac = (1.f - yratio)*thePixelTemp_[index].enty[ilow].fracytwo + yratio*thePixelTemp_[index].enty[ihigh].fracytwo;
3043 
3044  // next, loop over all x-angle entries, first, find relevant y-slices
3045 
3046  iylow = 0;
3047  yxratio = 0.f;
3048 
3049  if(acotb >= thePixelTemp_[index].entx[Nyx-1][0].cotbeta) {
3050 
3051  iylow = Nyx-2;
3052  yxratio = 1.f;
3053 
3054  } else if(acotb >= thePixelTemp_[index].entx[0][0].cotbeta) {
3055 
3056  for (i=0; i<Nyx-1; ++i) {
3057 
3058  if( thePixelTemp_[index].entx[i][0].cotbeta <= acotb && acotb < thePixelTemp_[index].entx[i+1][0].cotbeta) {
3059 
3060  iylow = i;
3061  yxratio = (acotb - thePixelTemp_[index].entx[i][0].cotbeta)/(thePixelTemp_[index].entx[i+1][0].cotbeta - thePixelTemp_[index].entx[i][0].cotbeta);
3062  break;
3063  }
3064  }
3065  }
3066 
3067  iyhigh=iylow + 1;
3068 
3069  ilow = 0;
3070  xxratio = 0.f;
3071 
3072  if(cotalpha >= thePixelTemp_[index].entx[0][Nxx-1].cotalpha) {
3073 
3074  ilow = Nxx-2;
3075  xxratio = 1.f;
3076 
3077  } else {
3078 
3079  if(cotalpha >= thePixelTemp_[index].entx[0][0].cotalpha) {
3080 
3081  for (i=0; i<Nxx-1; ++i) {
3082 
3083  if( thePixelTemp_[index].entx[0][i].cotalpha <= cotalpha && cotalpha < thePixelTemp_[index].entx[0][i+1].cotalpha) {
3084 
3085  ilow = i;
3086  xxratio = (cotalpha - thePixelTemp_[index].entx[0][i].cotalpha)/(thePixelTemp_[index].entx[0][i+1].cotalpha - thePixelTemp_[index].entx[0][i].cotalpha);
3087  break;
3088  }
3089  }
3090  }
3091  }
3092 
3093  ihigh=ilow + 1;
3094 
3095  for(i=0; i<3; ++i) {
3096  qfrac[i]=(1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index].entx[iylow][ilow].qbfrac[i] + xxratio*thePixelTemp_[index].entx[iylow][ihigh].qbfrac[i])
3097  +yxratio*((1.f - xxratio)*thePixelTemp_[index].entx[iyhigh][ilow].qbfrac[i] + xxratio*thePixelTemp_[index].entx[iyhigh][ihigh].qbfrac[i]);
3098  }
3099  nx1_frac = (1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index].entx[iylow][ilow].fracxone + xxratio*thePixelTemp_[index].entx[iylow][ihigh].fracxone)
3100  +yxratio*((1.f - xxratio)*thePixelTemp_[index].entx[iyhigh][ilow].fracxone + xxratio*thePixelTemp_[index].entx[iyhigh][ihigh].fracxone);
3101  nx2_frac = (1.f - yxratio)*((1.f - xxratio)*thePixelTemp_[index].entx[iylow][ilow].fracxtwo + xxratio*thePixelTemp_[index].entx[iylow][ihigh].fracxtwo)
3102  +yxratio*((1.f - xxratio)*thePixelTemp_[index].entx[iyhigh][ilow].fracxtwo + xxratio*thePixelTemp_[index].entx[iyhigh][ihigh].fracxtwo);
3103 
3104 
3105 
3106  qbin_frac[0] = qfrac[0];
3107  qbin_frac[1] = qbin_frac[0] + qfrac[1];
3108  qbin_frac[2] = qbin_frac[1] + qfrac[2];
3109  qbin_frac[3] = 1.f;
3110  return;
3111 
3112 } // qbin
3113 
3114 // *************************************************************************************************************************************
3116 
3122 // *************************************************************************************************************************************
3123 
3124 bool SiPixelTemplate::simpletemplate2D(float xhit, float yhit, std::vector<bool>& ydouble, std::vector<bool>& xdouble, float template2d[BXM2][BYM2])
3125 {
3126 
3127  // Local variables
3128 
3129  float x0, y0, xf, yf, xi, yi, sf, si, s0, qpix, slopey, slopex, ds;
3130  int i, j, jpix0, ipix0, jpixf, ipixf, jpix, ipix, nx, ny, anx, any, jmax, imax;
3131  float qtotal;
3132  // double path;
3133  std::list<SimplePixel> list;
3134  std::list<SimplePixel>::iterator listIter, listEnd;
3135 
3136  // Calculate the entry and exit points for the line charge from the track
3137 
3138  x0 = xhit - 0.5*zsize_*cota_current_;
3139  y0 = yhit - 0.5*zsize_*cotb_current_;
3140 
3141  jpix0 = floor(x0/xsize_)+1;
3142  ipix0 = floor(y0/ysize_)+1;
3143 
3144  if(jpix0 < 0 || jpix0 > BXM3) {return false;}
3145  if(ipix0 < 0 || ipix0 > BYM3) {return false;}
3146 
3147  xf = xhit + 0.5*zsize_*cota_current_ + lorxwidth_;
3148  yf = yhit + 0.5*zsize_*cotb_current_ + lorywidth_;
3149 
3150  jpixf = floor(xf/xsize_)+1;
3151  ipixf = floor(yf/ysize_)+1;
3152 
3153  if(jpixf < 0 || jpixf > BXM3) {return false;}
3154  if(ipixf < 0 || ipixf > BYM3) {return false;}
3155 
3156  // total charge length
3157 
3158  sf = std::sqrt((xf-x0)*(xf-x0) + (yf-y0)*(yf-y0));
3159  if((xf-x0) != 0.f) {slopey = (yf-y0)/(xf-x0);} else { slopey = 1.e10;}
3160  if((yf-y0) != 0.f) {slopex = (xf-x0)/(yf-y0);} else { slopex = 1.e10;}
3161 
3162  // use average charge in this direction
3163 
3164  qtotal = qavg_avg_;
3165 
3166  SimplePixel element;
3167  element.s = sf;
3168  element.x = xf;
3169  element.y = yf;
3170  element.i = ipixf;
3171  element.j = jpixf;
3172  element.btype = 0;
3173  list.push_back(element);
3174 
3175  // nx is the number of x interfaces crossed by the line charge
3176 
3177  nx = jpixf - jpix0;
3178  anx = abs(nx);
3179  if(anx > 0) {
3180  if(nx > 0) {
3181  for(j=jpix0; j<jpixf; ++j) {
3182  xi = xsize_*j;
3183  yi = slopey*(xi-x0) + y0;
3184  ipix = (int)(yi/ysize_)+1;
3185  si = std::sqrt((xi-x0)*(xi-x0) + (yi-y0)*(yi-y0));
3186  element.s = si;
3187  element.x = xi;
3188  element.y = yi;
3189  element.i = ipix;
3190  element.j = j;
3191  element.btype = 1;
3192  list.push_back(element);
3193  }
3194  } else {
3195  for(j=jpix0; j>jpixf; --j) {
3196  xi = xsize_*(j-1);
3197  yi = slopey*(xi-x0) + y0;
3198  ipix = (int)(yi/ysize_)+1;
3199  si = std::sqrt((xi-x0)*(xi-x0) + (yi-y0)*(yi-y0));
3200  element.s = si;
3201  element.x = xi;
3202  element.y = yi;
3203  element.i = ipix;
3204  element.j = j;
3205  element.btype = 1;
3206  list.push_back(element);
3207  }
3208  }
3209  }
3210 
3211  ny = ipixf - ipix0;
3212  any = abs(ny);
3213  if(any > 0) {
3214  if(ny > 0) {
3215  for(i=ipix0; i<ipixf; ++i) {
3216  yi = ysize_*i;
3217  xi = slopex*(yi-y0) + x0;
3218  jpix = (int)(xi/xsize_)+1;
3219  si = std::sqrt((xi-x0)*(xi-x0) + (yi-y0)*(yi-y0));
3220  element.s = si;
3221  element.x = xi;
3222  element.y = yi;
3223  element.i = i;
3224  element.j = jpix;
3225  element.btype = 2;
3226  list.push_back(element);
3227  }
3228  } else {
3229  for(i=ipix0; i>ipixf; --i) {
3230  yi = ysize_*(i-1);
3231  xi = slopex*(yi-y0) + x0;
3232  jpix = (int)(xi/xsize_)+1;
3233  si = std::sqrt((xi-x0)*(xi-x0) + (yi-y0)*(yi-y0));
3234  element.s = si;
3235  element.x = xi;
3236  element.y = yi;
3237  element.i = i;
3238  element.j = jpix;
3239  element.btype = 2;
3240  list.push_back(element);
3241  }
3242  }
3243  }
3244 
3245  imax = std::max(ipix0, ipixf);
3246  jmax = std::max(jpix0, jpixf);
3247 
3248  // Sort the list according to the distance from the initial point
3249 
3250  list.sort();
3251 
3252  // Look for double pixels and adjust the list appropriately
3253 
3254  for(i=1; i<imax; ++i) {
3255  if(ydouble[i-1]) {
3256  listIter = list.begin();
3257  if(ny > 0) {
3258  while(listIter != list.end()) {
3259  if(listIter->i == i && listIter->btype == 2) {
3260  listIter = list.erase(listIter);
3261  continue;
3262  }
3263  if(listIter->i > i) {
3264  --(listIter->i);
3265  }
3266  ++listIter;
3267  }
3268  } else {
3269  while(listIter != list.end()) {
3270  if(listIter->i == i+1 && listIter->btype == 2) {
3271  listIter = list.erase(listIter);
3272  continue;
3273  }
3274  if(listIter->i > i+1) {
3275  --(listIter->i);
3276  }
3277  ++listIter;
3278  }
3279  }
3280  }
3281  }
3282 
3283  for(j=1; j<jmax; ++j) {
3284  if(xdouble[j-1]) {
3285  listIter = list.begin();
3286  if(nx > 0) {
3287  while(listIter != list.end()) {
3288  if(listIter->j == j && listIter->btype == 1) {
3289  listIter = list.erase(listIter);
3290  continue;
3291  }
3292  if(listIter->j > j) {
3293  --(listIter->j);
3294  }
3295  ++listIter;
3296  }
3297  } else {
3298  while(listIter != list.end()) {
3299  if(listIter->j == j+1 && listIter->btype == 1) {
3300  listIter = list.erase(listIter);
3301  continue;
3302  }
3303  if(listIter->j > j+1) {
3304  --(listIter->j);
3305  }
3306  ++listIter;
3307  }
3308  }
3309  }
3310  }
3311 
3312  // The list now contains the path lengths of the line charge in each pixel from (x0,y0). Cacluate the lengths of the segments and the charge.
3313 
3314  s0 = 0.f;
3315  listIter = list.begin();
3316  listEnd = list.end();
3317  for( ;listIter != listEnd; ++listIter) {
3318  si = listIter->s;
3319  ds = si - s0;
3320  s0 = si;
3321  j = listIter->j;
3322  i = listIter->i;
3323  if(sf > 0.f) { qpix = qtotal*ds/sf;} else {qpix = qtotal;}
3324  template2d[j][i] += qpix;
3325  }
3326 
3327  return true;
3328 
3329 } // simpletemplate2D
3330 
3331 
3332 // ************************************************************************************************************
3337 // ************************************************************************************************************
3338 void SiPixelTemplate::vavilov_pars(double& mpv, double& sigma, double& kappa)
3339 
3340 {
3341  // Local variables
3342  int i;
3343  int ilow, ihigh, Ny;
3344  float yratio, cotb, cotalpha0, arg;
3345 
3346  // Interpolate in cotbeta only for the correct total path length (converts cotalpha, cotbeta into an effective cotbeta)
3347 
3348  cotalpha0 = thePixelTemp_[index_id_].enty[0].cotalpha;
3349  arg = cotb_current_*cotb_current_ + cota_current_*cota_current_ - cotalpha0*cotalpha0;
3350  if(arg < 0.f) arg = 0.f;
3351  cotb = std::sqrt(arg);
3352 
3353  // Copy the charge scaling factor to the private variable
3354 
3355  Ny = thePixelTemp_[index_id_].head.NTy;
3356 
3357 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
3358  if(Ny < 2) {
3359  throw cms::Exception("DataCorrupt") << "template ID = " << id_current_ << "has too few entries: Ny = " << Ny << std::endl;
3360  }
3361 #else
3362  assert(Ny > 1);
3363 #endif
3364 
3365  // next, loop over all y-angle entries
3366 
3367  ilow = 0;
3368  yratio = 0.f;
3369 
3370  if(cotb >= thePixelTemp_[index_id_].enty[Ny-1].cotbeta) {
3371 
3372  ilow = Ny-2;
3373  yratio = 1.f;
3374 
3375  } else {
3376 
3377  if(cotb >= thePixelTemp_[index_id_].enty[0].cotbeta) {
3378 
3379  for (i=0; i<Ny-1; ++i) {
3380 
3381  if( thePixelTemp_[index_id_].enty[i].cotbeta <= cotb && cotb < thePixelTemp_[index_id_].enty[i+1].cotbeta) {
3382 
3383  ilow = i;
3384  yratio = (cotb - thePixelTemp_[index_id_].enty[i].cotbeta)/(thePixelTemp_[index_id_].enty[i+1].cotbeta - thePixelTemp_[index_id_].enty[i].cotbeta);
3385  break;
3386  }
3387  }
3388  }
3389  }
3390 
3391  ihigh=ilow + 1;
3392 
3393  // Interpolate Vavilov parameters
3394 
3395  mpvvav_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].mpvvav + yratio*thePixelTemp_[index_id_].enty[ihigh].mpvvav;
3396  sigmavav_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].sigmavav + yratio*thePixelTemp_[index_id_].enty[ihigh].sigmavav;
3397  kappavav_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].kappavav + yratio*thePixelTemp_[index_id_].enty[ihigh].kappavav;
3398 
3399  // Copy to parameter list
3400 
3401 
3402  mpv = (double)mpvvav_;
3403  sigma = (double)sigmavav_;
3404  kappa = (double)kappavav_;
3405 
3406  return;
3407 
3408 } // vavilov_pars
3409 
3410 // ************************************************************************************************************
3415 // ************************************************************************************************************
3416 void SiPixelTemplate::vavilov2_pars(double& mpv, double& sigma, double& kappa)
3417 
3418 {
3419  // Local variables
3420  int i;
3421  int ilow, ihigh, Ny;
3422  float yratio, cotb, cotalpha0, arg;
3423 
3424  // Interpolate in cotbeta only for the correct total path length (converts cotalpha, cotbeta into an effective cotbeta)
3425 
3426  cotalpha0 = thePixelTemp_[index_id_].enty[0].cotalpha;
3427  arg = cotb_current_*cotb_current_ + cota_current_*cota_current_ - cotalpha0*cotalpha0;
3428  if(arg < 0.f) arg = 0.f;
3429  cotb = std::sqrt(arg);
3430 
3431  // Copy the charge scaling factor to the private variable
3432 
3433  Ny = thePixelTemp_[index_id_].head.NTy;
3434 
3435 #ifndef SI_PIXEL_TEMPLATE_STANDALONE
3436  if(Ny < 2) {
3437  throw cms::Exception("DataCorrupt") << "template ID = " << id_current_ << "has too few entries: Ny = " << Ny << std::endl;
3438  }
3439 #else
3440  assert(Ny > 1);
3441 #endif
3442 
3443  // next, loop over all y-angle entries
3444 
3445  ilow = 0;
3446  yratio = 0.f;
3447 
3448  if(cotb >= thePixelTemp_[index_id_].enty[Ny-1].cotbeta) {
3449 
3450  ilow = Ny-2;
3451  yratio = 1.f;
3452 
3453  } else {
3454 
3455  if(cotb >= thePixelTemp_[index_id_].enty[0].cotbeta) {
3456 
3457  for (i=0; i<Ny-1; ++i) {
3458 
3459  if( thePixelTemp_[index_id_].enty[i].cotbeta <= cotb && cotb < thePixelTemp_[index_id_].enty[i+1].cotbeta) {
3460 
3461  ilow = i;
3462  yratio = (cotb - thePixelTemp_[index_id_].enty[i].cotbeta)/(thePixelTemp_[index_id_].enty[i+1].cotbeta - thePixelTemp_[index_id_].enty[i].cotbeta);
3463  break;
3464  }
3465  }
3466  }
3467  }
3468 
3469  ihigh=ilow + 1;
3470 
3471  // Interpolate Vavilov parameters
3472 
3473  mpvvav2_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].mpvvav2 + yratio*thePixelTemp_[index_id_].enty[ihigh].mpvvav2;
3474  sigmavav2_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].sigmavav2 + yratio*thePixelTemp_[index_id_].enty[ihigh].sigmavav2;
3475  kappavav2_ = (1.f - yratio)*thePixelTemp_[index_id_].enty[ilow].kappavav2 + yratio*thePixelTemp_[index_id_].enty[ihigh].kappavav2;
3476 
3477  // Copy to parameter list
3478 
3479  mpv = (double)mpvvav2_;
3480  sigma = (double)sigmavav2_;
3481  kappa = (double)kappavav2_;
3482 
3483  return;
3484 
3485 } // vavilov2_pars
3486 
3487 
float qavg_avg
average cluster charge of clusters that are less than qavg (normalize 2-D simple templates) ...
int runnum
< Basic template entry corresponding to a single set of track angles
float xflpar[4][6]
Aqfl-parameterized x-correction in 4 charge bins.
float xrms[4]
average x-rms of reconstruction binned in 4 charge bins
void vavilov2_pars(double &mpv, double &sigma, double &kappa)
#define BXSIZE
#define LOGERROR(x)
float clslenx
cluster x-length in pixels at signal height sxmax/2
float qavg
average cluster charge for this set of track angles (now includes threshold effects) ...
float syone
rms for one pixel y-clusters
float chi2yavgone
average y chi^2 for 1 pixel clusters
bool interpolate(int id, float cotalpha, float cotbeta, float locBz, float locBx)
int cytemp()
Return central pixel of y template pixels above readout threshold.
float dyone
mean offset/correction for one pixel y-clusters
#define BYSIZE
float sigmavav
"sigma" scale fctor for Vavilov distribution
float fracxtwo
fraction of double pixel sample with xsize = 1
float yavggen[4]
generic algorithm: average y-bias of reconstruction binned in 4 charge bins
float sxmax
average pixel signal for x-projection of cluster
int btype
type of boundary (0=end, 1 = x-boundary, 2 = y-boundary)
Definition: SimplePixel.h:22
void xsigma2(int fxpix, int lxpix, float sxthr, float xsum[13+4], float xsig2[13+4])
float chi2yminc2m[4]
1st pass chi2 min search: minimum of y chi^2 in 4 charge bins (merged clusters)
float xavgc2m[4]
1st pass chi2 min search: average x-bias of reconstruction binned in 4 charge bins ...
#define TXSIZE
bool any(const std::vector< T > &v, const T &what)
Definition: ECalSD.cc:37
float chi2xavgone
average x chi^2 for 1 pixel clusters
float fracytwo
fraction of double pixel sample with ysize = 1
float yrms[4]
average y-rms of reconstruction binned in 4 charge bins
int NTxx
number of Template x-entries in each slice
#define BXM3
#define BXM1
float mpvvav2
most probable charge in Vavilov distribution for 2 merged clusters (not actually for larger kappa) ...
float ygx0gen[4]
generic algorithm: average y0 from Gaussian fit binned in 4 charge bins
float xavg[4]
average x-bias of reconstruction binned in 4 charge bins
static bool pushfile(int filenum, std::vector< SiPixelTemplateStore > &thePixelTemp_)
bool simpletemplate2D(float xhitp, float yhitp, std::vector< bool > &ydouble, std::vector< bool > &xdouble, float template2d[13+2][21+2])
Make simple 2-D templates from track angles set in interpolate and hit position.
float lorybias
estimate of y-lorentz bias
float y
y coordinate of boundary intersection
Definition: SimplePixel.h:19
float fluence
radiation fluence in n_eq/cm^2
float ss50
1/2 of the single hit dcol threshold in electrons
float dytwo
mean offset/correction for one double-pixel y-clusters
float ysize
pixel size (for future use in upgraded geometry)
float dxone
mean offset/correction for one pixel x-clusters
float pixmax
maximum charge for individual pixels in cluster
float qscale
Charge scaling to match cmssw and pixelav.
float chi2yavgc2m[4]
1st pass chi2 min search: average y chi^2 in 4 charge bins (merged clusters)
float qmin
minimum cluster charge for valid hit (keeps 99.9% of simulated hits)
float chi2xavgc2m[4]
1st pass chi2 min search: average x chi^2 in 4 charge bins (merged clusters)
float xflcorr(int binq, float qflx)
float xgsiggen[4]
generic algorithm: average sigma_x from Gaussian fit binned in 4 charge bins
float chi2xminc2m[4]
1st pass chi2 min search: minimum of x chi^2 in 4 charge bins (merged clusters)
int ID
< template header structure
float Bfield
Bfield in Tesla.
float cotalpha
cot(alpha) is proportional to cluster length in x and is basis of interpolation
float temperature
detector temperature in deg K
A arg
Definition: Factorize.h:37
float ytemp[9][21]
templates for y-reconstruction (binned over 1 central pixel)
float yrmsc2m[4]
1st pass chi2 min search: average y-rms of reconstruction binned in 4 charge bins ...
float lorywidth
estimate of y-lorentz width for optimal resolution
#define BYM1
#define BXM2
float fbin[3]
The QBin definitions in Q_clus/Q_avg.
void ytemp(int fybin, int lybin, float ytemplate[41][21+4])
int cxtemp()
Return central pixel of x-template pixels above readout threshold.
int templ_version
Version number of the template to ensure code compatibility.
float xpar[2][5]
projected x-pixel uncertainty parameterization
float ygx0[4]
average y0 from Gaussian fit binned in 4 charge bins
float xgx0gen[4]
generic algorithm: average x0 from Gaussian fit binned in 4 charge bins
float symax
average pixel signal for y-projection of cluster
float kappavav2
kappa parameter for Vavilov distribution for 2 merged clusters
float xgsig[4]
average sigma_x from Gaussian fit binned in 4 charge bins
float cotbeta
cot(beta) is proportional to cluster length in y and is basis of interpolation
float beta
beta track angle (defined in CMS CMS IN 2004/014)
void vavilov_pars(double &mpv, double &sigma, double &kappa)
#define ENDL
T sqrt(T t)
Definition: SSEVec.h:18
#define BHX
float yflcorr(int binq, float qfly)
float s
distance from track entry
Definition: SimplePixel.h:17
float xrmsc2m[4]
1st pass chi2 min search: average x-rms of reconstruction binned in 4 charge bins ...
void ytemp3d(int j, int k, std::vector< float > &ytemplate)
void temperrors(int id, float cotalpha, float cotbeta, int qBin, float &sigmay, float &sigmax, float &sy1, float &sy2, float &sx1, float &sx2)
float lorxwidth
estimate of x-lorentz width for optimal resolution
float xgx0[4]
average x0 from Gaussian fit binned in 4 charge bins
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void ysigma2(int fypix, int lypix, float sythr, float ysum[21+4], float ysig2[21+4])
char title[80]
template title
#define BYM2
int j
y index of traversed pixel
Definition: SimplePixel.h:21
double f[11][100]
float ygsiggen[4]
generic algorithm: average sigma_y from Gaussian fit binned in 4 charge bins
float fracxone
fraction of sample with xsize = 1
float mpvvav
most probable charge in Vavilov distribution (not actually for larger kappa)
#define BYM3
float sxtwo
rms for one double-pixel x-clusters
float r_qMeas_qTrue
ratio of measured to true cluster charge
int Dtype
detector type (0=BPix, 1=FPix)
float chi2yavg[4]
average y chi^2 in 4 charge bins
float alpha
alpha track angle (defined in CMS CMS IN 2004/014)
float xtemp[9][13]
templates for x-reconstruction (binned over 1 central pixel)
SiPixelTemplateHeader head
< template storage structure
float chi2xminone
minimum of x chi^2 for 1 pixel clusters
float ypar[2][5]
projected y-pixel uncertainty parameterization
int k[5][pyjets_maxn]
void xtemp3d(int j, int k, std::vector< float > &xtemplate)
float s50
1/2 of the multihit dcol threshold in electrons
#define TYSIZE
void xtemp(int fxbin, int lxbin, float xtemplate[41][13+4])
float zsize
pixel size (for future use in upgraded geometry)
void qbin_dist(int id, float cotalpha, float cotbeta, float qbin_frac[4], float &ny1_frac, float &ny2_frac, float &nx1_frac, float &nx2_frac)
float Vbias
detector bias potential in Volts
float qbfrac[3]
fraction of sample in qbin = 0-2 (>=3 is the complement)
float xsize
pixel size (for future use in upgraded geometry)
void ytemp3d_int(int nypix, int &nybins)
float fracyone
fraction of sample with ysize = 1
float qmin2
tighter minimum cluster charge for valid hit (keeps 99.8% of simulated hits)
float yavg[4]
average y-bias of reconstruction binned in 4 charge bins
void xtemp3d_int(int nxpix, int &nxbins)
#define BHY
float chi2ymin[4]
minimum of y chi^2 in 4 charge bins
float yavgc2m[4]
1st pass chi2 min search: average y-bias of reconstruction binned in 4 charge bins ...
float x
x coordinate of boundary intersection
Definition: SimplePixel.h:18
int NTy
number of Template y entries
float dxtwo
mean offset/correction for one double-pixel x-clusters
float lorxbias
estimate of x-lorentz bias
HLT enums.
#define LOGINFO(x)
int i
x index of traversed pixel
Definition: SimplePixel.h:20
int NTyx
number of Template y-slices of x entries
float yflpar[4][6]
Aqfl-parameterized y-correction in 4 charge bins.
float sxone
rms for one pixel x-clusters
float chi2xmin[4]
minimum of x chi^2 in 4 charge bins
static const G4double kappa
float chi2yminone
minimum of y chi^2 for 1 pixel clusters
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)
float costrk[3]
direction cosines of tracks used to generate this entry
static void postInit(std::vector< SiPixelTemplateStore > &thePixelTemp_)
SiPixelTemplateEntry entx[5][29]
29 Barrel x templates spanning cluster lengths from -6px (-1.125Rad) to +6px (+1.125Rad) in each of 5...
float ygsig[4]
average sigma_y from Gaussian fit binned in 4 charge bins
SiPixelTemplateEntry enty[60]
60 Barrel y templates spanning cluster lengths from 0px to +18px [28 entries for fpix] ...
float sigmavav2
"sigma" scale fctor for Vavilov distribution for 2 merged clusters
float sytwo
rms for one double-pixel y-clusters
float xrmsgen[4]
generic algorithm: average x-rms of reconstruction binned in 4 charge bins
float chi2xavg[4]
average x chi^2 in 4 charge bins
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run
float kappavav
kappa parameter for Vavilov distribution
float xavggen[4]
generic algorithm: average x-bias of reconstruction binned in 4 charge bins
float yrmsgen[4]
generic algorithm: average y-rms of reconstruction binned in 4 charge bins
float clsleny
cluster y-length in pixels at signal height symax/2