77 : theHitsMin_(iConfig.getParameter<
int>(
"HitsMin")),
78 thePruneCut_(iConfig.getParameter<double>(
"PruneCut")),
79 theTimeOffset_(iConfig.getParameter<double>(
"DTTimeOffset")),
80 theError_(iConfig.getParameter<double>(
"HitError")),
81 useSegmentT0_(iConfig.getParameter<
bool>(
"UseSegmentT0")),
82 doWireCorr_(iConfig.getParameter<
bool>(
"DoWireCorr")),
83 dropTheta_(iConfig.getParameter<
bool>(
"DropTheta")),
84 requireBothProjections_(iConfig.getParameter<
bool>(
"RequireBothProjections")),
85 debug(iConfig.getParameter<
bool>(
"debug")) {
97 const std::vector<const DTRecSegment4D*>& segments,
102 std::cout <<
" *** DT Timimng Extractor ***" << std::endl;
124 std::vector<TimeMeasurement> tms;
125 for (
const auto& rechit : segments) {
127 DetId id = rechit->geographicalId();
134 bool bothProjections = ((rechit->hasPhi()) && (rechit->hasZed()));
145 segm = dynamic_cast<const DTRecSegment2D*>(rechit->phiSegment());
147 std::cout <<
" *** Segment t0: " << segm->
t0() << std::endl;
149 segm = dynamic_cast<const DTRecSegment2D*>(rechit->zSegment());
160 for (
const auto& hiti : hits1d) {
164 std::pair<TrajectoryStateOnSurface, double> tsos;
168 double dist_straight = dtcell->
toGlobal(hiti.localPosition()).
mag();
169 if (tsos.first.isValid()) {
170 dist = tsos.second + posp.mag();
173 dist = dist_straight;
177 thisHit.
driftCell = hiti.geographicalId();
193 if (
doWireCorr_ && !bothProjections && tsos.first.isValid()) {
195 float propgL = layer->
toLocal(tsos.first.globalPosition()).
y();
196 float wirePropCorr = propgL / 24.4 * 0.00543;
198 wirePropCorr = -wirePropCorr;
202 tofCorr = (tofCorr / 29.979) * 0.00543;
208 float slCorr = (dist_straight - dist) / 29.979 * 0.00543;
217 tms.push_back(thisHit);
222 bool modified =
false;
223 std::vector<double> dstnc, local_t0, hitWeightTimeVtx, hitWeightInvbeta, left;
224 double totalWeightInvbeta = 0;
225 double totalWeightTimeVtx = 0;
232 hitWeightTimeVtx.clear();
233 hitWeightInvbeta.clear();
236 std::vector<int> hit_idx;
237 totalWeightInvbeta = 0;
238 totalWeightTimeVtx = 0;
241 for (
int sta = 1; sta < 5; sta++)
243 std::vector<TimeMeasurement> seg;
244 std::vector<int> seg_idx;
246 for (
auto& tm : tms) {
247 if ((tm.station == sta) && (tm.isPhi ==
phi)) {
249 seg_idx.push_back(tmpos);
254 unsigned int segsize = seg.size();
259 std::vector<double> hitxl, hitxr, hityl, hityr;
261 for (
auto& tm : seg) {
262 DetId id = tm.driftCell;
270 hitxl.push_back(celly);
271 hityl.push_back(tm.posInLayer);
273 hitxr.push_back(celly);
274 hityr.push_back(tm.posInLayer);
278 if (!
fitT0(
a,
b, hitxl, hityl, hitxr, hityr)) {
280 std::cout <<
" t0 = zero, Left hits: " << hitxl.size() <<
" Right hits: " << hitxr.size() << std::endl;
285 if ((hitxl.empty()) || (hityl.empty()))
289 for (
const auto& tm : seg) {
290 DetId id = tm.driftCell;
296 double segmLocalPos =
b + layerZ *
a;
297 double hitLocalPos = tm.posInLayer;
298 int hitSide = -tm.isLeft * 2 + 1;
299 double t0_segm = (-(hitSide * segmLocalPos) + (hitSide * hitLocalPos)) / 0.00543 + tm.timeCorr;
302 std::cout <<
" Segm hit. dstnc: " << tm.distIP <<
" t0: " << t0_segm << std::endl;
304 dstnc.push_back(tm.distIP);
305 local_t0.push_back(t0_segm);
306 left.push_back(hitSide);
307 hitWeightInvbeta.push_back(((
double)seg.size() - 2.) * tm.distIP * tm.distIP /
309 hitWeightTimeVtx.push_back(((
double)seg.size() - 2.) / ((double)seg.size() *
theError_ *
theError_));
310 hit_idx.push_back(seg_idx.at(segidx));
312 totalWeightInvbeta += ((double)seg.size() - 2.) * tm.distIP * tm.distIP /
314 totalWeightTimeVtx += ((double)seg.size() - 2.) / ((double)seg.size() *
theError_ *
theError_);
318 if (totalWeightInvbeta == 0)
323 std::cout <<
" Points for global fit: " << dstnc.size() << std::endl;
325 double invbeta = 0, invbetaErr = 0;
326 double timeVtx = 0, timeVtxErr = 0;
328 for (
unsigned int i = 0;
i < dstnc.size();
i++) {
329 invbeta += (1. + local_t0.at(
i) / dstnc.at(
i) * 30.) * hitWeightInvbeta.at(
i) / totalWeightInvbeta;
330 timeVtx += local_t0.at(
i) * hitWeightTimeVtx.at(
i) / totalWeightTimeVtx;
334 std::vector<TimeMeasurement>::iterator tmmax;
337 double diff_ibeta, diff_tvtx;
338 for (
unsigned int i = 0;
i < dstnc.size();
i++) {
339 diff_ibeta = (1. + local_t0.at(
i) / dstnc.at(
i) * 30.) - invbeta;
340 diff_ibeta = diff_ibeta * diff_ibeta * hitWeightInvbeta.at(
i);
341 diff_tvtx = local_t0.at(
i) - timeVtx;
342 diff_tvtx = diff_tvtx * diff_tvtx * hitWeightTimeVtx.at(
i);
343 invbetaErr += diff_ibeta;
344 timeVtxErr += diff_tvtx;
348 if (diff_tvtx > chimax) {
349 tmmax = tms.begin() + hit_idx.at(
i);
361 double cf = 1. / (dstnc.size() - 1);
362 invbetaErr =
sqrt(invbetaErr / totalWeightInvbeta * cf);
363 timeVtxErr =
sqrt(timeVtxErr / totalWeightTimeVtx * cf);
364 std::cout <<
" Measured 1/beta: " << invbeta <<
" +/- " << invbetaErr << std::endl;
365 std::cout <<
" Measured time: " << timeVtx <<
" +/- " << timeVtxErr << std::endl;
370 for (
unsigned int i = 0;
i < dstnc.size();
i++) {
371 tmSequence.
dstnc.push_back(dstnc.at(
i));
372 tmSequence.
local_t0.push_back(local_t0.at(
i));
390 std::cout <<
" The muon track matches " <<
range.size() <<
" segments." << std::endl;
396 const std::vector<double>& xl,
397 const std::vector<double>& yl,
398 const std::vector<double>& xr,
399 const std::vector<double>& yr) {
400 double sx = 0,
sy = 0, sxy = 0, sxx = 0, ssx = 0, ssy = 0,
s = 0,
ss = 0;
402 for (
unsigned int i = 0;
i < xl.size();
i++) {
405 sxy += xl[
i] * yl[
i];
406 sxx += xl[
i] * xl[
i];
413 for (
unsigned int i = 0;
i < xr.size();
i++) {
416 sxy += xr[
i] * yr[
i];
417 sxx += xr[
i] * xr[
i];
430 b = (ssx *
sy * ssx + sxx * ssy *
ss +
sx * sxy *
s - sxx *
sy *
s - ssx * sxy *
ss -
sx * ssy * ssx) /
delta;
431 t0_corr = (ssx *
s * sxy + sxx *
ss *
sy +
sx *
sx * ssy - sxx *
s * ssy -
sx *
ss * sxy - ssx *
sx *
sy) /
delta;