CMS 3D CMS Logo

List of all members | Public Member Functions | Public Attributes | Private Member Functions | Private Attributes
GlobalCoordsObtainer Class Reference

#include <GlobalCoordsObtainer.h>

Public Member Functions

void generate_luts ()
 
std::vector< double > get_global_coordinates (uint32_t, int, int, int)
 
 GlobalCoordsObtainer (const edm::ParameterSet &pset)
 
 ~GlobalCoordsObtainer ()
 

Public Attributes

int max_drift_tdc = -1
 
edm::FileInPath maxdrift_filename_
 
int maxdriftinfo_ [5][4][14]
 

Private Member Functions

std::map< int, lut_valuecalc_atan_lut (int, int, double, double, double, int, int, int, int, int)
 
int from_two_comp (int val, int size)
 
int to_two_comp (int val, int size)
 

Private Attributes

bool cmssw_for_global_
 
std::vector< global_constantglobal_constants
 
edm::FileInPath global_coords_filename_
 
std::map< uint32_t, lut_groupluts
 

Detailed Description

Definition at line 51 of file GlobalCoordsObtainer.h.

Constructor & Destructor Documentation

◆ GlobalCoordsObtainer()

GlobalCoordsObtainer::GlobalCoordsObtainer ( const edm::ParameterSet pset)

Definition at line 10 of file GlobalCoordsObtainer.cc.

References IntegrityClient_cfi::ChId, Exception, mps_splice::line, global_constant_per_sl::perp, perp(), muonDTDigis_cfi::pset, AlCaHLTBitMon_QueryRunRegistry::string, and global_constant_per_sl::x_phi0.

10  {
11  global_coords_filename_ = pset.getParameter<edm::FileInPath>("global_coords_filename");
12  std::ifstream ifin3(global_coords_filename_.fullPath());
13 
14  if (ifin3.fail()) {
15  throw cms::Exception("Missing Input File")
16  << "GlobalCoordsObtainer::GlobalCoordsObtainer() - Cannot find " << global_coords_filename_.fullPath();
17  }
18 
19  int wh, st, se, sl;
20  double perp, x_phi0;
22 
23  global_constant_per_sl sl1_constants;
24  global_constant_per_sl sl3_constants;
25 
26  while (ifin3.good()) {
27  ifin3 >> wh >> st >> se >> sl >> perp >> x_phi0;
28 
29  if (sl == 1) {
30  sl1_constants.perp = perp;
31  sl1_constants.x_phi0 = x_phi0;
32  } else {
33  sl3_constants.perp = perp;
34  sl3_constants.x_phi0 = x_phi0;
35 
36  DTChamberId ChId(wh, st, se);
37  global_constants.push_back({ChId.rawId(), sl1_constants, sl3_constants});
38  }
39  }
40 
41  int maxdrift;
42  maxdrift_filename_ = pset.getParameter<edm::FileInPath>("maxdrift_filename");
43  std::ifstream ifind(maxdrift_filename_.fullPath());
44  if (ifind.fail()) {
45  throw cms::Exception("Missing Input File")
46  << "MPSLFilter::MPSLFilter() - Cannot find " << maxdrift_filename_.fullPath();
47  }
48  while (ifind.good()) {
49  ifind >> wh >> st >> se >> maxdrift;
50  maxdriftinfo_[wh][st][se] = maxdrift;
51  }
52 }
edm::FileInPath global_coords_filename_
edm::FileInPath maxdrift_filename_
std::vector< global_constant > global_constants
T perp() const
Magnitude of transverse component.
const std::string & fullPath() const
Definition: FileInPath.cc:144

◆ ~GlobalCoordsObtainer()

GlobalCoordsObtainer::~GlobalCoordsObtainer ( )

Definition at line 54 of file GlobalCoordsObtainer.cc.

54 {}

Member Function Documentation

◆ calc_atan_lut()

std::map< int, lut_value > GlobalCoordsObtainer::calc_atan_lut ( int  msb_num,
int  lsb_num,
double  in_res,
double  abscissa_0,
double  out_res,
int  a_extra_bits,
int  b_extra_bits,
int  a_size,
int  b_size,
int  sgn 
)
private

Definition at line 90 of file GlobalCoordsObtainer.cc.

References a, b, cms::cuda::bs, createfilelist::int, funct::pow(), FWPFMaths::sgn(), jetUpdater_cfi::sort, mathSSE::sqrt(), RandomServiceHelper::t1, RandomServiceHelper::t2, testProducerWithPsetDescEmpty_cfi::y1, and testProducerWithPsetDescEmpty_cfi::y2.

