66// (typically WireCell::Root::SCEFieldTH3) lives in the root/ subpackage and
77// is looked up by jsonnet TypeName.
88//
9- // Applies:
9+ // Applies (all in WCT mm) :
1010// (1) T0: x_t0 = x_raw - dirx * cluster_t0 * drift_speed
11- // (2) SCE: x_sce = x_t0 + field->displacement_x(apa, x_t0, y, z)
11+ // (2) SCE: x_sce = x_t0 + field->displacement_x(apa, x_t0, y, z)
12+ // y_sce = y + field->displacement_y(apa, x_t0, y, z)
13+ // z_sce = z + field->displacement_z(apa, x_t0, y, z)
1214//
1315// East/West (apa==0/1) routing is handled inside the ISCEField implementation.
14- // If no field is provided (nullptr), the SCE step is a no-op (T0 still applied).
16+ // If no field is provided (nullptr), the SCE step is a no-op (T0 still applied
17+ // to x; y, z pass through).
1518//
1619// Author: Avinay Bhat (UChicago), for SBND
1720// Modeled on T0Correction by Haiwang Yu.
@@ -53,24 +56,30 @@ namespace WireCell::Clus {
5356 double cluster_t0, int face, int apa) const override ;
5457
5558 virtual PointCloud::Tree::Scope output_scope () const override {
56- return {" 3d" , {" x_sce" , " y " , " z " }};
59+ return {" 3d" , {" x_sce" , " y_sce " , " z_sce " }};
5760 }
5861 virtual std::vector<std::string> stored_array_names () const override {
59- return {" x_sce" };
62+ return {" x_sce" , " y_sce " , " z_sce " };
6063 }
6164
6265 private:
6366 IDetectorVolumes::pointer m_dv;
6467 WireCell::ISCEField::pointer m_field;
6568 std::map<int , std::map<int , double >> m_drift_speeds;
6669
67- // Combined T0 + SCE for one X coordinate. All quantities in WCT mm.
68- inline double corrected_x (double x_raw_mm, double y_mm, double z_mm,
69- double cluster_t0, int face, int apa) const {
70+ // Combined T0 + full 3D SCE for one point. All quantities in WCT mm.
71+ inline void corrected_xyz (double x_raw_mm, double y_mm, double z_mm,
72+ double cluster_t0, int face, int apa,
73+ double & xs, double & ys, double & zs) const {
7074 const double dirx = m_dv->face_dirx (WirePlaneId (kAllLayers , face, apa));
7175 const double x_t0_mm = x_raw_mm - dirx * cluster_t0 * m_drift_speeds.at (apa).at (face);
72- const double dx_mm = m_field ? m_field->displacement_x (apa, x_t0_mm, y_mm, z_mm) : 0.0 ;
73- return x_t0_mm + dx_mm;
76+ if (m_field) {
77+ xs = x_t0_mm + m_field->displacement_x (apa, x_t0_mm, y_mm, z_mm);
78+ ys = y_mm + m_field->displacement_y (apa, x_t0_mm, y_mm, z_mm);
79+ zs = z_mm + m_field->displacement_z (apa, x_t0_mm, y_mm, z_mm);
80+ } else {
81+ xs = x_t0_mm; ys = y_mm; zs = z_mm;
82+ }
7483 }
7584 };
7685
@@ -83,21 +92,23 @@ namespace WireCell::Clus {
8392 const auto md = m_dv->metadata (wpid);
8493 m_drift_speeds[wpid.apa ()][wpid.face ()] = md[" drift_speed" ].asDouble ();
8594 }
86- if (m_field) spdlog::info (" SCECorrection: ISCEField wired in" );
95+ if (m_field) spdlog::info (" SCECorrection: ISCEField wired in (x,y,z) " );
8796 else spdlog::info (" SCECorrection: no ISCEField -- SCE disabled (T0 still applied)" );
8897 }
8998
9099 inline Point SCECorrection::forward (const Point& pos_raw, double t0, int face, int apa) const {
91100 Point pc (pos_raw);
92- pc[ 0 ] = corrected_x (pos_raw[0 ], pos_raw[1 ], pos_raw[2 ], t0, face, apa);
101+ corrected_xyz (pos_raw[0 ], pos_raw[1 ], pos_raw[2 ], t0, face, apa, pc[ 0 ], pc[ 1 ], pc[ 2 ] );
93102 return pc;
94103 }
95104
96105 inline Point SCECorrection::backward (const Point& pos_cor, double t0, int face, int apa) const {
97106 Point pr (pos_cor);
98107 if (m_field) {
99- // Approximate: evaluate field at x_sce instead of x_t0 (small displacement OK) .
108+ // Approximate: evaluate field at the corrected position .
100109 pr[0 ] -= m_field->displacement_x (apa, pos_cor[0 ], pos_cor[1 ], pos_cor[2 ]);
110+ pr[1 ] -= m_field->displacement_y (apa, pos_cor[0 ], pos_cor[1 ], pos_cor[2 ]);
111+ pr[2 ] -= m_field->displacement_z (apa, pos_cor[0 ], pos_cor[1 ], pos_cor[2 ]);
101112 }
102113 const double dirx = m_dv->face_dirx (WirePlaneId (kAllLayers , face, apa));
103114 pr[0 ] += dirx * t0 * m_drift_speeds.at (apa).at (face);
@@ -117,14 +128,15 @@ namespace WireCell::Clus {
117128 const auto & ax = pc_raw.get (arr_raw_names[0 ])->elements <double >();
118129 const auto & ay = pc_raw.get (arr_raw_names[1 ])->elements <double >();
119130 const auto & az = pc_raw.get (arr_raw_names[2 ])->elements <double >();
120- std::vector<double > ax_c (ax.size ());
131+ std::vector<double > ax_c (ax.size ()), ay_c (ax. size ()), az_c (ax. size ()) ;
121132 for (size_t i = 0 ; i < ax.size (); ++i) {
122- ax_c[i] = corrected_x (ax[i], ay[i], az[i], t0, face, apa);
133+ corrected_xyz (ax[i], ay[i], az[i], t0, face, apa,
134+ ax_c[i], ay_c[i], az_c[i]);
123135 }
124136 Dataset ds;
125- ds.add (arr_cor_names[0 ], Array (ax_c));
126- ds.add (arr_cor_names[1 ], Array (ay ));
127- ds.add (arr_cor_names[2 ], Array (az ));
137+ ds.add (arr_cor_names[0 ], Array (ax_c)); // x_sce
138+ ds.add (arr_cor_names[1 ], Array (ay_c )); // y_sce
139+ ds.add (arr_cor_names[2 ], Array (az_c )); // z_sce
128140 return ds;
129141 }
130142
@@ -138,17 +150,21 @@ namespace WireCell::Clus {
138150 const auto & az = pc_cor.get (arr_cor_names[2 ])->elements <double >();
139151 const double dirx = m_dv->face_dirx (WirePlaneId (kAllLayers , face, apa));
140152 const double v = m_drift_speeds.at (apa).at (face);
141- std::vector<double > ax_r (ax.size ());
153+ std::vector<double > ax_r (ax.size ()), ay_r (ax. size ()), az_r (ax. size ()) ;
142154 for (size_t i = 0 ; i < ax.size (); ++i) {
143- double x = ax[i];
144- if (m_field) x -= m_field->displacement_x (apa, ax[i], ay[i], az[i]);
155+ double x = ax[i], y = ay[i], z = az[i];
156+ if (m_field) {
157+ x -= m_field->displacement_x (apa, ax[i], ay[i], az[i]);
158+ y -= m_field->displacement_y (apa, ax[i], ay[i], az[i]);
159+ z -= m_field->displacement_z (apa, ax[i], ay[i], az[i]);
160+ }
145161 x += dirx * t0 * v;
146- ax_r[i] = x;
162+ ax_r[i] = x; ay_r[i] = y; az_r[i] = z;
147163 }
148164 Dataset ds;
149165 ds.add (arr_raw_names[0 ], Array (ax_r));
150- ds.add (arr_raw_names[1 ], Array (ay ));
151- ds.add (arr_raw_names[2 ], Array (az ));
166+ ds.add (arr_raw_names[1 ], Array (ay_r ));
167+ ds.add (arr_raw_names[2 ], Array (az_r ));
152168 return ds;
153169 }
154170
0 commit comments