CMS 3D CMS Logo

SectorProcessorLUT.cc
Go to the documentation of this file.
2 
3 #include <cassert>
4 #include <iostream>
5 #include <fstream>
6 
10 
11 
13  version_(0xFFFFFFFF)
14 {
15 
16 }
17 
19 
20 }
21 
22 void SectorProcessorLUT::read(bool pc_lut_data, int pc_lut_version) {
23  if (version_ == pc_lut_version) return;
24 
25  edm::LogInfo("L1T") << "EMTF using pc_lut_ver: " << pc_lut_version
26  << ", configured for " << (pc_lut_data ? "data" : "MC");
27 
28  std::string coord_lut_dir = "";
29  if (pc_lut_version == 0)
30  coord_lut_dir = "ph_lut_v1"; // All year 2016
31  else if (pc_lut_version == 1)
32  coord_lut_dir = "ph_lut_v2"; // Beginning of 2017, improved alignment from ideal CMS geometry (MC)
33  else if (pc_lut_version == 2 && pc_lut_data)
34  coord_lut_dir = "ph_lut_v3_data"; // Update in September 2017 from ReReco alignment, data only
35  else if (pc_lut_version == 2)
36  coord_lut_dir = "ph_lut_v2"; // MC still uses ideal CMS aligment
37  else if (pc_lut_version == -1 && pc_lut_data)
38  coord_lut_dir = "ph_lut_v3_data"; // September 2017 data LCT alignment, but use local CPPF LUTs for RPC
39  else if (pc_lut_version == -1)
40  coord_lut_dir = "ph_lut_v2"; // MC using ideal CMS LCT alignment, but use local CPPF LUTs for RPC
41  else
42  throw cms::Exception("SectorProcessorLUT")
43  << "Trying to use EMTF pc_lut_version = " << pc_lut_version << ", does not exist!";
44  // Will catch user trying to run with Global Tag settings on 2016 data, rather than fakeEmtfParams. - AWB 08.06.17
45 
46  std::string coord_lut_path = "L1Trigger/L1TMuon/data/emtf_luts/" + coord_lut_dir + "/";
47 
48  read_file(coord_lut_path+"ph_init_neighbor.txt", ph_init_neighbor_);
49  read_file(coord_lut_path+"ph_disp_neighbor.txt", ph_disp_neighbor_);
50  read_file(coord_lut_path+"th_init_neighbor.txt", th_init_neighbor_);
51  read_file(coord_lut_path+"th_disp_neighbor.txt", th_disp_neighbor_);
52  read_file(coord_lut_path+"th_lut_neighbor.txt", th_lut_neighbor_);
53  read_file(coord_lut_path+"th_corr_lut_neighbor.txt", th_corr_lut_neighbor_);
54 
55  std::string cppf_coord_lut_path = "L1Trigger/L1TMuon/data/cppf/"; // Coordinate LUTs actually used by CPPF
56  bool use_local_cppf_files = (pc_lut_version == -1);
57  if (use_local_cppf_files) { // More accurate coordinate transformation LUTs from Jia Fu
58  cppf_coord_lut_path = "L1Trigger/L1TMuon/data/cppf_luts/angleScale_v1/";
59  }
60 
61  read_cppf_file(cppf_coord_lut_path, cppf_ph_lut_, cppf_th_lut_, use_local_cppf_files); // cppf filenames are hardcoded in the function
62 
63  if (ph_init_neighbor_.size() != 2*6*61) { // [endcap_2][sector_6][chamber_61]
64  throw cms::Exception("SectorProcessorLUT")
65  << "Expected ph_init_neighbor_ to get " << 2*6*61 << " values, "
66  << "got " << ph_init_neighbor_.size() << " values.";
67  }
68 
69  if (ph_disp_neighbor_.size() != 2*6*61) { // [endcap_2][sector_6][chamber_61]
70  throw cms::Exception("SectorProcessorLUT")
71  << "Expected ph_disp_neighbor_ to get " << 2*6*61 << " values, "
72  << "got " << ph_disp_neighbor_.size() << " values.";
73  }
74 
75  if (th_init_neighbor_.size() != 2*6*61) { // [endcap_2][sector_6][chamber_61]
76  throw cms::Exception("SectorProcessorLUT")
77  << "Expected th_init_neighbor_ to get " << 2*6*61 << " values, "
78  << "got " << th_init_neighbor_.size() << " values.";
79  }
80 
81  if (th_disp_neighbor_.size() != 2*6*61) { // [endcap_2][sector_6][chamber_61]
82  throw cms::Exception("SectorProcessorLUT")
83  << "Expected th_disp_neighbor_ to get " << 2*6*61 << " values, "
84  << "got " << th_disp_neighbor_.size() << " values.";
85  }
86 
87  if (th_lut_neighbor_.size() != 2*6*61*128) { // [endcap_2][sector_6][chamber_61][wire_128]
88  throw cms::Exception("SectorProcessorLUT")
89  << "Expected th_lut_neighbor_ to get " << 2*6*61*128 << " values, "
90  << "got " << th_lut_neighbor_.size() << " values.";
91  }
92 
93  if (th_corr_lut_neighbor_.size() != 2*6*7*128) { // [endcap_2][sector_6][chamber_61][strip_wire_128]
94  throw cms::Exception("SectorProcessorLUT")
95  << "Expected th_corr_lut_neighbor_ to get " << 2*6*7*128 << " values, "
96  << "got " << th_corr_lut_neighbor_.size() << " values.";
97  }
98 
99  if (cppf_ph_lut_.size() != 2*6*6*6*3*64) { // [endcap_2][rpc_sector_6][rpc_station_ring_6][rpc_subsector_6][rpc_roll_3][rpc_halfstrip_64]
100  throw cms::Exception("SectorProcessorLUT")
101  << "Expected cppf_ph_lut_ to get " << 2*6*6*6*3*64 << " values, "
102  << "got " << cppf_ph_lut_.size() << " values.";
103  }
104 
105  if (cppf_th_lut_.size() != 2*6*6*6*3) { // [endcap_2][rpc_sector_6][rpc_station_ring_6][rpc_subsector_6][rpc_roll_3]
106  throw cms::Exception("SectorProcessorLUT")
107  << "Expected cppf_th_lut_ to get " << 2*6*6*6*3 << " values, "
108  << "got " << cppf_th_lut_.size() << " values.";
109  }
110 
111  // clct pattern convertion array from CMSSW
112  //{0.0, 0.0, -0.60, 0.60, -0.64, 0.64, -0.23, 0.23, -0.21, 0.21, 0.0}
113  // 0 0 -5 +5 -5 +5 -2 +2 -2 +2 0
114  ph_patt_corr_ = {
115  0, 0, 5, 5, 5, 5, 2, 2, 2, 2, 0
116  };
117  if (ph_patt_corr_.size() != 11) {
118  throw cms::Exception("SectorProcessorLUT")
119  << "Expected ph_patt_corr_ to get " << 11 << " values, "
120  << "got " << ph_patt_corr_.size() << " values.";
121  }
122 
124  0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0
125  };
126  if (ph_patt_corr_sign_.size() != 11) {
127  throw cms::Exception("SectorProcessorLUT")
128  << "Expected ph_patt_corr_sign_ to get " << 11 << " values, "
129  << "got " << ph_patt_corr_sign_.size() << " values.";
130  }
131 
132  ph_zone_offset_ = {
133  39,57,76,39,58,76,41,60,79,
134  95,114,132,95,114,133,98,116,135,
135  38,76,113,39,58,76,95,114,132,
136  38,76,113,39,58,76,95,114,132,
137  38,76,113,38,57,76,95,113,132,
138  21,21,23,1,21,1,21,1,20
139  };
140  if (ph_zone_offset_.size() != 6*9) {
141  throw cms::Exception("SectorProcessorLUT")
142  << "Expected ph_zone_offset_ to get " << 6*9 << " values, "
143  << "got " << ph_zone_offset_.size() << " values.";
144  }
145 
146  // start phi of each chamber in reduced precision, for zone hits,
147  // with negative offset to allow for possible chamber movement
148  ph_init_hard_ = {
149  39, 57, 76, 39, 58, 76, 41, 60, 79, 39, 57, 76, 21, 21, 23, 21,
150  95, 114, 132, 95, 114, 133, 98, 116, 135, 95, 114, 132, 0, 0, 0, 0,
151  38, 76, 113, 39, 58, 76, 95, 114, 132, 1, 21, 0, 0, 0, 0, 0,
152  38, 76, 113, 39, 58, 76, 95, 114, 132, 1, 21, 0, 0, 0, 0, 0,
153  38, 76, 113, 38, 57, 76, 95, 113, 132, 1, 20, 0, 0, 0, 0, 0
154  };
155  if (ph_init_hard_.size() != 5*16) {
156  throw cms::Exception("SectorProcessorLUT")
157  << "Expected ph_init_hard_ to get " << 5*16 << " values, "
158  << "got " << ph_init_hard_.size() << " values.";
159  }
160 
161  version_ = pc_lut_version;
162  return;
163 }
164 
165 uint32_t SectorProcessorLUT::get_ph_init(int fw_endcap, int fw_sector, int pc_lut_id) const {
166  size_t index = (fw_endcap * 6 + fw_sector) * 61 + pc_lut_id;
167  return ph_init_neighbor_.at(index);
168 }
169 
170 uint32_t SectorProcessorLUT::get_ph_disp(int fw_endcap, int fw_sector, int pc_lut_id) const {
171  size_t index = (fw_endcap * 6 + fw_sector) * 61 + pc_lut_id;
172  return ph_disp_neighbor_.at(index);
173 }
174 
175 uint32_t SectorProcessorLUT::get_th_init(int fw_endcap, int fw_sector, int pc_lut_id) const {
176  size_t index = (fw_endcap * 6 + fw_sector) * 61 + pc_lut_id;
177  return th_init_neighbor_.at(index);
178 }
179 
180 uint32_t SectorProcessorLUT::get_th_disp(int fw_endcap, int fw_sector, int pc_lut_id) const {
181  size_t index = (fw_endcap * 6 + fw_sector) * 61 + pc_lut_id;
182  return th_disp_neighbor_.at(index);
183 }
184 
185 uint32_t SectorProcessorLUT::get_th_lut(int fw_endcap, int fw_sector, int pc_lut_id, int pc_wire_id) const {
186  int pc_lut_id2 = pc_lut_id;
187 
188  // Make ME1/1a the same as ME1/1b
189  if ((9 <= pc_lut_id2 && pc_lut_id2 < 12) || (25 <= pc_lut_id2 && pc_lut_id2 < 28))
190  pc_lut_id2 -= 9;
191  // Make ME1/1a neighbor the same as ME1/1b
192  if (pc_lut_id2 == 15)
193  pc_lut_id2 -= 3;
194 
195  size_t index = ((fw_endcap * 6 + fw_sector) * 61 + pc_lut_id2) * 128 + pc_wire_id;
196  return th_lut_neighbor_.at(index);
197 }
198 
199 uint32_t SectorProcessorLUT::get_th_corr_lut(int fw_endcap, int fw_sector, int pc_lut_id, int pc_wire_strip_id) const {
200  int pc_lut_id2 = pc_lut_id;
201 
202  // Make ME1/1a the same as ME1/1b
203  if ((9 <= pc_lut_id2 && pc_lut_id2 < 12) || (25 <= pc_lut_id2 && pc_lut_id2 < 28))
204  pc_lut_id2 -= 9;
205  // Make ME1/1a neighbor the same as ME1/1b
206  if (pc_lut_id2 == 15)
207  pc_lut_id2 -= 3;
208 
209  if (pc_lut_id2 <= 3) {
210  pc_lut_id2 -= 0;
211  } else if (pc_lut_id2 == 12) {
212  pc_lut_id2 -= 9;
213  } else if (16 <= pc_lut_id2 && pc_lut_id2 < 19) {
214  pc_lut_id2 -= 12;
215  } else {
216  throw cms::Exception("SectorProcessorLUT")
217  << "get_th_corr_lut(): out of range pc_lut_id: " << pc_lut_id;
218  }
219 
220  size_t index = ((fw_endcap * 6 + fw_sector) * 7 + pc_lut_id2) * 128 + pc_wire_strip_id;
221  return th_corr_lut_neighbor_.at(index);
222 }
223 
225  return ph_patt_corr_.at(pattern);
226 }
227 
229  return ph_patt_corr_sign_.at(pattern);
230 }
231 
232 uint32_t SectorProcessorLUT::get_ph_zone_offset(int pc_station, int pc_chamber) const {
233  size_t index = pc_station * 9 + pc_chamber;
234  return ph_zone_offset_.at(index);
235 }
236 
237 uint32_t SectorProcessorLUT::get_ph_init_hard(int fw_station, int fw_cscid) const {
238  size_t index = fw_station * 16 + fw_cscid;
239  return ph_init_hard_.at(index);
240 }
241 
242 uint32_t SectorProcessorLUT::get_cppf_lut_id(int rpc_region, int rpc_sector, int rpc_station, int rpc_ring, int rpc_subsector, int rpc_roll) const {
243  uint32_t iendcap = (rpc_region == -1) ? 1 : 0;
244  uint32_t isector = (rpc_sector - 1);
245  uint32_t istationring = (rpc_station >= 3) ? ((rpc_station - 3) * 2 + (rpc_ring - 2) + 2) : (rpc_station - 1);
246  uint32_t isubsector = (rpc_subsector - 1);
247  uint32_t iroll = (rpc_roll - 1);
248  return ((((iendcap * 6 + isector) * 6 + istationring) * 6 + isubsector) * 3 + iroll);
249 }
250 
251 uint32_t SectorProcessorLUT::get_cppf_ph_lut(int rpc_region, int rpc_sector, int rpc_station, int rpc_ring, int rpc_subsector, int rpc_roll, int halfstrip, bool is_neighbor) const {
252  size_t th_index = get_cppf_lut_id(rpc_region, rpc_sector, rpc_station, rpc_ring, rpc_subsector, rpc_roll);
253  size_t ph_index = (th_index * 64) + (halfstrip - 1);
254  uint32_t ph = cppf_ph_lut_.at(ph_index);
255  if (!is_neighbor && rpc_subsector == 2)
256  ph += 900;
257  return ph;
258 }
259 
260 uint32_t SectorProcessorLUT::get_cppf_th_lut(int rpc_region, int rpc_sector, int rpc_station, int rpc_ring, int rpc_subsector, int rpc_roll) const {
261  size_t th_index = get_cppf_lut_id(rpc_region, rpc_sector, rpc_station, rpc_ring, rpc_subsector, rpc_roll);
262  uint32_t th = cppf_th_lut_.at(th_index);
263  return th;
264 }
265 
266 void SectorProcessorLUT::read_file(const std::string& filename, std::vector<uint32_t>& vec) {
267  vec.clear();
268 
269  std::ifstream infile;
270  infile.open(edm::FileInPath(filename).fullPath().c_str());
271 
272  int buf;
273  while (infile >> buf) {
274  buf = (buf == -999) ? 0 : buf;
275  vec.push_back(buf);
276  }
277  infile.close();
278 }
279 
280 void SectorProcessorLUT::read_cppf_file(const std::string& filename, std::vector<uint32_t>& vec1, std::vector<uint32_t>& vec2, bool local) {
281  auto get_rpc_region = [](uint32_t id) { return (static_cast<int>((id >> 0) & 0X3) + (-1)); };
282  auto get_rpc_sector = [](uint32_t id) { return (static_cast<int>((id >> 7) & 0XF) + (1)); };
283  auto get_rpc_ring = [](uint32_t id) { return (static_cast<int>((id >> 2) & 0X7) + (1)); };
284  auto get_rpc_station = [](uint32_t id) { return (static_cast<int>((id >> 5) & 0X3) + (1)); };
285  auto get_rpc_subsector = [](uint32_t id) { return (static_cast<int>((id >> 12) & 0X7) + (1)); };
286  auto get_rpc_roll = [](uint32_t id) { return (static_cast<int>((id >> 15) & 0X7) + (0)); };
287 
288  std::vector<std::string> cppf_filenames = {
289  "angleScale_RPC_CPPFp1.txt",
290  "angleScale_RPC_CPPFp2.txt",
291  "angleScale_RPC_CPPFp3.txt",
292  "angleScale_RPC_CPPFp4.txt",
293  "angleScale_RPC_CPPFn1.txt",
294  "angleScale_RPC_CPPFn2.txt",
295  "angleScale_RPC_CPPFn3.txt",
296  "angleScale_RPC_CPPFn4.txt",
297  };
298 
299 
300  vec1.clear();
301  vec2.clear();
302  vec1.resize(2*6*6*6*3*64, 0);
303  vec2.resize(2*6*6*6*3, 0);
304 
305  for (size_t i = 0; i < cppf_filenames.size(); ++i) {
306  std::ifstream infile;
307  infile.open(edm::FileInPath(filename + cppf_filenames.at(i)).fullPath().c_str());
308 
309  // std::cout << "\n\nOpening CPPF LUT file " << cppf_filenames.at(i) << std::endl;
310 
311  int buf1, buf2, buf3, buf4, buf5, buf6;
312  // Special variables for transforming centrally-provided CPPF LUTs
313  int buf1_prev = 0, buf2_prev = 0, halfstrip_prev = 0; // Values from previous line in file
314  int line_num = 0; // Line number in file
315  int count_dir = -1; // Direction of half-strip counting: +1 is up, -1 is down
316  int dStrip = 0; // Offset for half-strip from full strip
317  while ((infile >> buf1) && (infile >> buf2) && (infile >> buf3) && (infile >> buf4) && (infile >> buf5) && (infile >> buf6)) {
318 
319  if ((line_num % 192) == 191) line_num += 1; // Gap in central files vs. Jia Fu's files
320  line_num += 1;
321  // On roughly every-other line, files in L1Trigger/L1TMuon/data/cppf have 0 in the first three columns
322  // Skips a "0 0 0" line once every 192 lines
323  if ((line_num % 2) == 1) {
324  buf1_prev = buf1;
325  buf2_prev = buf2;
326  }
327 
328  if (local && (buf1 == 0 || buf2 == 0)) {
329  throw cms::Exception("SectorProcessorLUT") << "Expected non-0 values, got buf1 = " << buf1 << ", buf2 = " << buf2;
330  }
331  if (!local && (buf1_prev == 0 || buf2_prev == 0)) {
332  throw cms::Exception("SectorProcessorLUT") << "Expected non-0 values, got buf1_prev = " << buf1_prev << ", buf2_prev = " << buf2_prev;
333  }
334 
335  uint32_t id = (local ? buf1 : buf1_prev);
336  int32_t rpc_region = get_rpc_region(id);
337  int32_t rpc_sector = get_rpc_sector(id);
338  int32_t rpc_station = get_rpc_station(id);
339  int32_t rpc_ring = get_rpc_ring(id);
340  int32_t rpc_subsector = get_rpc_subsector(id);
341  int32_t rpc_roll = get_rpc_roll(id);
342 
343  // Offset into halfstrips from centrally-provided LUTs
344  if ( buf2_prev*2 > halfstrip_prev + 8 ||
345  buf2_prev*2 < halfstrip_prev - 8 ) { // Starting a new series of strips
346  if (buf2_prev == 1) count_dir = +1; // Starting from a low number, counting up
347  else count_dir = -1; // Starting from a high number, counting down
348  }
349  if (count_dir == -1) dStrip = (buf2_prev*2 == halfstrip_prev ? 1 : 0);
350  if (count_dir == +1) dStrip = (buf2_prev*2 == halfstrip_prev + 2 ? 1 : 0);
351  if (buf2_prev*2 < halfstrip_prev - 8 && buf2_prev == 1) dStrip = 1;
352 
353  //uint32_t strip = buf2;
354  uint32_t halfstrip = (local ? buf2 : buf2_prev*2 - dStrip); // I modified the local text files to use 'halfstrip' instead of 'strip' in column 2
355  halfstrip_prev = halfstrip;
356 
357  uint32_t ph = buf5;
358  uint32_t th = buf6;
359 
360  size_t th_index = get_cppf_lut_id(rpc_region, rpc_sector, rpc_station, rpc_ring, rpc_subsector, rpc_roll);
361  size_t ph_index = (th_index * 64) + (halfstrip - 1);
362 
363  // std::cout << id << " " << rpc_region << " " << rpc_sector << " " << rpc_station << " " << rpc_ring << " "
364  // << rpc_subsector << " " << rpc_roll << " " << halfstrip << " " << th_index << " " << ph_index << std::endl;
365 
366  vec1.at(ph_index) = ph;
367  if (halfstrip == 1)
368  vec2.at(th_index) = th;
369 
370  // Fill gap in centrally-provided LUTs once every 192 lines
371  if (!local && (line_num % 192) == 191)
372  vec1.at(ph_index+1) = ph;
373 
374  } // End while ((infile >> buf1) && ... && (infile >> buf6))
375  infile.close();
376  } // End loop over CPPF LUT files
377 }
std::vector< uint32_t > ph_zone_offset_
std::vector< uint32_t > cppf_ph_lut_
void read(bool pc_lut_data, int pc_lut_version)
std::vector< uint32_t > th_corr_lut_neighbor_
uint32_t get_ph_patt_corr_sign(int pattern) const
std::vector< uint32_t > cppf_th_lut_
std::vector< uint32_t > th_disp_neighbor_
uint32_t get_th_init(int fw_endcap, int fw_sector, int pc_lut_id) const
std::vector< uint32_t > ph_patt_corr_
std::vector< double > vec1
Definition: HCALResponse.h:15
uint32_t get_cppf_th_lut(int rpc_region, int rpc_sector, int rpc_station, int rpc_ring, int rpc_subsector, int rpc_roll) const
std::vector< uint32_t > ph_init_hard_
uint32_t get_th_disp(int fw_endcap, int fw_sector, int pc_lut_id) const
uint32_t get_ph_disp(int fw_endcap, int fw_sector, int pc_lut_id) const
std::vector< uint32_t > ph_patt_corr_sign_
void read_cppf_file(const std::string &filename, std::vector< uint32_t > &vec1, std::vector< uint32_t > &vec2, bool local)
std::vector< uint32_t > th_init_neighbor_
uint32_t get_ph_zone_offset(int pc_station, int pc_chamber) const
std::vector< uint32_t > ph_disp_neighbor_
uint32_t get_cppf_lut_id(int rpc_region, int rpc_sector, int rpc_station, int rpc_ring, int rpc_subsector, int rpc_roll) const
uint32_t get_ph_patt_corr(int pattern) const
uint32_t get_th_lut(int fw_endcap, int fw_sector, int pc_lut_id, int pc_wire_id) const
std::vector< uint32_t > ph_init_neighbor_
uint32_t get_ph_init_hard(int fw_station, int fw_cscid) const
void read_file(const std::string &filename, std::vector< uint32_t > &vec)
std::vector< vec1 > vec2
Definition: HCALResponse.h:16
uint32_t get_ph_init(int fw_endcap, int fw_sector, int pc_lut_id) const
uint32_t get_th_corr_lut(int fw_endcap, int fw_sector, int pc_lut_id, int pc_wire_strip_id) const
uint32_t get_cppf_ph_lut(int rpc_region, int rpc_sector, int rpc_station, int rpc_ring, int rpc_subsector, int rpc_roll, int halfstrip, bool is_neighbor) const
std::vector< uint32_t > th_lut_neighbor_