99  {
100  // Calculates the coefficients needed to calculate the arc-tan function in fw
101  // by doing a piece-wise linear approximation.
102  // In fw, input (x) and output (y) are integers, these conversions are needed
103  // t = x*in_res - abscissa_0
104  // phi = arctan(t)
105  // y = phi/out_res
106  // => y = arctan(x*in_res - abcissa_0)/out_res
107  // The linear function is approximated as
108  // y = a*x_lsb + b
109  // Where a, b = func(x_msb) are the coefficients stored in the lut
110 
111  // a is stored as unsigned, b as signed, with their respective sizes a_size, b_size,
112  // previously shifted left by a_extra_bits and b_extra_bits, respectively
113 
114  long int a_min = -std::pow(2, (a_size - 1));
115  long int a_max = std::pow(2, (a_size - 1)) - 1;
116  long int b_min = -std::pow(2, (b_size - 1));
117  long int b_max = std::pow(2, (b_size - 1)) - 1;
118 
119  std::map<int, lut_value> lut;
120 
121  for (long int x_msb = -(long int)std::pow(2, msb_num - 1); x_msb < (long int)std::pow(2, msb_num - 1); x_msb++) {
122  int x1 = ((x_msb) << lsb_num);
123  int x2 = ((x_msb + 1) << lsb_num) - 1;
124 
125  double t1 = x1 * in_res - abscissa_0;
126  double t2 = x2 * in_res - abscissa_0;
127 
128  double phi1 = sgn * atan(t1);
129  double phi2 = sgn * atan(t2);
130 
131  double y1 = phi1 / out_res;
132  double y2 = phi2 / out_res;
133 
134  // we want to find a, b so that the error in the extremes is the same as the error in the center
135  // so the error in the extremes will be the same, so the "a" is determined by those points
136  double a = (y2 - y1) / (x2 - x1);
137 
138  // by derivating the error function and equaling to 0, you get this is the point
139  // towards the interval center with the highest error
140  // err_f = y - (a*x+b) = sgn*arctan(x*in_res - abcissa_0)/out_res - (a*x+b)
141  // d(err_f)/dx = sgn*(1/(1+(x*in_res - abcissa_0)^2))*in_res/out_res - a
142  // d(err_f)/dx = 0 => x_max_err = (sqrt(in_res/out_res/a-1) + abscissa_0)/in_res
143  // There is sign ambiguity in the sqrt operation. The sqrt has units of t (adimensional).
144  // It is resolved by setting the sqrt to have the same sign as (t1+t2)/2
145 
146  double t_max_err = sqrt(sgn * in_res / out_res / a - 1);
147  if ((t1 + t2) < 0) {
148  t_max_err *= -1;
149  }
150 
151  double x_max_err = (t_max_err + abscissa_0) / in_res;
152  double phi_max_err = sgn * atan(t_max_err);
153  double y_max_err = phi_max_err / out_res;
154 
155  // once you have the point of max error, the "b" parameter is chosen as the average between
156  // those two numbers, which makes the error at the center be equal in absolute value
157  // to the error in the extremes
158  // units: rad
159 
160  double b = (y1 + y_max_err - a * (x_max_err - x1)) / 2;
161 
162  // increase b in 1/2 of y_lsb, so that fw truncate operation on the of the result
163  // is equivalent to a round function instead of a floor function
164  b += 0.5;
165 
166  // shift left and round
167  long int a_int = (long int)(round(a * (pow(2, a_extra_bits))));
168  long int b_int = (long int)(round(b * (pow(2, b_extra_bits))));
169 
170  // tuck a, b constants into the bit size of the output (un)signed integer
171  std::vector<long int> as = {a_min, a_int, a_max};
172  std::vector<long int> bs = {b_min, b_int, b_max};
173 
174  std::sort(as.begin(), as.end());
175  std::sort(bs.begin(), bs.end());
176 
177  a_int = as.at(1);
178  b_int = bs.at(1);
179 
180  // // convert a, b to two's complement
181  // auto a_signed = a_int % (long int) (pow(2, a_size));
182  // auto b_signed = b_int % (long int) (pow(2, b_size));
183 
184  // convert x_msb to two's complement signed
185  int index = to_two_comp(x_msb, msb_num);
186  lut[index] = {a_int, b_int};
187  }
188  return lut;
189 }
float sgn(float val)
Definition: FWPFMaths.cc:7
int to_two_comp(int val, int size)
T sqrt(T t)
Definition: SSEVec.h:23
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29

◆ from_two_comp()

int GlobalCoordsObtainer::from_two_comp ( int  val,
int  size 
)
inlineprivate

