11#include "trg/klm/modules/klmtrigger/klm_trig_linear_fit.h"
12#include "trg/klm/modules/klmtrigger/IO_csv.h"
13#include "trg/klm/modules/klmtrigger/bit_operations.h"
15#include "trg/klm/modules/klmtrigger/ntuples_full.h"
22using namespace Belle2::KLM_TRG_definitions;
31 void bitshift(int64_t& out, int64_t& shift, int64_t in, int64_t deltashift)
33 int64_t mask = 0xFFFFFF;
34 if (((mask << deltashift) & in) > 0) {
35 throw std::runtime_error(
"bitshift error");
43 constexpr int64_t get_index(
const T& e,
int track_id = 0)
47 bitshift(ret, shift, track_id, 5);
48 bitshift(ret, shift, e.layer, 6);
49 bitshift(ret, shift, e.plane, 2);
50 bitshift(ret, shift, e.sector, 6);
51 bitshift(ret, shift, e.section, 3);
52 bitshift(ret, shift, e.subdetector, 3);
60 int m_number_of_tracks = 4;
62 double last_x = 0, last_y = 0;
66 std::map< int, internal > m_storage;
70 int operator()(
const T& e)
72 for (
int j = 0; j < m_number_of_tracks; ++j) {
74 auto& track = m_storage[get_index(e, j)];
76 std::abs(track.last_y - e.y_pos) < y_cutoff
85 const auto last_track = m_number_of_tracks - 1;
86 update_track(last_track, e);
92 void update_track(
int Track_ID,
const T& e)
94 auto& track = m_storage[get_index(e, Track_ID)];
95 track.last_y = e.y_pos;
96 track.last_x = e.x_pos;
103 template <
typename Container_T>
104 auto operator()(
const Container_T& container)
const
109 int64_t sumX = 0, sumY = 0, sumXX = 0, sumXY = 0, sumYY = 0;
110 for (
const auto& e : container) {
112 sumXX += e.x_pos * e.x_pos;
115 sumYY += e.y_pos * e.y_pos;
117 sumXY += e.x_pos * e.y_pos;
119 int64_t nHits = container.size();
120 int denom = sumXX * nHits - sumX * sumX;
122 return nt::ntuple(slopeXY(1e9), interceptXY(1e9), ipXY(1e9), chisqXY(1e9), Nhits(nHits));
125 auto slopeXY_ = slopeXY((
double)(sumXY * nHits - sumX * sumY) / (
double)denom);
126 auto interceptXY_ = interceptXY((
double)(sumXX * sumY - sumX * sumXY) / (
double)denom);
128 auto ipXY_ = ipXY(interceptXY_ * interceptXY_ * (1.0 - slopeXY_ * slopeXY_));
130 auto chisqXY_ = chisqXY(slopeXY_ * slopeXY_ * sumXX
131 + interceptXY_ * interceptXY_ * nHits
133 + 2.0 * slopeXY_ * interceptXY_ * sumX
134 - 2.0 * slopeXY_ * sumXY
135 - 2.0 * interceptXY_ * sumY);
137 return nt::ntuple(slopeXY_, interceptXY_, ipXY_, chisqXY_, Nhits(nHits));
148 void klm_trig_linear_fit_t::clear_geometry()
154 void klm_trig_linear_fit_t::add_geometry(
const KLM_geo_fit_t& geometry)
157 m_KLMgeomap[get_index(geometry)] = geo_KLM_t{
167 void klm_trig_linear_fit_t::run(
const KLM_Digit_compact_ts& hits)
170 __CSV__WRITE__(hits);
171 m_linear_fits.clear();
174 auto hits_w_geo_fit = nt::algorithms::add_column(
176 [&](
const auto & e1) {
178 Belle2::KLM_TRG_definitions::x_pos(0),
179 Belle2::KLM_TRG_definitions::y_pos(0)
182 auto&& e2 = m_KLMgeomap[get_index(e1)];
183 ret.x_pos.v = e1.layer * e2.slopeX + e2.offsetX;
184 ret.y_pos.v = e1.strip * e2.slopeY + e2.offsetY;
191 __CSV__WRITE__(hits_w_geo_fit);
192 nt::algorithms::sort(hits_w_geo_fit);
196 track_maker_.y_cutoff = y_cutoff;
199 auto hits_w_geo_fit_w_tracks = nt::algorithms::add_column(
201 [&](
const auto & e) {
203 track_id(track_maker_(e))
212 __CSV__WRITE__(hits_w_geo_fit_w_tracks);
216 m_linear_fits = nt_group(
217 hits_w_geo_fit_w_tracks[0].subdetector,
218 hits_w_geo_fit_w_tracks[0].section,
219 hits_w_geo_fit_w_tracks[0].sector,
220 hits_w_geo_fit_w_tracks[0].plane,
221 hits_w_geo_fit_w_tracks[0].track_id
223 hits_w_geo_fit_w_tracks,
226 __CSV__WRITE__(m_linear_fits);
229 nt::algorithms::filter(m_linear_fits, [&](
const auto & e) {
return std::abs(e.interceptXY) <= m_intercept_cutoff; });
232 auto m_linear_fits1 = nt_group(
233 m_linear_fits[0].subdetector,
234 m_linear_fits[0].section,
235 m_linear_fits[0].sector
238 [](
const auto & es) {
241 for (
const auto& e : es) {
242 if (e.plane == 0) { plane0 = true; }
243 if (e.plane == 1) { plane1 = true; }
246 ax_maker(trigger_or) = (int)(plane0 || plane1),
247 ax_maker(trigger_and) = (int)(plane0 && plane1)
251 __CSV__WRITE__(m_linear_fits1);
253 m_sections_trig = nt_group(
254 m_linear_fits1[0].subdetector,
255 m_linear_fits1[0].section
260 KLM_TRG_definitions::sector_mask {},
261 KLM_TRG_definitions::sector_mask_or{}
263 auto trig_and = nt::algorithms::filter_copy(e, [](
const auto & x) {
return x.trigger_and > 0; });
264 ret.sector_mask.v = Belle2::to_bit_mask< sector >(trig_and);
265 ret.sector_mask_or.v = Belle2::to_bit_mask< sector >(e);
270 __CSV__WRITE__(m_sections_trig);
275 const KLM_trig_linear_fits& klm_trig_linear_fit_t::get_result()
const
277 return m_linear_fits;
282 int klm_trig_linear_fit_t::get_triggermask(
int subdetector,
int section)
284 for (
const auto& e : m_sections_trig) {
285 if (e.subdetector == subdetector && e.section == section) {
286 return e.sector_mask;
292 int klm_trig_linear_fit_t::get_triggermask_or(
int subdetector,
int section)
294 for (
const auto& e : m_sections_trig) {
295 if (e.subdetector == subdetector && e.section == section) {
296 return e.sector_mask_or;
302 void klm_trig_linear_fit_t::set_y_cutoff(
int cutoff)
307 void klm_trig_linear_fit_t::set_intercept_cutoff(
int cutoff)
309 m_intercept_cutoff = cutoff;
Abstract base class for different kinds of events.