9#include <cdc/simulation/CDCSensitiveDetector.h>
11#include <cdc/simulation/CDCSimControlPar.h>
12#include <cdc/simulation/Helix.h>
13#include <cdc/geometry/CDCGeometryPar.h>
14#include <cdc/utilities/ClosestApproach.h>
15#include <framework/logging/Logger.h>
16#include <framework/datastore/RelationArray.h>
17#include <framework/geometry/B2Vector3.h>
20#include "G4TransportationManager.hh"
22#include "G4FieldManager.hh"
24#include "CLHEP/Geometry/Vector3D.h"
25#include "CLHEP/Geometry/Point3D.h"
28#ifndef ENABLE_BACKWARDS_COMPATIBILITY
31#ifndef ENABLE_BACKWARDS_COMPATIBILITY
32typedef HepGeom::Vector3D<double> HepVector3D;
49 SensitiveDetectorBase(name,
Const::CDC),
52 m_thresholdEnergyDeposit(thresholdEnergyDeposit),
53 m_thresholdKineticEnergy(thresholdKineticEnergy), m_hitNumber(0)
73 B2DEBUG(150,
"CDCSensitiveDetector: Sense wire sag on(=1)/off(=0): " <<
m_wireSag);
76 B2DEBUG(150,
"CDCSensitiveDetector: Set left/right flag modified for tracking (=1)/ not set (=0): " <<
m_modifiedLeftRightFlag);
80 B2DEBUG(150,
"CDCSensitiveDetector: MinTrackLength (mm): " <<
m_minTrackLength);
143#if defined(CDC_DEBUG)
144 std::cout <<
" " << std::endl;
145 std::cout <<
"********* step in ********" << std::endl;
148 const G4double edep = aStep->GetTotalEnergyDeposit();
155 const G4double stepLength = aStep->GetStepLength();
156 if (stepLength == 0.)
return false;
159 const G4Track& t = * aStep->GetTrack();
177 const G4int pid = t.GetDefinition()->GetPDGEncoding();
178 const G4double charge = t.GetDefinition()->GetPDGCharge();
179 const G4int trackID = t.GetTrackID();
182 const G4VPhysicalVolume& v = * t.GetVolume();
183 const G4StepPoint& in = * aStep->GetPreStepPoint();
184 const G4StepPoint& out = * aStep->GetPostStepPoint();
185 const G4ThreeVector& posIn = in.GetPosition();
186 const G4ThreeVector& posOut = out.GetPosition();
187 const G4ThreeVector momIn(in.GetMomentum().x(), in.GetMomentum().y(),
188 in.GetMomentum().z());
189#if defined(CDC_DEBUG)
190 std::cout <<
"pid = " << pid << std::endl;
191 std::cout <<
"mass = " << t.GetDefinition()->GetPDGMass() << std::endl;
192 std::cout <<
"posIn = " << posIn << std::endl;
193 std::cout <<
"posOut= " << posOut << std::endl;
194 std::cout <<
"tof at post-step = " << out.GetGlobalTime() << std::endl;
195 std::cout <<
"stepl = " << stepLength << std::endl;
199 const unsigned layerId = v.GetCopyNo();
201 B2DEBUG(150,
"LayerID in continuous counting method: " << layerId);
205 if ((charge == 0.) && (abs(pid) != 99666))
return false;
208 B2Vector3D tposIn(posIn.x() / CLHEP::cm, posIn.y() / CLHEP::cm, posIn.z() / CLHEP::cm);
209 B2Vector3D tposOut(posOut.x() / CLHEP::cm, posOut.y() / CLHEP::cm, posOut.z() / CLHEP::cm);
210 const unsigned idIn =
m_cdcgp->
cellId(layerIDWithLayerOffset, tposIn);
211 const unsigned idOut =
m_cdcgp->
cellId(layerIDWithLayerOffset, tposOut);
212#if defined(CDC_DEBUG)
213 std::cout <<
"edep= " << edep << std::endl;
214 std::cout <<
"idIn,idOut= " << idIn <<
" " << idOut << std::endl;
220 const G4double s_in_layer = stepLength / CLHEP::cm;
221 G4double xint[6] = {0};
223 const G4ThreeVector momOut(out.GetMomentum().x(), out.GetMomentum().y(),
224 out.GetMomentum().z());
225 const G4double speedIn = in.GetVelocity();
226 const G4double speedOut = out.GetVelocity();
227 const G4double speed = 0.5 * (speedIn + speedOut);
228 const G4double speedInCmPerNs = speed / CLHEP::cm;
230 const unsigned int nWires = wires.size();
231 G4double tofBefore = in.GetGlobalTime();
232 G4double kinEnergyBefore = in.GetKineticEnergy();
233 G4double momBefore = momIn.mag();
234 const G4double eLoss = kinEnergyBefore - out.GetKineticEnergy();
235 const G4double mass = t.GetDefinition()->GetPDGMass();
236#if defined(CDC_DEBUG)
237 std::cout <<
"momBefore = " << momBefore << std::endl;
238 std::cout <<
"momIn = " << momIn.x() <<
" " << momIn.y() <<
" " << momIn.z() << std::endl;
239 std::cout <<
"momOut= " << momOut.x() <<
" " << momOut.y() <<
" " << momOut.z() << std::endl;
240 std::cout <<
"speedIn,speedOut= " << speedIn <<
" " << speedOut << std::endl;
241 std::cout <<
" speedInCmPerNs= " << speedInCmPerNs << std::endl;
242 std::cout <<
"tofBefore= " << tofBefore << std::endl;
245 const G4Field* field = G4TransportationManager::GetTransportationManager()->GetFieldManager()->GetDetectorField();
247 for (
unsigned i = 0; i < nWires; ++i) {
248#if defined(CDC_DEBUG)
249 std::cout <<
"============ i,wires[i]= " << i <<
" " << wires[i] << std::endl;
252 const G4double pos[3] = {posIn.x(), posIn.y(), posIn.z()};
254 field->GetFieldValue(pos, Bfield);
256 Bfield[2] == 0.) ?
false :
true;
257#if defined(CDC_DEBUG)
258 std::cout <<
"Bfield= " << Bfield[0] <<
" " << Bfield[1] <<
" " << Bfield[2] << std::endl;
263 G4ThreeVector posW(0, 0, 0);
279 if (Bfield[0] == 0. && Bfield[1] == 0. &&
282 const G4double B_kG[3] = {Bfield[0] / CLHEP::kilogauss,
283 Bfield[1] / CLHEP::kilogauss,
284 Bfield[2] / CLHEP::kilogauss
286#if defined(CDC_DEBUG)
287 std::cout <<
"B_kG= " << B_kG[0] <<
" " << B_kG[1] <<
" " << B_kG[2] << std::endl;
291 const HepPoint3D x(pos[0] / CLHEP::cm, pos[1] / CLHEP::cm, pos[2] / CLHEP::cm);
292 const HepVector3D p(momIn.x() / CLHEP::GeV, momIn.y() / CLHEP::GeV, momIn.z() / CLHEP::GeV);
293 Helix tmp(x, p, charge);
305 const HepVector3D wire = fwd - bck;
307 (x.z() - bck.z()) / wire.z() * wire + bck;
309 tryp = (tmp.
x(0.).z() - bck.z()) / wire.z() * wire + bck;
311 tryp = (tmp.
x(0.).z() - bck.z()) / wire.z() * wire + bck;
314 distance = std::abs(tmp.
a()[0]);
324 const G4double xwb(bck.x()), ywb(bck.y()), zwb(bck.z());
325 const G4double xwf(fwd.x()), ywf(fwd.y()), zwf(fwd.z());
326 const G4double xp(onTrack.x()), yp(onTrack.y()), zp(onTrack.z());
327 const G4double px(pOnTrack.x()), py(pOnTrack.y()), pz(pOnTrack.z());
328 G4double q2[3] = {0.}, q1[3] = {0.}, q3[3] = {0.};
329 const G4int ntryMax(50);
332 HELWIR(xwb, ywb, zwb, xwf, ywf, zwf,
333 xp, yp, zp, px, py, pz,
334 B_kG, charge, ntryMax, dist, q2, q1, q3, ntry);
336#if defined(CDC_DEBUG)
337 std::cout <<
"ntry= " << ntry << std::endl;
338 std::cout <<
"bf distance= " << distance << std::endl;
339 std::cout <<
"onTrack = " << onTrack << std::endl;
340 std::cout <<
"posW = " << posW << std::endl;
342 if (ntry <= ntryMax) {
344 G4double ywb_sag, ywf_sag;
346 HELWIR(xwb, ywb_sag, zwb, xwf, ywf_sag, zwf,
347 xp, yp, zp, px, py, pz,
348 B_kG, charge, ntryMax, dist, q2, q1, q3, ntry);
350 if (ntry <= ntryMax) {
358 pOnTrack.setX(q3[0]);
359 pOnTrack.setY(q3[1]);
360 pOnTrack.setZ(q3[2]);
362#if defined(CDC_DEBUG)
363 std::cout <<
" " << std::endl;
364 std::cout <<
"helix distance= " << distance << std::endl;
365 std::cout <<
"onTrack = " << onTrack << std::endl;
366 std::cout <<
"posW = " << posW << std::endl;
367 std::cout <<
"pOnTrack= " << pOnTrack << std::endl;
368 G4ThreeVector bwp(bck.x(), bck.y(), bck.z());
369 G4ThreeVector fwp(fwd.x(), fwd.y(), fwd.z());
370 G4ThreeVector hitPosition, wirePosition;
371 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
372 hitPosition, wirePosition);
374 G4double ywb_sag, ywf_sag;
375 m_cdcgp->
getWireSagEffect(CDCGeometryPar::c_Base, layerIDWithLayerOffset, wires[i], wirePosition.z(), ywb_sag, ywf_sag);
378 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
379 hitPosition, wirePosition);
381 std::cout <<
"line distance= " << distance << std::endl;
382 std::cout <<
"onTrack= " << hitPosition.x() <<
" " << hitPosition.y() <<
" " << hitPosition.z() << std::endl;
383 std::cout <<
"posW = " << wirePosition.x() <<
" " << wirePosition.y() <<
" " << wirePosition.z() << std::endl;
388 G4ThreeVector bwp(bck.x(), bck.y(), bck.z());
389 G4ThreeVector fwp(fwd.x(), fwd.y(), fwd.z());
390 G4ThreeVector hitPosition, wirePosition;
391 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
392 hitPosition, wirePosition);
394 G4double ywb_sag, ywf_sag;
395 m_cdcgp->
getWireSagEffect(CDCGeometryPar::c_Base, layerIDWithLayerOffset, wires[i], wirePosition.z(), ywb_sag, ywf_sag);
398 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
399 hitPosition, wirePosition);
402 onTrack.setX(hitPosition.x());
403 onTrack.setY(hitPosition.y());
404 onTrack.setZ(hitPosition.z());
405 posW.setX(wirePosition.x());
406 posW.setY(wirePosition.y());
407 posW.setZ(wirePosition.z());
409 pOnTrack.setX(0.5 * (momIn.x() + momOut.x()) / CLHEP::GeV);
410 pOnTrack.setY(0.5 * (momIn.y() + momOut.y()) / CLHEP::GeV);
411 pOnTrack.setZ(0.5 * (momIn.z() + momOut.z()) / CLHEP::GeV);
414#if defined(CDC_DEBUG)
415 std::cout <<
"af distance= " << distance << std::endl;
416 std::cout <<
"onTrack = " << onTrack << std::endl;
417 std::cout <<
"posW = " << posW << std::endl;
418 std::cout <<
"pOnTrack = " << pOnTrack << std::endl;
419 if (distance > 2.4) {
420 std::cout <<
"toolargedriftl" << std::endl;
423 distance *= CLHEP::cm; onTrack *= CLHEP::cm; posW *= CLHEP::cm;
424 pOnTrack *= CLHEP::GeV;
426 G4ThreeVector posTrack(onTrack.x(), onTrack.y(), onTrack.z());
427 G4ThreeVector mom(pOnTrack.x(), pOnTrack.y(), pOnTrack.z());
429 const B2Vector3D tPosW(posW.x(), posW.y(), posW.z());
430 const B2Vector3D tPosTrack(posTrack.x(), posTrack.y(), posTrack.z());
431 const B2Vector3D tMom(mom.x(), mom.y(), mom.z());
437 G4int newLr = newLrRaw;
442 saveSimHit(layerIDWithLayerOffset, wires[i], trackID, pid, distance, tofBefore, edep, s_in_layer * CLHEP::cm, pOnTrack, posW, posIn,
444 posTrack, lr, newLrRaw, newLr, speed, hitWeight);
445#if defined(CDC_DEBUG)
446 std::cout <<
"saveSimHit" << std::endl;
447 std::cout <<
"momIn = " << momIn << std::endl;
448 std::cout <<
"pOnTrack = " << pOnTrack << std::endl;
453 G4int cel1 = wires[i] + 1;
455 if (i + 1 <= nWires - 1) {
456 cel2 = wires[i + 1] + 1;
458 const G4double s2 = t.GetTrackLength() / CLHEP::cm;
459 G4double s1 = (s2 - s_in_layer);
460 G4ThreeVector din = momIn;
461 if (din.mag() != 0.) din /= momIn.mag();
463 G4double vent[6] = {posIn.x() / CLHEP::cm, posIn.y() / CLHEP::cm, posIn.z() / CLHEP::cm, din.x(), din.y(), din.z()};
465 G4ThreeVector
dot(momOut.x(), momOut.y(), momOut.z());
466 if (
dot.mag() != 0.) {
473 G4double vext[6] = {posOut.x() / CLHEP::cm, posOut.y() / CLHEP::cm, posOut.z() / CLHEP::cm,
dot.x(),
dot.y(),
dot.z()};
476 for (
int j = 0; j < 6; ++j) vent[j] = xint[j];
482 G4double edep_in_cell(0.);
483 G4double eLossInCell(0.);
486#if defined(CDC_DEBUG)
487 std::cout <<
"layerId,cel1,cel2= " << layerId <<
" " << cel1 <<
" " << cel2 << std::endl;
488 std::cout <<
"vent= " << vent[0] <<
" " << vent[1] <<
" " << vent[2] <<
" " << vent[3] <<
" " << vent[4] <<
" " << vent[5] <<
490 std::cout <<
"vext= " << vext[0] <<
" " << vext[1] <<
" " << vext[2] <<
" " << vext[3] <<
" " << vext[4] <<
" " << vext[5] <<
492 std::cout <<
"s1,s2,ic= " << s1 <<
" " << s2 <<
" " << ic << std::endl;
494 CellBound(layerIDWithLayerOffset, cel1, cel2, vent, vext, s1, s2, xint, sint, flag);
495#if defined(CDC_DEBUG)
496 std::cout <<
"flag,sint= " << flag <<
" " << sint << std::endl;
497 std::cout <<
"xint= " << xint[0] <<
" " << xint[1] <<
" " << xint[2] <<
" " << xint[3] <<
" " << xint[4] <<
" " << xint[5] <<
501 const G4double test = (sint - s1) / s_in_layer;
502 if (test < 0. || test > 1.) {
503 B2WARNING(
"CDCSensitiveDetector: Strange path length: " <<
"s1= " << s1 <<
" sint= " << sint <<
" s_in_layer= " << s_in_layer <<
506 edep_in_cell = edep * std::abs((sint - s1)) / s_in_layer;
508 const G4ThreeVector x_In(vent[0]*CLHEP::cm, vent[1]*CLHEP::cm, vent[2]*CLHEP::cm);
509 const G4ThreeVector x_Out(xint[0]*CLHEP::cm, xint[1]*CLHEP::cm, xint[2]*CLHEP::cm);
510 const G4ThreeVector p_In(momBefore * vent[3], momBefore * vent[4], momBefore * vent[5]);
513 saveSimHit(layerIDWithLayerOffset, wires[i], trackID, pid, distance, tofBefore, edep_in_cell, std::abs((sint - s1)) * CLHEP::cm,
516 posTrack, lr, newLrRaw, newLr, speed, hitWeight);
517#if defined(CDC_DEBUG)
518 std::cout <<
"saveSimHit" << std::endl;
519 std::cout <<
"p_In = " << p_In << std::endl;
520 std::cout <<
"pOnTrack= " << pOnTrack << std::endl;
522 tofBefore += (sint - s1) / speedInCmPerNs;
523 eLossInCell = eLoss * (sint - s1) / s_in_layer;
524 kinEnergyBefore -= eLossInCell;
525 if (kinEnergyBefore >= 0.) {
526 momBefore =
sqrt(kinEnergyBefore * (kinEnergyBefore + 2.*mass));
528 B2WARNING(
"CDCSensitiveDetector: Kinetic Energy < 0.");
534 const G4double test = (s2 - sint) / s_in_layer;
535 if (test < 0. || test > 1.) {
536 B2WARNING(
"CDCSensitiveDetector: Strange path length: " <<
"s2= " << s2 <<
" sint= " << sint <<
" s_in_layer= " << s_in_layer <<
539 edep_in_cell = edep * std::abs((s2 - sint)) / s_in_layer;
541 const G4ThreeVector x_In(vent[0]*CLHEP::cm, vent[1]*CLHEP::cm, vent[2]*CLHEP::cm);
542 const G4ThreeVector p_In(momBefore * vent[3], momBefore * vent[4], momBefore * vent[5]);
545 saveSimHit(layerIDWithLayerOffset, wires[i], trackID, pid, distance, tofBefore, edep_in_cell, std::abs((s2 - sint)) * CLHEP::cm,
548 posOut, posTrack, lr, newLrRaw, newLr, speed, hitWeight);
549#if defined(CDC_DEBUG)
550 std::cout <<
"saveSimHit" << std::endl;
551 std::cout <<
"p_In = " << p_In << std::endl;
552 std::cout <<
"pOnTrack= " << pOnTrack << std::endl;
590 const G4double distance,
593 const G4double stepLength,
594 const G4ThreeVector& mom,
595 const G4ThreeVector& posW,
596 const G4ThreeVector& posIn,
597 const G4ThreeVector& posOut,
598 const G4ThreeVector& posTrack,
600 const G4int newLrRaw,
602 const G4double speed,
603 const G4double hitWeight)
611 const G4double sign = (posTrack - posIn).
dot(mom) < 0. ? -1. : 1.;
612 const G4double CorrectTof = tof + sign * (posTrack - posIn).mag() / speed;
614#if defined(CDC_DEBUG)
615 std::cout <<
"posIn= " << posIn.x() <<
" " << posIn.y() <<
" " << posIn.z() << std::endl;
616 std::cout <<
"posOut= " << posOut.x() <<
" " << posOut.y() <<
" " << posOut.z() << std::endl;
617 std::cout <<
"posTrack= " << posTrack.x() <<
" " << posTrack.y() <<
" " << posTrack.z() << std::endl;
618 std::cout <<
"posW= " << posW.x() <<
" " << posW.y() <<
" " << posW.z() << std::endl;
619 std::cout <<
"tof = " << tof << std::endl;
620 std::cout <<
"deltaTof = " << (posTrack - posIn).mag() / speed << std::endl;
621 std::cout <<
"CorrectTof= " << CorrectTof << std::endl;
622 if (CorrectTof > 95) {
623 std::cout <<
"toolargecorrecttof" << std::endl;
641 B2Vector3D momentum(mom.getX() / CLHEP::GeV, mom.getY() / CLHEP::GeV, mom.getZ() / CLHEP::GeV);
643 B2Vector3D posWire(posW.getX() / CLHEP::cm, posW.getY() / CLHEP::cm, posW.getZ() / CLHEP::cm);
645 B2Vector3D positionIn(posIn.getX() / CLHEP::cm, posIn.getY() / CLHEP::cm, posIn.getZ() / CLHEP::cm);
647 B2Vector3D positionOut(posOut.getX() / CLHEP::cm, posOut.getY() / CLHEP::cm, posOut.getZ() / CLHEP::cm);
649 B2Vector3D positionTrack(posTrack.getX() / CLHEP::cm, posTrack.getY() / CLHEP::cm, posTrack.getZ() / CLHEP::cm);
654#if defined(CDC_DEBUG)
655 std::cout <<
"sensitived,oldlr,newlrRaw,newlr= " << lr <<
" " << newLrRaw <<
" " << newLr << std::endl;
692 const G4double venter[6],
693 const G4double vexit[6],
694 const G4double s1,
const G4double s2,
696 G4double& sint, G4int& iflag)
726 B2ERROR(
"CDCSensitiveDetector: s1(=" << s1 <<
") > s2(=" << s2 <<
")");
728 if (std::abs(ic1 - ic2) != 1) {
729 if (ic1 == 1 && ic2 == div) {
730 }
else if (ic1 == div && ic2 == 1) {
732 B2ERROR(
"CDCSensitiveDetector: |ic1 - ic2| != 1 in CellBound; " <<
"ic1=" << ic1 <<
" " <<
"ic2=" << ic2);
756 G4double xx1[6], xx2[6];
757 for (
int i = 0; i < 6; ++i) {
763 G4double psi = double(ic2 - ic1) * CLHEP::pi / div;
764 if (ic1 == 1 && ic2 == div) {
765 psi = -CLHEP::pi / div;
766 }
else if (ic1 == div && ic2 == 1) {
767 psi = CLHEP::pi / div;
769 G4double cospsi = cos(psi);
770 G4double sinpsi = sin(psi);
772 G4double xfwb = cospsi * xwb - sinpsi * ywb;
773 G4double yfwb = sinpsi * xwb + cospsi * ywb;
774 G4double xfwf = cospsi * xwf - sinpsi * ywf;
775 G4double yfwf = sinpsi * xwf + cospsi * ywf;
780 G4double vx = xfwf - xfwb;
781 G4double vy = yfwf - yfwb;
782 G4double vz = zfwf - zfwb;
783 G4double vv =
sqrt(vx * vx + vy * vy + vz * vz);
784 vx /= vv; vy /= vv; vz /= vv;
787 G4double shiftx = (xx1[0] + xx2[0]) * 0.5;
788 G4double shifty = (xx1[1] + xx2[1]) * 0.5;
789 G4double shiftz = (xx1[2] + xx2[2]) * 0.5;
790 G4double shifts = (s1 + s2) * 0.5;
791 G4double xshft = xx1[0] - shiftx;
792 G4double yshft = xx1[1] - shifty;
793 G4double zshft = xx1[2] - shiftz;
794 G4double sshft = s1 - shifts;
797 G4double pabs1 =
sqrt(xx1[3] * xx1[3] + xx1[4] * xx1[4] + xx1[5] * xx1[5]);
798 G4double pabs2 =
sqrt(xx2[3] * xx2[3] + xx2[4] * xx2[4] + xx2[5] * xx2[5]);
801 G4double a[4] = {0.}, b[4] = {0.}, c[4] = {0.};
804 GCUBS(sshft, xshft, xx1[3] / pabs1, xx2[3] / pabs2, a);
805 GCUBS(sshft, yshft, xx1[4] / pabs1, xx2[4] / pabs2, b);
806 GCUBS(sshft, zshft, xx1[5] / pabs1, xx2[5] / pabs2, c);
812 a[1] = xshft / sshft;
813 b[1] = yshft / sshft;
814 c[1] = zshft / sshft;
818 G4double stry(0.), xtry(0.), ytry(0.), ztry(0.);
819 G4double beta(0.), xfw(0.), yfw(0.);
820 G4double sphi(0.), cphi(0.), dphil(0.), dphih(0.);
821 const G4int maxTrials = 100;
822 const G4double eps = 5.e-4;
824 G4double sh = -sshft;
829 xtry = shiftx + a[0] + stry * (a[1] + stry * (a[2] + stry * a[3]));
830 ytry = shifty + b[0] + stry * (b[1] + stry * (b[2] + stry * b[3]));
831 ztry = shiftz + c[0] + stry * (c[1] + stry * (c[2] + stry * c[3]));
832 beta = (ztry - zfwb) / vz;
833 xfw = xfwb + beta * vx;
834 yfw = yfwb + beta * vy;
835 sphi = (xtry * yfw - ytry * xfw);
836 cphi = (xtry * xfw + ytry * yfw);
837 dphil = atan2(sphi, cphi);
841 while (((sh - sl) > eps) && (i < maxTrials)) {
842 stry = 0.5 * (sl + sh);
843 xtry = shiftx + a[0] + stry * (a[1] + stry * (a[2] + stry * a[3]));
844 ytry = shifty + b[0] + stry * (b[1] + stry * (b[2] + stry * b[3]));
845 ztry = shiftz + c[0] + stry * (c[1] + stry * (c[2] + stry * c[3]));
846 beta = (ztry - zfwb) / vz;
847 xfw = xfwb + beta * vx;
848 yfw = yfwb + beta * vy;
850 sphi = (xtry * yfw - ytry * xfw);
851 cphi = (xtry * xfw + ytry * yfw);
852 dphih = atan2(sphi, cphi);
854 if (dphil * dphih > 0.) {
863 if (i >= maxTrials - 1) {
865 B2WARNING(
"CDCSensitiveDetector: No intersection ?");
897 xint[0] = a[0] + sint * (a[1] + sint * (a[2] + sint * a[3]));
898 xint[1] = b[0] + sint * (b[1] + sint * (b[2] + sint * b[3]));
899 xint[2] = c[0] + sint * (c[1] + sint * (c[2] + sint * c[3]));
900 xint[3] = a[1] + sint * (2. * a[2] + 3. * sint * a[3]);
901 xint[4] = b[1] + sint * (2. * b[2] + 3. * sint * b[3]);
902 xint[5] = c[1] + sint * (2. * c[2] + 3. * sint * c[3]);
928 G4double p =
sqrt(xint[3] * xint[3] + xint[4] * xint[4] + xint[5] * xint[5]);
929 xint[3] /= p; xint[4] /= p; xint[5] /= p;
954 if (x == 0.)
goto L10;
956 fact = (d1 - d2) * 0.25;
957 a[0] = - 1. * fact * x;
959 a[1] = (6. * y - (d1 + d2) * x) / (4. * x);
960 a[3] = ((d1 + d2) * x - 2.*y) / (4.*x * x * x);
986 G4double bxz, bfield;
987 bxz = bx * bx + bz * bz;
988 bfield = bxz + by * by;
990 bfield =
sqrt(bfield);
995 m_brot[0][1] = -by * bx / bxz / bfield;
996 m_brot[1][1] = bxz / bfield;
997 m_brot[2][1] = -by * bz / bxz / bfield;
998 m_brot[0][2] = bx / bfield;
999 m_brot[1][2] = by / bfield;
1000 m_brot[2][2] = bz / bfield;
1017 G4double x0(x), y0(y), z0(z);
1023 }
else if (mode == -1) {
1044 G4double x0(x[0]), y0(x[1]), z0(x[2]);
1050 }
else if (mode == -1) {
1063 const G4double zwb4,
1064 const G4double xwf4,
const G4double ywf4,
1065 const G4double zwf4,
1066 const G4double xp,
const G4double yp,
1068 const G4double px,
const G4double py,
1070 const G4double B_kG[3],
1071 const G4double charge,
const G4int ntryMax,
1073 G4double q2[3], G4double q1[3],
1099 const G4int ndim = 3;
1100 const G4double delta = 1.e-5;
1103 G4double xwb, ywb, zwb, xwf, ywf, zwf;
1104 G4double xw, yw, zw, xh, yh, zh, pxh, pyh, pzh;
1105 G4double fi, fi_corr;
1107 G4double dr, fi0, cpa, dz, tanl;
1108 G4double x0, y0, z0;
1113 G4double sinfi0, cosfi0, sinfi0fi, cosfi0fi;
1115 G4double vx, vy, vz, vv, cx, cy, cz, tt[3][3];
1118 G4double xx[3], dxx[3], ddxx[3], pp[3];
1119 G4double xxtdxx, dxxtdxx, xxtddxx;
1123 G4double f, fderiv, deltafi, fact,
eval;
1124 G4double dx1, dy1, dx2, dy2, crs,
dot;
1129 xwb = xwb4; ywb = ywb4; zwb = zwb4;
1130 xwf = xwf4; ywf = ywf4; zwf = zwf4;
1132 G4double xxx(xp), yyy(yp), zzz(zp);
1133 G4double pxx(px), pyy(py), pzz(pz);
1136 Rotat(xwb, ywb, zwb, 1);
1137 Rotat(xwf, ywf, zwf, 1);
1138 Rotat(xxx, yyy, zzz, 1);
1139 Rotat(pxx, pyy, pzz, 1);
1141 G4double a[8] = {0.};
1142 G4double pt =
sqrt(pxx * pxx + pyy * pyy);
1143 a[1] = atan2(-pxx, pyy);
1146 a[5] = xxx; a[6] = yyy; a[7] = zzz;
1149 vx = xwf - xwb; vy = ywf - ywb; vz = zwf - zwb;
1150 vv =
sqrt(vx * vx + vy * vy + vz * vz);
1151 vx /= vv; vy /= vv; vz /= vv;
1155 if (vx == 0. && vy == 0.) iflg = 1;
1160 cx = xwb - vx * (vx * xwb + vy * ywb + vz * zwb);
1161 cy = ywb - vy * (vx * xwb + vy * ywb + vz * zwb);
1162 cz = zwb - vz * (vx * xwb + vy * ywb + vz * zwb);
1165 tt[0][0] = vx * vx - 1.; tt[1][0] = vx * vy; tt[2][0] = vx * vz;
1166 tt[0][1] = vy * vx; tt[1][1] = vy * vy - 1.; tt[2][1] = vy * vz;
1167 tt[0][2] = vz * vx; tt[1][2] = vz * vy; tt[2][2] = vz * vz - 1.;
1170 dr = a[0]; fi0 = a[1]; cpa = a[2];
1171 dz = a[3]; tanl = a[4];
1172 x0 = a[5]; y0 = a[6]; z0 = a[7];
1181 G4double bfield =
sqrt(B_kG[0] * B_kG[0] +
1184 G4double alpha = 1.e4 / 2.99792458 / bfield;
1188 xc = x0 + (dr + r) * cosfi0;
1189 yc = y0 + (dr + r) * sinfi0;
1194 crs = dx1 * dy2 - dy1 * dx2;
1195 dot = dx1 * dx2 + dy1 * dy2;
1196 fi = atan2(crs,
dot);
1203 cosfi0fi = cos(fi0 + fi);
1204 sinfi0fi = sin(fi0 + fi);
1207 xx[0] = x0 + dr * cosfi0 + r * (cosfi0 - cosfi0fi);
1208 xx[1] = y0 + dr * sinfi0 + r * (sinfi0 - sinfi0fi);
1209 xx[2] = z0 + dz - r * tanl * fi;
1210 pp[0] = -pt * sinfi0fi;
1211 pp[1] = pt * cosfi0fi;
1215 q2[0] = xwb; q2[1] = ywb; q2[2] = xx[2];
1216 q1[0] = xx[0]; q1[1] = xx[1]; q1[2] = xx[2];
1217 q3[0] = pp[0]; q3[1] = pp[1]; q3[2] = pp[2];
1222 distance =
sqrt((q2[0] - q1[0]) * (q2[0] - q1[0]) +
1223 (q2[1] - q1[1]) * (q2[1] - q1[1]) +
1224 (q2[2] - q1[2]) * (q2[2] - q1[2]));
1230 dxx[0] = r * sinfi0fi; dxx[1] = - r * cosfi0fi; dxx[2] = - r * tanl;
1257 Mvopr(ndim, xx, tt, dxx, tmp, 1);
1259 f = cx * dxx[0] + cy * dxx[1] + cz * dxx[2] + xxtdxx;
1260 if (std::abs(f) < delta)
goto line100;
1264 eval = (1.0 - 0.25 * fact) * std::abs(fst) - std::abs(f);
1265 if (
eval <= 0.) fact *= 0.5;
1269 ddxx[0] = r * cosfi0fi; ddxx[1] = r * sinfi0fi; ddxx[2] = 0.;
1272 Mvopr(ndim, dxx, tt, dxx, tmp, 1);
1274 Mvopr(ndim, xx, tt, ddxx, tmp, 1);
1276 fderiv = cx * ddxx[0] + cy * ddxx[1] + cz * ddxx[2] + dxxtdxx + xxtddxx;
1279 deltafi = f / fderiv;
1280 fi -= fact * deltafi;
1283 if (ntry > ntryMax) {
1293 zh = z0 + dz - r * tanl * fi;
1295 if (zh < zwb) fi_corr = (zwb - zh) / (-r * tanl);
1296 if (zh > zwf) fi_corr = (zwf - zh) / (-r * tanl);
1299 cosfi0fi = cos(fi0 + fi);
1300 sinfi0fi = sin(fi0 + fi);
1302 xh = x0 + dr * cosfi0 + r * (cosfi0 - cosfi0fi);
1303 yh = y0 + dr * sinfi0 + r * (sinfi0 - sinfi0fi);
1304 zh = z0 + dz - r * tanl * fi;
1305 pxh = -pt * sinfi0fi;
1306 pyh = pt * cosfi0fi;
1312 zw = vx * vz * xh + vy * vz * yh + vz * vz * zh + zwb - vz * (vx * xwb + vy * ywb + vz * zwb);
1313 xw = xwb + vx * (zw - zwb) / vz;
1314 yw = ywb + vy * (zw - zwb) / vz;
1316 q2[0] = xw; q2[1] = yw; q2[2] = zw;
1317 q1[0] = xh; q1[1] = yh; q1[2] = zh;
1318 q3[0] = pxh; q3[1] = pyh; q3[2] = pzh;
1324 distance =
sqrt((q2[0] - q1[0]) * (q2[0] - q1[0]) +
1325 (q2[1] - q1[1]) * (q2[1] - q1[1]) +
1326 (q2[2] - q1[2]) * (q2[2] - q1[2]));
1333 const G4double a[3], G4double c[3],
const G4int mode)
1354 for (
int i = 0; i < ndim; ++i) c[i] = 0.;
1356 for (
int i = 0; i < ndim; ++i) tmp[i] = 0.;
1359 for (
int i = 0; i < ndim; ++i) {
1360 for (
int j = 0; j < ndim; ++j) {
1361 c[i] += m[j][i] * a[j];
1365 }
else if (mode == 1) {
1366 for (
int i = 0; i < ndim; ++i) {
1367 for (
int j = 0; j < ndim; ++j) {
1368 tmp[i] += m[j][i] * a[j];
1370 c[0] += b[i] * tmp[i];
1383 std::vector<int> list;
1386 if (abs(i0 - i1) * 2 <
int(nWires)) {
1388 for (
int i = id0; i <= id1; ++i)
1391 for (
int i = id0; i >= id1; i--) {
1397 for (
int i = id0; i >= 0; i--)
1399 for (
int i = nWires - 1; i >= id1; i--)
1402 for (
int i = id0; i < nWires; ++i)
1404 for (
int i = 0; i <= id1; ++i)
1413 const G4ThreeVector posOut, G4ThreeVector& hitPosition, G4ThreeVector& wirePosition)
1418 B2Vector3D tposIn(posIn.x(), posIn.y(), posIn.z());
1419 B2Vector3D tposOut(posOut.x(), posOut.y(), posOut.z());
1424 G4double distance =
CDC::ClosestApproach(tbwp, tfwp, tposIn, tposOut, thitPosition, twirePosition);
1426 hitPosition.setX(thitPosition.
x());
1427 hitPosition.setY(thitPosition.
y());
1428 hitPosition.setZ(thitPosition.
z());
1430 wirePosition.setX(twirePosition.
x());
1431 wirePosition.setY(twirePosition.
y());
1432 wirePosition.setZ(twirePosition.
z());
1450 int nRelationsMinusOne = mcPartToSimHits.
getEntries() - 1;
1452 if (nRelationsMinusOne == -1)
return;
1464 size_t iRelation = 0;
1465 int trackIdOld = INT_MAX;
1470 for (
int it = nRelationsMinusOne; it >= 0; --it) {
1472 size_t nRelatedHits = mcPartToSimHit.
getSize();
1473 if (nRelatedHits > 1) B2FATAL(
"CDCSensitiveDetector::EndOfEvent: MCParticle<-> CDCSimHit relation is not one-to-one !");
1475 unsigned short trackId = mcPartToSimHit.
getFromIndex();
1478 trackIdOld = trackId;
1479 }
else if (weight <= 0. && trackId == trackIdOld) {
1483 trackIdOld = trackId;
1512 for (
int it = 0; it <= nRelationsMinusOne; ++it) {
1556 unsigned short sClayer = sWireId.
getICLayer();
1558 unsigned short sLayer = sWireId.
getILayer();
1559 unsigned short sWire = sWireId.
getIWire();
1562 std::multimap<unsigned short, CDCSimHit*>::iterator pItBegin =
m_hitWithPosWeight.find(sSuperLayer);
1563 std::multimap<unsigned short, CDCSimHit*>::iterator pItEnd =
m_hitWithPosWeight.find(sSuperLayer + 1);
1573 double minDistance2 = DBL_MAX;
1581 for (std::multimap<unsigned short, CDCSimHit*>::iterator pIt = pItBegin; pIt != pItEnd; ++pIt) {
1587 unsigned short neighb =
areNeighbors(sClayer, sSuperLayer, sLayer, sWire, pWireId);
1588 if (neighb != 0 || pWireId == sWireId) {
1589 double distance2 = (pHit->
getPosTrack() - sPos).Mag2();
1590 if (distance2 < minDistance2) {
1592 minDistance2 = distance2;
1614 const signed short iWire = wireId.
getIWire();
1615 const signed short iOtherWire = otherWireId.
getIWire();
1616 const signed short iCLayer = wireId.
getICLayer();
1617 const signed short iOtherCLayer = otherWireId.
getICLayer();
1620 if (iWire == iOtherWire) {
1621 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1622 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1629 if (abs(iLayerDifference) > 1)
return 0;
1631 if (iLayerDifference == 0) {
1635 }
else if (iLayerDifference == -1) {
1640 if (iWire == iOtherWire) {
1644 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1647 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1651 }
else if (iLayerDifference == 1) {
1656 if (iWire == iOtherWire) {
1660 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1663 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1672 unsigned short iWire,
const WireID& otherWireId)
const
1677 const signed short iOtherWire = otherWireId.
getIWire();
1678 const signed short iOtherCLayer = otherWireId.
getICLayer();
1681 if (iWire == iOtherWire) {
1682 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1683 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1689 signed short iLayerDifference = otherWireId.
getILayer() - iLayer;
1690 if (abs(iLayerDifference) > 1)
return 0;
1692 if (iLayerDifference == 0) {
1696 }
else if (iLayerDifference == -1) {
1701 if (iWire == iOtherWire) {
1705 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1708 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1712 }
else if (iLayerDifference == 1) {
1717 if (iWire == iOtherWire) {
1721 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1724 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
DataType y() const
access variable Y (= .at(1) without boundary check)
DataType z() const
access variable Z (= .at(2) without boundary check)
DataType x() const
access variable X (= .at(0) without boundary check)
void setLeftRightPassageRaw(int minusOneOrZeroOrOne)
The method to set new left/right info. for digitization.
void setPosIn(const B2Vector3D &posIn)
The method to set position of pre-step.
void setPosFlag(int zeroOrOne)
The method to set position flag.
B2Vector3D getPosWire() const
The method to get position on wire.
WireID getWireID() const
Getter for WireID object.
void setWireID(int iCLayerID, int iWireID)
Setter for Wire ID.
void setGlobalTime(double globalTime)
The method to set global time.
void setTrackId(int trackId)
The method to set track id.
void setPDGCode(int pdg)
The method to set PDG code.
void setMomentum(const B2Vector3D &momentum)
The method to set momentum.
void setPosWire(const B2Vector3D &posWire)
The method to set position on wire.
void setEnergyDep(double edep)
The method to set deposited energy.
void setPosOut(const B2Vector3D &posOut)
The method to set position of post-step.
void setDriftLength(double driftLength)
The method to set drift length.
void setStepLength(double stepLength)
The method to set step length.
B2Vector3D getPosTrack() const
The method to get position on the track.
B2Vector3D getMomentum() const
The method to get momentum.
void setFlightTime(double flightTime)
The method to set flight time.
void setPosTrack(const B2Vector3D &posTrack)
The method to set position on the track.
void setLeftRightPassage(int minusOneOrZeroOrOne)
The method to set new left/right info. for tracking.
unsigned cellId(unsigned layerId, const B2Vector3D &position) const
The method to get cell id based on given layer id and the position.
void getWireSagEffect(EWirePosition set, unsigned layerID, unsigned cellID, double zw, double &ywb_sag, double &ywf_sag) const
Compute effects of the sense wire sag.
ushort getOffsetOfFirstLayer() const
Get the offset of the first layer.
const B2Vector3D wireForwardPosition(uint layerId, int cellId, EWirePosition set=c_Base) const
Returns the forward position of the input sense wire.
const B2Vector3D wireBackwardPosition(uint layerId, int cellId, EWirePosition set=c_Base) const
Returns the backward position of the input sense wire.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
signed short getShiftInSuperLayer(unsigned short iSuperLayer, unsigned short iLayer) const
Returns shift in the super-layer.
unsigned short getOldLeftRight(const B2Vector3D &posOnWire, const B2Vector3D &posOnTrack, const B2Vector3D &momentum) const
Returns old left/right.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
unsigned short getNewLeftRightRaw(const B2Vector3D &posOnWire, const B2Vector3D &posOnTrack, const B2Vector3D &momentum) const
Returns new left/right_raw.
const signed short CW_NEIGHBOR
Constant for clockwise.
G4double m_thresholdEnergyDeposit
Threshold energy deposit to be stored.
const signed short CCW_NEIGHBOR
Constant for counterclockwise.
CDCGeometryPar * m_cdcgp
Pointer to CDCGeometryPar object.
const signed short CW_IN_NEIGHBOR
Constant for clockwise inwards.
std::multimap< unsigned short, CDCSimHit * > m_hitWithPosWeight
Map containing hits with positive weight.
G4double m_minTrackLength
Min.
const signed short CCW_OUT_NEIGHBOR
Constant for counterclockwise outwards.
G4bool m_wireSag
Switch to activate wire sag effect.
StoreArray< CDCSimHit > m_CDCSimHits
CDC simulation hits.
G4double m_thresholdKineticEnergy
Threshold kinetic energy to be stored.
const signed short CW_OUT_NEIGHBOR
Constant for clockwise outwards.
const signed short CCW
Constant for counterclockwise orientation.
const signed short CCW_IN_NEIGHBOR
Constant for counterclockwise inwards.
G4bool m_modifiedLeftRightFlag
Switch for left/right flag modified for tracking.
G4int m_magneticField
Magnetic field is on or off.
int m_hitNumber
The current number of created hits in an event.
G4double m_brot[3][3]
a rotation matrix.
std::vector< CDCSimHit * > m_hitWithNegWeight
Vector containing hits with negative weight.
G4int m_nonUniformField
Magnetic field is uniform or non-uniform.
StoreArray< MCParticle > m_MCParticles
MC particles.
const signed short CW
Constant for clockwise orientation.
The Class for CDC Simulation Control Parameters.
bool getModLeftRightFlag() const
Get modified left/right flag.
double getMinTrackLength() const
Get minimum track length.
double getThresholdEnergyDeposit() const
Get threshold for Energy Deposit;.
static CDCSimControlPar & getInstance()
Static method to get a reference to the CDCSimControlPar instance.
bool getWireSag() const
Get wiresag flag.
void ignoreErrorMatrix(void)
Unsets error matrix.
const HepPoint3D & pivot(void) const
returns pivot position.
double bFieldZ(double bz)
Sets/returns z componet of the magnetic field.
const HepVector & a(void) const
Returns helix parameters.
Hep3Vector momentum(double dPhi=0.) const
returns momentum vector after rotating angle dPhi in phi direction.
HepPoint3D x(double dPhi=0.) const
returns position after rotating angle dPhi in phi direction.
This class provides a set of constants for the framework.
Low-level class to create/modify relations between StoreArrays.
int getEntries() const
Get the number of elements.
void add(index_type from, index_type to, weight_type weight=1.0)
Add a new element to the relation.
Class to store a single element of a relation.
index_type getFromIndex() const
Get index we point from.
index_type getToIndex(size_t n=0) const
Get nth index we point to.
void setToIndex(index_type to, weight_type weight=1.0)
Set index we point to, converts relation to 1:1 and discards all existing to-indices.
float weight_type
type used for weights.
size_t getSize() const
Get number of indices we points to.
weight_type getWeight(size_t n=0) const
Get nth weight we point to.
static void registerMCParticleRelation(const std::string &name, RelationArray::EConsolidationAction ignoreAction=RelationArray::c_negativeWeight)
Register an relation involving MCParticles.
static Payload getInfo(Carrier &obj)
Static function to just return UserInformation attached to the obj of type Carrier.
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Class to identify a wire inside the CDC.
unsigned short getICLayer() const
Getter for continuous layer numbering.
unsigned short getIWire() const
Getter for wire within the layer.
unsigned short getISuperLayer() const
Getter for Super-Layer.
unsigned short getILayer() const
Getter for layer within the Super-Layer.
bool step(G4Step *aStep, G4TouchableHistory *history) override
Process each step and calculate variables defined in CDCB4VHit.
void setModifiedLeftRightFlag()
set left/right flag modified for tracking
unsigned short areNeighbors(const WireID &wireId, const WireID &otherWireId) const
Check if neighboring cell in the same super-layer; essentially a copy from cdcLocalTracking/mclookup.
void EndOfEvent(G4HCofThisEvent *) override
Do what you want to do at the beginning of each event (why this is not called ?)
void for_Rotat(const G4double bfld[3])
Calculates a rotation matrix.
void HELWIR(const G4double xwb4, const G4double ywb4, const G4double zwb4, const G4double xwf4, const G4double ywf4, const G4double zwf4, const G4double xp, const G4double yp, const G4double zp, const G4double px, const G4double py, const G4double pz, const G4double B_kG[3], const G4double charge, const G4int ntryMax, G4double &distance, G4double q2[3], G4double q1[3], G4double q3[3], G4int &ntry)
Calculate closest points between helix and wire.
CDCSensitiveDetector(G4String name, G4double thresholdEnergyDeposit, G4double thresholdKineticEnergy)
Constructor.
void CellBound(const G4int layerId, const G4int ic1, const G4int ic2, const G4double venter[6], const G4double vexit[6], const G4double s1, const G4double s2, G4double xint[6], G4double &sint, G4int &iflag)
Calculate intersection of track with cell boundary.
void Rotat(G4double &x, G4double &y, G4double &z, const int mode)
Translation method.
void saveSimHit(const G4int layerId, const G4int wireId, const G4int trackID, const G4int pid, const G4double distance, const G4double tof, const G4double edep, const G4double stepLength, const G4ThreeVector &mom, const G4ThreeVector &posW, const G4ThreeVector &posIn, const G4ThreeVector &posOut, const G4ThreeVector &posTrack, const G4int lr, const G4int NewLrRaw, const G4int NewLr, const G4double speed, const G4double hitWeight)
Save CDCSimHit into datastore.
void Mvopr(const G4int ndim, const G4double b[3], const G4double m[3][3], const G4double a[3], G4double c[3], const G4int mode)
Calculate the result of a matrix times vector.
void Initialize(G4HCofThisEvent *) override
Register CDC hits collection into G4HCofThisEvent.
G4double ClosestApproach(G4ThreeVector bwp, G4ThreeVector fwp, G4ThreeVector posIn, G4ThreeVector posOut, G4ThreeVector &hitPosition, G4ThreeVector &wirePosition)
Assume line track to calculate distance between track and wire (drift length).
void GCUBS(const G4double x, const G4double y, const G4double d1, const G4double d2, G4double a[4])
void reAssignLeftRightInfo()
Re-assign left/right info.
std::vector< int > WireId_in_hit_order(int id0, int id1, int nWires)
Sort wire id.
double sqrt(double a)
sqrt for double
T dot(GeneralVector< T > a, GeneralVector< T > b)
dot product of two general vectors
double eval(const std::vector< double > &spl, const std::vector< double > &vals, double x)
Evaluate spline (zero order or first order) in point x.
double ClosestApproach(const B2Vector3D &bwp, const B2Vector3D &fwp, const B2Vector3D &posIn, const B2Vector3D &posOut, B2Vector3D &hitPosition, B2Vector3D &wirePosition)
Returns a closest distance between a track and a wire.
Abstract base class for different kinds of events.