Definition at line 72 of file GlobalCoordsObtainer.h.

References findQualityFiles::size, and heppy_batch::val.

72 { return val - ((2 * val) & (1 << size)); }
size
Write out results.

◆ generate_luts()

void GlobalCoordsObtainer::generate_luts ( )

Definition at line 56 of file GlobalCoordsObtainer.cc.

References IntegrityClient_cfi::ChId, global_constant::chid, global_constant_per_sl::perp, funct::pow(), FWPFMaths::sgn(), global_constant::sl1, global_constant::sl3, and global_constant_per_sl::x_phi0.

56  {
57  for (auto& global_constant : global_constants) {
58  int sgn = 1;
60  // typical hasPosRF function
61  if (ChId.wheel() > 0 || (ChId.wheel() == 0 && ChId.sector() % 4 > 1)) {
62  sgn = -1;
63  }
64 
65  max_drift_tdc = maxdriftinfo_[ChId.wheel() + 2][ChId.station() - 1][ChId.sector() - 1];
66  int SEMICELL_IN_TDC_COUNTS = max_drift_tdc; //495 en un mundo peor y mas oscuro
67  int SL1_SEMICELL_OFFSET = 96;
68 
69  //Read atan function from LUTs
70  auto phi =
71  calc_atan_lut(11,
72  6,
73  21. / SEMICELL_IN_TDC_COUNTS / ((global_constant.sl1.perp + global_constant.sl3.perp) / .2),
74  (global_constant.sl1.x_phi0 - 2.1 * SL1_SEMICELL_OFFSET) /
76  1. / std::pow(2, 17),
77  9,
78  4,
79  11,
80  21,
81  sgn);
82 
83  auto phib =
84  calc_atan_lut(9, 5, 21. / SEMICELL_IN_TDC_COUNTS / (6.5 * 16), 0., 4. / std::pow(2, 13), 9, 3, 10, 16, sgn);
85 
86  luts[global_constant.chid] = {phi, phib};
87  }
88 }
float sgn(float val)
Definition: FWPFMaths.cc:7
global_constant_per_sl sl1
std::vector< global_constant > global_constants
std::map< uint32_t, lut_group > luts
global_constant_per_sl sl3
std::map< int, lut_value > calc_atan_lut(int, int, double, double, double, int, int, int, int, int)
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29

◆ get_global_coordinates()

std::vector< double > GlobalCoordsObtainer::get_global_coordinates ( uint32_t  chid,
int  sl,
int  x,
int  tanpsi 
)

Definition at line 191 of file GlobalCoordsObtainer.cc.

References createfilelist::int, cmsdt::PHI_B_SHL_BITS, cmsdt::PHI_LUT_ADDR_WIDTH, cmsdt::PHI_MULT_SHR_BITS, cmsdt::PHI_PHIB_RES_DIFF_BITS, cmsdt::PHI_SIZE, cmsdt::PHIB_B_SHL_BITS, cmsdt::PHIB_LUT_ADDR_WIDTH, cmsdt::PHIB_MULT_SHR_BITS, cmsdt::PHIB_SIZE, funct::pow(), cmsdt::TANPSI_SIZE, trackerHitRTTI::vector, x, and cmsdt::X_SIZE.

