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>
19 #include "G4TransportationManager.hh"
21 #include "G4FieldManager.hh"
23 #include "CLHEP/Geometry/Vector3D.h"
24 #include "CLHEP/Geometry/Point3D.h"
28 #ifndef ENABLE_BACKWARDS_COMPATIBILITY
31 #ifndef ENABLE_BACKWARDS_COMPATIBILITY
32 typedef 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();
200 B2DEBUG(150,
"LayerID in continuous counting method: " << layerId);
204 if ((charge == 0.) && (abs(pid) != 99666))
return false;
207 TVector3 tposIn(posIn.x() / CLHEP::cm, posIn.y() / CLHEP::cm, posIn.z() / CLHEP::cm);
208 TVector3 tposOut(posOut.x() / CLHEP::cm, posOut.y() / CLHEP::cm, posOut.z() / CLHEP::cm);
211 #if defined(CDC_DEBUG)
212 std::cout <<
"edep= " << edep << std::endl;
213 std::cout <<
"idIn,idOut= " << idIn <<
" " << idOut << std::endl;
219 const G4double s_in_layer = stepLength / CLHEP::cm;
220 G4double xint[6] = {0};
222 const G4ThreeVector momOut(out.GetMomentum().x(), out.GetMomentum().y(),
223 out.GetMomentum().z());
224 const G4double speedIn = in.GetVelocity();
225 const G4double speedOut = out.GetVelocity();
226 const G4double speed = 0.5 * (speedIn + speedOut);
227 const G4double speedInCmPerNs = speed / CLHEP::cm;
229 const unsigned int nWires = wires.size();
230 G4double tofBefore = in.GetGlobalTime();
231 G4double kinEnergyBefore = in.GetKineticEnergy();
232 G4double momBefore = momIn.mag();
233 const G4double eLoss = kinEnergyBefore - out.GetKineticEnergy();
234 const G4double mass = t.GetDefinition()->GetPDGMass();
235 #if defined(CDC_DEBUG)
236 std::cout <<
"momBefore = " << momBefore << std::endl;
237 std::cout <<
"momIn = " << momIn.x() <<
" " << momIn.y() <<
" " << momIn.z() << std::endl;
238 std::cout <<
"momOut= " << momOut.x() <<
" " << momOut.y() <<
" " << momOut.z() << std::endl;
239 std::cout <<
"speedIn,speedOut= " << speedIn <<
" " << speedOut << std::endl;
240 std::cout <<
" speedInCmPerNs= " << speedInCmPerNs << std::endl;
241 std::cout <<
"tofBefore= " << tofBefore << std::endl;
244 const G4Field* field = G4TransportationManager::GetTransportationManager()->GetFieldManager()->GetDetectorField();
246 for (
unsigned i = 0; i < nWires; ++i) {
247 #if defined(CDC_DEBUG)
248 std::cout <<
"============ i,wires[i]= " << i <<
" " << wires[i] << std::endl;
251 const G4double pos[3] = {posIn.x(), posIn.y(), posIn.z()};
253 field->GetFieldValue(pos, Bfield);
255 Bfield[2] == 0.) ?
false :
true;
256 #if defined(CDC_DEBUG)
257 std::cout <<
"Bfield= " << Bfield[0] <<
" " << Bfield[1] <<
" " << Bfield[2] << std::endl;
262 G4ThreeVector posW(0, 0, 0);
270 const HepPoint3D fwd(tfw3v.x(), tfw3v.y(), tfw3v.z());
271 const HepPoint3D bck(tbw3v.x(), tbw3v.y(), tbw3v.z());
278 if (Bfield[0] == 0. && Bfield[1] == 0. &&
281 const G4double B_kG[3] = {Bfield[0] / CLHEP::kilogauss,
282 Bfield[1] / CLHEP::kilogauss,
283 Bfield[2] / CLHEP::kilogauss
285 #if defined(CDC_DEBUG)
286 std::cout <<
"B_kG= " << B_kG[0] <<
" " << B_kG[1] <<
" " << B_kG[2] << std::endl;
290 const HepPoint3D x(pos[0] / CLHEP::cm, pos[1] / CLHEP::cm, pos[2] / CLHEP::cm);
291 const HepVector3D p(momIn.x() / CLHEP::GeV, momIn.y() / CLHEP::GeV, momIn.z() / CLHEP::GeV);
292 Helix tmp(x, p, charge);
293 tmp.bFieldZ(B_kG[2]);
294 tmp.ignoreErrorMatrix();
304 const HepVector3D wire = fwd - bck;
306 (x.z() - bck.z()) / wire.z() * wire + bck;
308 tryp = (tmp.x(0.).z() - bck.z()) / wire.z() * wire + bck;
310 tryp = (tmp.x(0.).z() - bck.z()) / wire.z() * wire + bck;
313 distance = std::abs(tmp.a()[0]);
320 pOnTrack = tmp.momentum(0.);
323 const G4double xwb(bck.x()), ywb(bck.y()), zwb(bck.z());
324 const G4double xwf(fwd.x()), ywf(fwd.y()), zwf(fwd.z());
325 const G4double xp(onTrack.x()), yp(onTrack.y()), zp(onTrack.z());
326 const G4double px(pOnTrack.x()), py(pOnTrack.y()), pz(pOnTrack.z());
327 G4double q2[3] = {0.}, q1[3] = {0.}, q3[3] = {0.};
328 const G4int ntryMax(50);
331 HELWIR(xwb, ywb, zwb, xwf, ywf, zwf,
332 xp, yp, zp, px, py, pz,
333 B_kG, charge, ntryMax, dist, q2, q1, q3, ntry);
335 #if defined(CDC_DEBUG)
336 std::cout <<
"ntry= " << ntry << std::endl;
337 std::cout <<
"bf distance= " << distance << std::endl;
338 std::cout <<
"onTrack = " << onTrack << std::endl;
339 std::cout <<
"posW = " << posW << std::endl;
341 if (ntry <= ntryMax) {
343 G4double ywb_sag, ywf_sag;
345 HELWIR(xwb, ywb_sag, zwb, xwf, ywf_sag, zwf,
346 xp, yp, zp, px, py, pz,
347 B_kG, charge, ntryMax, dist, q2, q1, q3, ntry);
349 if (ntry <= ntryMax) {
357 pOnTrack.setX(q3[0]);
358 pOnTrack.setY(q3[1]);
359 pOnTrack.setZ(q3[2]);
361 #if defined(CDC_DEBUG)
362 std::cout <<
" " << std::endl;
363 std::cout <<
"helix distance= " << distance << std::endl;
364 std::cout <<
"onTrack = " << onTrack << std::endl;
365 std::cout <<
"posW = " << posW << std::endl;
366 std::cout <<
"pOnTrack= " << pOnTrack << std::endl;
367 G4ThreeVector bwp(bck.x(), bck.y(), bck.z());
368 G4ThreeVector fwp(fwd.x(), fwd.y(), fwd.z());
369 G4ThreeVector hitPosition, wirePosition;
370 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
371 hitPosition, wirePosition);
373 G4double ywb_sag, ywf_sag;
377 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
378 hitPosition, wirePosition);
380 std::cout <<
"line distance= " << distance << std::endl;
381 std::cout <<
"onTrack= " << hitPosition.x() <<
" " << hitPosition.y() <<
" " << hitPosition.z() << std::endl;
382 std::cout <<
"posW = " << wirePosition.x() <<
" " << wirePosition.y() <<
" " << wirePosition.z() << std::endl;
387 G4ThreeVector bwp(bck.x(), bck.y(), bck.z());
388 G4ThreeVector fwp(fwd.x(), fwd.y(), fwd.z());
389 G4ThreeVector hitPosition, wirePosition;
390 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
391 hitPosition, wirePosition);
393 G4double ywb_sag, ywf_sag;
397 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
398 hitPosition, wirePosition);
401 onTrack.setX(hitPosition.x());
402 onTrack.setY(hitPosition.y());
403 onTrack.setZ(hitPosition.z());
404 posW.setX(wirePosition.x());
405 posW.setY(wirePosition.y());
406 posW.setZ(wirePosition.z());
408 pOnTrack.setX(0.5 * (momIn.x() + momOut.x()) / CLHEP::GeV);
409 pOnTrack.setY(0.5 * (momIn.y() + momOut.y()) / CLHEP::GeV);
410 pOnTrack.setZ(0.5 * (momIn.z() + momOut.z()) / CLHEP::GeV);
413 #if defined(CDC_DEBUG)
414 std::cout <<
"af distance= " << distance << std::endl;
415 std::cout <<
"onTrack = " << onTrack << std::endl;
416 std::cout <<
"posW = " << posW << std::endl;
417 std::cout <<
"pOnTrack = " << pOnTrack << std::endl;
418 if (distance > 2.4) {
419 std::cout <<
"toolargedriftl" << std::endl;
422 distance *= CLHEP::cm; onTrack *= CLHEP::cm; posW *= CLHEP::cm;
423 pOnTrack *= CLHEP::GeV;
425 G4ThreeVector posTrack(onTrack.x(), onTrack.y(), onTrack.z());
426 G4ThreeVector mom(pOnTrack.x(), pOnTrack.y(), pOnTrack.z());
428 const TVector3 tPosW(posW.x(), posW.y(), posW.z());
429 const TVector3 tPosTrack(posTrack.x(), posTrack.y(), posTrack.z());
430 const TVector3 tMom(mom.x(), mom.y(), mom.z());
436 G4int newLr = newLrRaw;
441 saveSimHit(layerId, wires[i], trackID, pid, distance, tofBefore, edep, s_in_layer * CLHEP::cm, pOnTrack, posW, posIn, posOut,
442 posTrack, lr, newLrRaw, newLr, speed, hitWeight);
443 #if defined(CDC_DEBUG)
444 std::cout <<
"saveSimHit" << std::endl;
445 std::cout <<
"momIn = " << momIn << std::endl;
446 std::cout <<
"pOnTrack = " << pOnTrack << std::endl;
451 G4int cel1 = wires[i] + 1;
453 if (i + 1 <= nWires - 1) {
454 cel2 = wires[i + 1] + 1;
456 const G4double s2 = t.GetTrackLength() / CLHEP::cm;
457 G4double s1 = (s2 - s_in_layer);
458 G4ThreeVector din = momIn;
459 if (din.mag() != 0.) din /= momIn.mag();
461 G4double vent[6] = {posIn.x() / CLHEP::cm, posIn.y() / CLHEP::cm, posIn.z() / CLHEP::cm, din.x(), din.y(), din.z()};
463 G4ThreeVector dot(momOut.x(), momOut.y(), momOut.z());
464 if (dot.mag() != 0.) {
471 G4double vext[6] = {posOut.x() / CLHEP::cm, posOut.y() / CLHEP::cm, posOut.z() / CLHEP::cm, dot.x(), dot.y(), dot.z()};
474 for (
int j = 0; j < 6; ++j) vent[j] = xint[j];
480 G4double edep_in_cell(0.);
481 G4double eLossInCell(0.);
484 #if defined(CDC_DEBUG)
485 std::cout <<
"layerId,cel1,cel2= " << layerId <<
" " << cel1 <<
" " << cel2 << std::endl;
486 std::cout <<
"vent= " << vent[0] <<
" " << vent[1] <<
" " << vent[2] <<
" " << vent[3] <<
" " << vent[4] <<
" " << vent[5] <<
488 std::cout <<
"vext= " << vext[0] <<
" " << vext[1] <<
" " << vext[2] <<
" " << vext[3] <<
" " << vext[4] <<
" " << vext[5] <<
490 std::cout <<
"s1,s2,ic= " << s1 <<
" " << s2 <<
" " << ic << std::endl;
492 CellBound(layerId, cel1, cel2, vent, vext, s1, s2, xint, sint, flag);
493 #if defined(CDC_DEBUG)
494 std::cout <<
"flag,sint= " << flag <<
" " << sint << std::endl;
495 std::cout <<
"xint= " << xint[0] <<
" " << xint[1] <<
" " << xint[2] <<
" " << xint[3] <<
" " << xint[4] <<
" " << xint[5] <<
499 const G4double test = (sint - s1) / s_in_layer;
500 if (test < 0. || test > 1.) {
501 B2WARNING(
"CDCSensitiveDetector: Strange path length: " <<
"s1= " << s1 <<
" sint= " << sint <<
" s_in_layer= " << s_in_layer <<
504 edep_in_cell = edep * std::abs((sint - s1)) / s_in_layer;
506 const G4ThreeVector x_In(vent[0]*CLHEP::cm, vent[1]*CLHEP::cm, vent[2]*CLHEP::cm);
507 const G4ThreeVector x_Out(xint[0]*CLHEP::cm, xint[1]*CLHEP::cm, xint[2]*CLHEP::cm);
508 const G4ThreeVector p_In(momBefore * vent[3], momBefore * vent[4], momBefore * vent[5]);
511 saveSimHit(layerId, wires[i], trackID, pid, distance, tofBefore, edep_in_cell, std::abs((sint - s1)) * CLHEP::cm, pOnTrack, posW,
513 posTrack, lr, newLrRaw, newLr, speed, hitWeight);
514 #if defined(CDC_DEBUG)
515 std::cout <<
"saveSimHit" << std::endl;
516 std::cout <<
"p_In = " << p_In << std::endl;
517 std::cout <<
"pOnTrack= " << pOnTrack << std::endl;
519 tofBefore += (sint - s1) / speedInCmPerNs;
520 eLossInCell = eLoss * (sint - s1) / s_in_layer;
521 kinEnergyBefore -= eLossInCell;
522 if (kinEnergyBefore >= 0.) {
523 momBefore = sqrt(kinEnergyBefore * (kinEnergyBefore + 2.*mass));
525 B2WARNING(
"CDCSensitiveDetector: Kinetic Energy < 0.");
531 const G4double test = (s2 - sint) / s_in_layer;
532 if (test < 0. || test > 1.) {
533 B2WARNING(
"CDCSensitiveDetector: Strange path length: " <<
"s2= " << s2 <<
" sint= " << sint <<
" s_in_layer= " << s_in_layer <<
536 edep_in_cell = edep * std::abs((s2 - sint)) / s_in_layer;
538 const G4ThreeVector x_In(vent[0]*CLHEP::cm, vent[1]*CLHEP::cm, vent[2]*CLHEP::cm);
539 const G4ThreeVector p_In(momBefore * vent[3], momBefore * vent[4], momBefore * vent[5]);
542 saveSimHit(layerId, wires[i], trackID, pid, distance, tofBefore, edep_in_cell, std::abs((s2 - sint)) * CLHEP::cm, pOnTrack, posW,
544 posOut, posTrack, lr, newLrRaw, newLr, speed, hitWeight);
545 #if defined(CDC_DEBUG)
546 std::cout <<
"saveSimHit" << std::endl;
547 std::cout <<
"p_In = " << p_In << std::endl;
548 std::cout <<
"pOnTrack= " << pOnTrack << std::endl;
586 const G4double distance,
589 const G4double stepLength,
590 const G4ThreeVector& mom,
591 const G4ThreeVector& posW,
592 const G4ThreeVector& posIn,
593 const G4ThreeVector& posOut,
594 const G4ThreeVector& posTrack,
596 const G4int newLrRaw,
598 const G4double speed,
599 const G4double hitWeight)
607 const G4double sign = (posTrack - posIn).dot(mom) < 0. ? -1. : 1.;
608 const G4double CorrectTof = tof + sign * (posTrack - posIn).mag() / speed;
610 #if defined(CDC_DEBUG)
611 std::cout <<
"posIn= " << posIn.x() <<
" " << posIn.y() <<
" " << posIn.z() << std::endl;
612 std::cout <<
"posOut= " << posOut.x() <<
" " << posOut.y() <<
" " << posOut.z() << std::endl;
613 std::cout <<
"posTrack= " << posTrack.x() <<
" " << posTrack.y() <<
" " << posTrack.z() << std::endl;
614 std::cout <<
"posW= " << posW.x() <<
" " << posW.y() <<
" " << posW.z() << std::endl;
615 std::cout <<
"tof = " << tof << std::endl;
616 std::cout <<
"deltaTof = " << (posTrack - posIn).mag() / speed << std::endl;
617 std::cout <<
"CorrectTof= " << CorrectTof << std::endl;
618 if (CorrectTof > 95) {
619 std::cout <<
"toolargecorrecttof" << std::endl;
637 TVector3 momentum(mom.getX() / CLHEP::GeV, mom.getY() / CLHEP::GeV, mom.getZ() / CLHEP::GeV);
639 TVector3 posWire(posW.getX() / CLHEP::cm, posW.getY() / CLHEP::cm, posW.getZ() / CLHEP::cm);
641 TVector3 positionIn(posIn.getX() / CLHEP::cm, posIn.getY() / CLHEP::cm, posIn.getZ() / CLHEP::cm);
643 TVector3 positionOut(posOut.getX() / CLHEP::cm, posOut.getY() / CLHEP::cm, posOut.getZ() / CLHEP::cm);
645 TVector3 positionTrack(posTrack.getX() / CLHEP::cm, posTrack.getY() / CLHEP::cm, posTrack.getZ() / CLHEP::cm);
650 #if defined(CDC_DEBUG)
651 std::cout <<
"sensitived,oldlr,newlrRaw,newlr= " << lr <<
" " << newLrRaw <<
" " << newLr << std::endl;
688 const G4double venter[6],
689 const G4double vexit[6],
690 const G4double s1,
const G4double s2,
692 G4double& sint, G4int& iflag)
722 B2ERROR(
"CDCSensitiveDetector: s1(=" << s1 <<
") > s2(=" << s2 <<
")");
724 if (std::abs(ic1 - ic2) != 1) {
725 if (ic1 == 1 && ic2 == div) {
726 }
else if (ic1 == div && ic2 == 1) {
728 B2ERROR(
"CDCSensitiveDetector: |ic1 - ic2| != 1 in CellBound; " <<
"ic1=" << ic1 <<
" " <<
"ic2=" << ic2);
752 G4double xx1[6], xx2[6];
753 for (
int i = 0; i < 6; ++i) {
759 G4double psi = double(ic2 - ic1) * CLHEP::pi / div;
760 if (ic1 == 1 && ic2 == div) {
761 psi = -CLHEP::pi / div;
762 }
else if (ic1 == div && ic2 == 1) {
763 psi = CLHEP::pi / div;
765 G4double cospsi = cos(psi);
766 G4double sinpsi = sin(psi);
768 G4double xfwb = cospsi * xwb - sinpsi * ywb;
769 G4double yfwb = sinpsi * xwb + cospsi * ywb;
770 G4double xfwf = cospsi * xwf - sinpsi * ywf;
771 G4double yfwf = sinpsi * xwf + cospsi * ywf;
776 G4double vx = xfwf - xfwb;
777 G4double vy = yfwf - yfwb;
778 G4double vz = zfwf - zfwb;
779 G4double vv = sqrt(vx * vx + vy * vy + vz * vz);
780 vx /= vv; vy /= vv; vz /= vv;
783 G4double shiftx = (xx1[0] + xx2[0]) * 0.5;
784 G4double shifty = (xx1[1] + xx2[1]) * 0.5;
785 G4double shiftz = (xx1[2] + xx2[2]) * 0.5;
786 G4double shifts = (s1 + s2) * 0.5;
787 G4double xshft = xx1[0] - shiftx;
788 G4double yshft = xx1[1] - shifty;
789 G4double zshft = xx1[2] - shiftz;
790 G4double sshft = s1 - shifts;
793 G4double pabs1 = sqrt(xx1[3] * xx1[3] + xx1[4] * xx1[4] + xx1[5] * xx1[5]);
794 G4double pabs2 = sqrt(xx2[3] * xx2[3] + xx2[4] * xx2[4] + xx2[5] * xx2[5]);
797 G4double a[4] = {0.}, b[4] = {0.}, c[4] = {0.};
800 GCUBS(sshft, xshft, xx1[3] / pabs1, xx2[3] / pabs2, a);
801 GCUBS(sshft, yshft, xx1[4] / pabs1, xx2[4] / pabs2, b);
802 GCUBS(sshft, zshft, xx1[5] / pabs1, xx2[5] / pabs2, c);
808 a[1] = xshft / sshft;
809 b[1] = yshft / sshft;
810 c[1] = zshft / sshft;
814 G4double stry(0.), xtry(0.), ytry(0.), ztry(0.);
815 G4double beta(0.), xfw(0.), yfw(0.);
816 G4double sphi(0.), cphi(0.), dphil(0.), dphih(0.);
817 const G4int maxTrials = 100;
818 const G4double eps = 5.e-4;
820 G4double sh = -sshft;
825 xtry = shiftx + a[0] + stry * (a[1] + stry * (a[2] + stry * a[3]));
826 ytry = shifty + b[0] + stry * (b[1] + stry * (b[2] + stry * b[3]));
827 ztry = shiftz + c[0] + stry * (c[1] + stry * (c[2] + stry * c[3]));
828 beta = (ztry - zfwb) / vz;
829 xfw = xfwb + beta * vx;
830 yfw = yfwb + beta * vy;
831 sphi = (xtry * yfw - ytry * xfw);
832 cphi = (xtry * xfw + ytry * yfw);
833 dphil = atan2(sphi, cphi);
837 while (((sh - sl) > eps) && (i < maxTrials)) {
838 stry = 0.5 * (sl + sh);
839 xtry = shiftx + a[0] + stry * (a[1] + stry * (a[2] + stry * a[3]));
840 ytry = shifty + b[0] + stry * (b[1] + stry * (b[2] + stry * b[3]));
841 ztry = shiftz + c[0] + stry * (c[1] + stry * (c[2] + stry * c[3]));
842 beta = (ztry - zfwb) / vz;
843 xfw = xfwb + beta * vx;
844 yfw = yfwb + beta * vy;
846 sphi = (xtry * yfw - ytry * xfw);
847 cphi = (xtry * xfw + ytry * yfw);
848 dphih = atan2(sphi, cphi);
850 if (dphil * dphih > 0.) {
859 if (i >= maxTrials - 1) {
861 B2WARNING(
"CDCSensitiveDetector: No intersection ?");
893 xint[0] = a[0] + sint * (a[1] + sint * (a[2] + sint * a[3]));
894 xint[1] = b[0] + sint * (b[1] + sint * (b[2] + sint * b[3]));
895 xint[2] = c[0] + sint * (c[1] + sint * (c[2] + sint * c[3]));
896 xint[3] = a[1] + sint * (2. * a[2] + 3. * sint * a[3]);
897 xint[4] = b[1] + sint * (2. * b[2] + 3. * sint * b[3]);
898 xint[5] = c[1] + sint * (2. * c[2] + 3. * sint * c[3]);
924 G4double p = sqrt(xint[3] * xint[3] + xint[4] * xint[4] + xint[5] * xint[5]);
925 xint[3] /= p; xint[4] /= p; xint[5] /= p;
950 if (x == 0.)
goto L10;
952 fact = (d1 - d2) * 0.25;
953 a[0] = - 1. * fact * x;
955 a[1] = (6. * y - (d1 + d2) * x) / (4. * x);
956 a[3] = ((d1 + d2) * x - 2.*y) / (4.*x * x * x);
982 G4double bxz, bfield;
983 bxz = bx * bx + bz * bz;
984 bfield = bxz + by * by;
986 bfield = sqrt(bfield);
991 m_brot[0][1] = -by * bx / bxz / bfield;
992 m_brot[1][1] = bxz / bfield;
993 m_brot[2][1] = -by * bz / bxz / bfield;
994 m_brot[0][2] = bx / bfield;
995 m_brot[1][2] = by / bfield;
996 m_brot[2][2] = bz / bfield;
1013 G4double x0(x), y0(y), z0(z);
1019 }
else if (mode == -1) {
1040 G4double x0(x[0]), y0(x[1]), z0(x[2]);
1046 }
else if (mode == -1) {
1059 const G4double zwb4,
1060 const G4double xwf4,
const G4double ywf4,
1061 const G4double zwf4,
1062 const G4double xp,
const G4double yp,
1064 const G4double px,
const G4double py,
1066 const G4double B_kG[3],
1067 const G4double charge,
const G4int ntryMax,
1069 G4double q2[3], G4double q1[3],
1095 const G4int ndim = 3;
1096 const G4double delta = 1.e-5;
1099 G4double xwb, ywb, zwb, xwf, ywf, zwf;
1100 G4double xw, yw, zw, xh, yh, zh, pxh, pyh, pzh;
1101 G4double fi, fi_corr;
1103 G4double dr, fi0, cpa, dz, tanl;
1104 G4double x0, y0, z0;
1109 G4double sinfi0, cosfi0, sinfi0fi, cosfi0fi;
1111 G4double vx, vy, vz, vv, cx, cy, cz, tt[3][3];
1114 G4double xx[3], dxx[3], ddxx[3], pp[3];
1115 G4double xxtdxx, dxxtdxx, xxtddxx;
1119 G4double f, fderiv, deltafi, fact,
eval;
1120 G4double dx1, dy1, dx2, dy2, crs, dot;
1125 xwb = xwb4; ywb = ywb4; zwb = zwb4;
1126 xwf = xwf4; ywf = ywf4; zwf = zwf4;
1128 G4double xxx(xp), yyy(yp), zzz(zp);
1129 G4double pxx(px), pyy(py), pzz(pz);
1132 Rotat(xwb, ywb, zwb, 1);
1133 Rotat(xwf, ywf, zwf, 1);
1134 Rotat(xxx, yyy, zzz, 1);
1135 Rotat(pxx, pyy, pzz, 1);
1137 G4double a[8] = {0.};
1138 G4double pt = sqrt(pxx * pxx + pyy * pyy);
1139 a[1] = atan2(-pxx, pyy);
1142 a[5] = xxx; a[6] = yyy; a[7] = zzz;
1145 vx = xwf - xwb; vy = ywf - ywb; vz = zwf - zwb;
1146 vv = sqrt(vx * vx + vy * vy + vz * vz);
1147 vx /= vv; vy /= vv; vz /= vv;
1151 if (vx == 0. && vy == 0.) iflg = 1;
1156 cx = xwb - vx * (vx * xwb + vy * ywb + vz * zwb);
1157 cy = ywb - vy * (vx * xwb + vy * ywb + vz * zwb);
1158 cz = zwb - vz * (vx * xwb + vy * ywb + vz * zwb);
1161 tt[0][0] = vx * vx - 1.; tt[1][0] = vx * vy; tt[2][0] = vx * vz;
1162 tt[0][1] = vy * vx; tt[1][1] = vy * vy - 1.; tt[2][1] = vy * vz;
1163 tt[0][2] = vz * vx; tt[1][2] = vz * vy; tt[2][2] = vz * vz - 1.;
1166 dr = a[0]; fi0 = a[1]; cpa = a[2];
1167 dz = a[3]; tanl = a[4];
1168 x0 = a[5]; y0 = a[6]; z0 = a[7];
1177 G4double bfield = sqrt(B_kG[0] * B_kG[0] +
1180 G4double alpha = 1.e4 / 2.99792458 / bfield;
1184 xc = x0 + (dr + r) * cosfi0;
1185 yc = y0 + (dr + r) * sinfi0;
1190 crs = dx1 * dy2 - dy1 * dx2;
1191 dot = dx1 * dx2 + dy1 * dy2;
1192 fi = atan2(crs, dot);
1199 cosfi0fi = cos(fi0 + fi);
1200 sinfi0fi = sin(fi0 + fi);
1203 xx[0] = x0 + dr * cosfi0 + r * (cosfi0 - cosfi0fi);
1204 xx[1] = y0 + dr * sinfi0 + r * (sinfi0 - sinfi0fi);
1205 xx[2] = z0 + dz - r * tanl * fi;
1206 pp[0] = -pt * sinfi0fi;
1207 pp[1] = pt * cosfi0fi;
1211 q2[0] = xwb; q2[1] = ywb; q2[2] = xx[2];
1212 q1[0] = xx[0]; q1[1] = xx[1]; q1[2] = xx[2];
1213 q3[0] = pp[0]; q3[1] = pp[1]; q3[2] = pp[2];
1218 distance = sqrt((q2[0] - q1[0]) * (q2[0] - q1[0]) +
1219 (q2[1] - q1[1]) * (q2[1] - q1[1]) +
1220 (q2[2] - q1[2]) * (q2[2] - q1[2]));
1226 dxx[0] = r * sinfi0fi; dxx[1] = - r * cosfi0fi; dxx[2] = - r * tanl;
1253 Mvopr(ndim, xx, tt, dxx, tmp, 1);
1255 f = cx * dxx[0] + cy * dxx[1] + cz * dxx[2] + xxtdxx;
1256 if (std::abs(f) < delta)
goto line100;
1260 eval = (1.0 - 0.25 * fact) * std::abs(fst) - std::abs(f);
1261 if (
eval <= 0.) fact *= 0.5;
1265 ddxx[0] = r * cosfi0fi; ddxx[1] = r * sinfi0fi; ddxx[2] = 0.;
1268 Mvopr(ndim, dxx, tt, dxx, tmp, 1);
1270 Mvopr(ndim, xx, tt, ddxx, tmp, 1);
1272 fderiv = cx * ddxx[0] + cy * ddxx[1] + cz * ddxx[2] + dxxtdxx + xxtddxx;
1275 deltafi = f / fderiv;
1276 fi -= fact * deltafi;
1279 if (ntry > ntryMax) {
1289 zh = z0 + dz - r * tanl * fi;
1291 if (zh < zwb) fi_corr = (zwb - zh) / (-r * tanl);
1292 if (zh > zwf) fi_corr = (zwf - zh) / (-r * tanl);
1295 cosfi0fi = cos(fi0 + fi);
1296 sinfi0fi = sin(fi0 + fi);
1298 xh = x0 + dr * cosfi0 + r * (cosfi0 - cosfi0fi);
1299 yh = y0 + dr * sinfi0 + r * (sinfi0 - sinfi0fi);
1300 zh = z0 + dz - r * tanl * fi;
1301 pxh = -pt * sinfi0fi;
1302 pyh = pt * cosfi0fi;
1308 zw = vx * vz * xh + vy * vz * yh + vz * vz * zh + zwb - vz * (vx * xwb + vy * ywb + vz * zwb);
1309 xw = xwb + vx * (zw - zwb) / vz;
1310 yw = ywb + vy * (zw - zwb) / vz;
1312 q2[0] = xw; q2[1] = yw; q2[2] = zw;
1313 q1[0] = xh; q1[1] = yh; q1[2] = zh;
1314 q3[0] = pxh; q3[1] = pyh; q3[2] = pzh;
1320 distance = sqrt((q2[0] - q1[0]) * (q2[0] - q1[0]) +
1321 (q2[1] - q1[1]) * (q2[1] - q1[1]) +
1322 (q2[2] - q1[2]) * (q2[2] - q1[2]));
1329 const G4double a[3], G4double c[3],
const G4int mode)
1350 for (
int i = 0; i < ndim; ++i) c[i] = 0.;
1352 for (
int i = 0; i < ndim; ++i) tmp[i] = 0.;
1355 for (
int i = 0; i < ndim; ++i) {
1356 for (
int j = 0; j < ndim; ++j) {
1357 c[i] += m[j][i] * a[j];
1361 }
else if (mode == 1) {
1362 for (
int i = 0; i < ndim; ++i) {
1363 for (
int j = 0; j < ndim; ++j) {
1364 tmp[i] += m[j][i] * a[j];
1366 c[0] += b[i] * tmp[i];
1379 std::vector<int> list;
1382 if (abs(i0 - i1) * 2 <
int(nWires)) {
1384 for (
int i = id0; i <= id1; ++i)
1387 for (
int i = id0; i >= id1; i--) {
1393 for (
int i = id0; i >= 0; i--)
1395 for (
int i = nWires - 1; i >= id1; i--)
1398 for (
int i = id0; i < nWires; ++i)
1400 for (
int i = 0; i <= id1; ++i)
1409 const G4ThreeVector posOut, G4ThreeVector& hitPosition, G4ThreeVector& wirePosition)
1412 TVector3 tbwp(bwp.x(), bwp.y(), bwp.z());
1413 TVector3 tfwp(fwp.x(), fwp.y(), fwp.z());
1414 TVector3 tposIn(posIn.x(), posIn.y(), posIn.z());
1415 TVector3 tposOut(posOut.x(), posOut.y(), posOut.z());
1416 TVector3 thitPosition(0., 0., 0.);
1417 TVector3 twirePosition(0., 0., 0.);
1420 G4double distance =
CDC::ClosestApproach(tbwp, tfwp, tposIn, tposOut, thitPosition, twirePosition);
1422 hitPosition.setX(thitPosition.x());
1423 hitPosition.setY(thitPosition.y());
1424 hitPosition.setZ(thitPosition.z());
1426 wirePosition.setX(twirePosition.x());
1427 wirePosition.setY(twirePosition.y());
1428 wirePosition.setZ(twirePosition.z());
1446 int nRelationsMinusOne = mcPartToSimHits.
getEntries() - 1;
1448 if (nRelationsMinusOne == -1)
return;
1460 size_t iRelation = 0;
1461 int trackIdOld = INT_MAX;
1466 for (
int it = nRelationsMinusOne; it >= 0; --it) {
1468 size_t nRelatedHits = mcPartToSimHit.
getSize();
1469 if (nRelatedHits > 1) B2FATAL(
"CDCSensitiveDetector::EndOfEvent: MCParticle<-> CDCSimHit relation is not one-to-one !");
1471 unsigned short trackId = mcPartToSimHit.
getFromIndex();
1474 trackIdOld = trackId;
1475 }
else if (weight <= 0. && trackId == trackIdOld) {
1479 trackIdOld = trackId;
1508 for (
int it = 0; it <= nRelationsMinusOne; ++it) {
1552 unsigned short sClayer = sWireId.
getICLayer();
1554 unsigned short sLayer = sWireId.
getILayer();
1555 unsigned short sWire = sWireId.
getIWire();
1558 std::multimap<unsigned short, CDCSimHit*>::iterator pItBegin =
m_hitWithPosWeight.find(sSuperLayer);
1559 std::multimap<unsigned short, CDCSimHit*>::iterator pItEnd =
m_hitWithPosWeight.find(sSuperLayer + 1);
1569 double minDistance2 = DBL_MAX;
1577 for (std::multimap<unsigned short, CDCSimHit*>::iterator pIt = pItBegin; pIt != pItEnd; ++pIt) {
1583 unsigned short neighb =
areNeighbors(sClayer, sSuperLayer, sLayer, sWire, pWireId);
1584 if (neighb != 0 || pWireId == sWireId) {
1585 double distance2 = (pHit->
getPosTrack() - sPos).Mag2();
1586 if (distance2 < minDistance2) {
1588 minDistance2 = distance2;
1610 const signed short iWire = wireId.
getIWire();
1611 const signed short iOtherWire = otherWireId.
getIWire();
1612 const signed short iCLayer = wireId.
getICLayer();
1613 const signed short iOtherCLayer = otherWireId.
getICLayer();
1616 if (iWire == iOtherWire) {
1617 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1618 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1625 if (abs(iLayerDifference) > 1)
return 0;
1627 if (iLayerDifference == 0) {
1631 }
else if (iLayerDifference == -1) {
1636 if (iWire == iOtherWire) {
1640 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1643 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1647 }
else if (iLayerDifference == 1) {
1652 if (iWire == iOtherWire) {
1656 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1659 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1668 unsigned short iWire,
const WireID& otherWireId)
const
1673 const signed short iOtherWire = otherWireId.
getIWire();
1674 const signed short iOtherCLayer = otherWireId.
getICLayer();
1677 if (iWire == iOtherWire) {
1678 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1679 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1685 signed short iLayerDifference = otherWireId.
getILayer() - iLayer;
1686 if (abs(iLayerDifference) > 1)
return 0;
1688 if (iLayerDifference == 0) {
1692 }
else if (iLayerDifference == -1) {
1697 if (iWire == iOtherWire) {
1701 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1704 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1708 }
else if (iLayerDifference == 1) {
1713 if (iWire == iOtherWire) {
1717 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1720 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
void setLeftRightPassageRaw(int minusOneOrZeroOrOne)
The method to set new left/right info. for digitization.
void setPosOut(TVector3 posOut)
The method to set position of post-step.
TVector3 getPosWire() const
The method to get position on wire.
void setPosFlag(int zeroOrOne)
The method to set position flag.
void setPosWire(TVector3 posWire)
The method to set 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.
TVector3 getMomentum() const
The method to get momentum.
void setEnergyDep(double edep)
The method to set deposited energy.
void setDriftLength(double driftLength)
The method to set drift length.
void setStepLength(double stepLength)
The method to set step length.
void setMomentum(TVector3 momentum)
The method to set momentum.
void setFlightTime(double flightTime)
The method to set flight time.
TVector3 getPosTrack() const
The method to get position on the track.
void setPosTrack(TVector3 posTrack)
The method to set position on the track.
void setPosIn(TVector3 posIn)
The method to set position of pre-step.
void setLeftRightPassage(int minusOneOrZeroOrOne)
The method to set new left/right info. for tracking.
unsigned short getOldLeftRight(const TVector3 &posOnWire, const TVector3 &posOnTrack, const TVector3 &momentum) const
Returns old left/right.
const TVector3 wireBackwardPosition(int layerId, int cellId, EWirePosition set=c_Base) const
Returns the backward position of the input sense wire.
unsigned short getNewLeftRightRaw(const TVector3 &posOnWire, const TVector3 &posOnTrack, const TVector3 &momentum) const
Returns new left/right_raw.
void getWireSagEffect(EWirePosition set, unsigned layerID, unsigned cellID, double zw, double &ywb_sag, double &ywf_sag) const
Compute effects of the sense wire sag.
const TVector3 wireForwardPosition(int layerId, int cellId, EWirePosition set=c_Base) const
Returns the forward 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.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
unsigned cellId(unsigned layerId, const TVector3 &position) const
The method to get cell id based on given layer id and the position.
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.
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 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 TVector3 &bwp, const TVector3 &fwp, const TVector3 &posIn, const TVector3 &posOut, TVector3 &hitPosition, TVector3 &wirePosition)
Returns a closest distance between a track and a wire.
Abstract base class for different kinds of events.