191  {
192  // Depending on the type of primitive (SL1, SL3 or correlated), choose the
193  // appropriate input data (x, tanpsi) from the input primitive data structure
194  // and the corresponding phi-lut from the 3 available options
195 
196  auto phi_lut = &luts[chid].phi; //One parameter to rule them all
197  auto phib_lut = &luts[chid].phib;
198 
199  // x and slope are given in two's complement in fw
200  x = to_two_comp(x, X_SIZE);
201  tanpsi = to_two_comp(tanpsi, TANPSI_SIZE);
202 
203  // Slice x and tanpsi
204  // Both x and tanpsi are represented in vhdl as signed, this means their values
205  // are stored as two's complement.
206 
207  // The MSB part is going to be used to index the luts and obtain a and b parameters
208  // Converting the upper part of the signed to an integer (with sign).
209 
210  int x_msb = x >> (X_SIZE - PHI_LUT_ADDR_WIDTH);
211  x_msb = from_two_comp(x_msb, PHI_LUT_ADDR_WIDTH);
212 
213  int tanpsi_msb = tanpsi >> (TANPSI_SIZE - PHIB_LUT_ADDR_WIDTH);
214  tanpsi_msb = from_two_comp(tanpsi_msb, PHIB_LUT_ADDR_WIDTH);
215 
216  // The LSB part can be sliced right away because it must yield a positive integer
217  int x_lsb = x & (int)(std::pow(2, (X_SIZE - PHI_LUT_ADDR_WIDTH)) - 1);
218  int tanpsi_lsb = tanpsi & (int)(std::pow(2, (TANPSI_SIZE - PHIB_LUT_ADDR_WIDTH)) - 1);
219 
220  // Index the luts wiht the MSB parts already calculated
221  auto phi_lut_q = phi_lut->at(to_two_comp(x_msb, PHI_LUT_ADDR_WIDTH));
222  auto phib_lut_q = phib_lut->at(to_two_comp(tanpsi_msb, PHIB_LUT_ADDR_WIDTH));
223 
224  // Separate this data into the coefficients a and b
225  auto phi_lut_a = phi_lut_q.a;
226  auto phi_lut_b = phi_lut_q.b;
227  auto phib_lut_a = phib_lut_q.a;
228  auto phib_lut_b = phib_lut_q.b;
229 
230  // Do the linear piece-wise operations
231  // At this point all variables that can be negative have already been converted
232  // so will yield negative values when necessary
233  int phi_uncut = (phi_lut_b << PHI_B_SHL_BITS) + x_lsb * phi_lut_a;
234  int psi_uncut = (phib_lut_b << PHIB_B_SHL_BITS) + tanpsi_lsb * phib_lut_a;
235 
236  // Trim phi to its final size
237  int phi = (phi_uncut >> PHI_MULT_SHR_BITS);
238 
239  // Calculate phi_bending from the uncut version of phi and psi, and the trim it to size
240  int phib_uncut = psi_uncut - (phi_uncut >> (PHI_PHIB_RES_DIFF_BITS + PHI_MULT_SHR_BITS - PHIB_MULT_SHR_BITS));
241  int phib = (phib_uncut >> PHIB_MULT_SHR_BITS);
242 
243  double phi_f = (double)phi * PHI_SIZE;
244  double phib_f = (double)phib * PHIB_SIZE;
245 
246  return std::vector({phi_f, phib_f});
247 }
constexpr int PHI_LUT_ADDR_WIDTH
Definition: constants.h:432
constexpr int PHI_PHIB_RES_DIFF_BITS
Definition: constants.h:444
constexpr int PHIB_B_SHL_BITS
Definition: constants.h:439
int to_two_comp(int val, int size)
constexpr int PHI_B_SHL_BITS
Definition: constants.h:433
std::map< uint32_t, lut_group > luts
constexpr double PHIB_SIZE
Definition: constants.h:430
constexpr int PHIB_LUT_ADDR_WIDTH
Definition: constants.h:438
constexpr int PHI_MULT_SHR_BITS
Definition: constants.h:434
constexpr double PHI_SIZE
Definition: constants.h:429
constexpr int TANPSI_SIZE
Definition: constants.h:428
int from_two_comp(int val, int size)
constexpr int PHIB_MULT_SHR_BITS
Definition: constants.h:440
constexpr int X_SIZE
Definition: constants.h:427
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29

◆ to_two_comp()

int GlobalCoordsObtainer::to_two_comp ( int  val,
int  size 
)
inlineprivate

Definition at line 66 of file GlobalCoordsObtainer.h.

References funct::pow(), findQualityFiles::size, and heppy_batch::val.

66  {
67  if (val >= 0)
68  return val;
69  return std::pow(2, size) + val;
70  }
size
Write out results.
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29

Member Data Documentation

◆ cmssw_for_global_

bool GlobalCoordsObtainer::cmssw_for_global_
private

Definition at line 75 of file GlobalCoordsObtainer.h.

◆ global_constants

std::vector<global_constant> GlobalCoordsObtainer::global_constants
private

Definition at line 77 of file GlobalCoordsObtainer.h.

◆ global_coords_filename_

edm::FileInPath GlobalCoordsObtainer::global_coords_filename_
private

Definition at line 76 of file GlobalCoordsObtainer.h.

◆ luts

std::map<uint32_t, lut_group> GlobalCoordsObtainer::luts
private

Definition at line 78 of file GlobalCoordsObtainer.h.

◆ max_drift_tdc

int GlobalCoordsObtainer::max_drift_tdc = -1

Definition at line 61 of file GlobalCoordsObtainer.h.

◆ maxdrift_filename_

edm::FileInPath GlobalCoordsObtainer::maxdrift_filename_

Definition at line 59 of file GlobalCoordsObtainer.h.

◆ maxdriftinfo_

int GlobalCoordsObtainer::maxdriftinfo_[5][4][14]

Definition at line 60 of file GlobalCoordsObtainer.h.