12 #include <cdc/simulation/CDCSensitiveDetector.h>
14 #include <cdc/simulation/CDCSimControlPar.h>
15 #include <cdc/simulation/Helix.h>
16 #include <cdc/geometry/CDCGeometryPar.h>
17 #include <cdc/utilities/ClosestApproach.h>
18 #include <framework/logging/Logger.h>
19 #include <framework/datastore/StoreArray.h>
20 #include <framework/datastore/RelationArray.h>
21 #include <cdc/dataobjects/CDCSimHit.h>
24 #include "G4TransportationManager.hh"
26 #include "G4FieldManager.hh"
28 #include "CLHEP/Geometry/Vector3D.h"
29 #include "CLHEP/Geometry/Point3D.h"
33 #ifndef ENABLE_BACKWARDS_COMPATIBILITY
36 #ifndef ENABLE_BACKWARDS_COMPATIBILITY
37 typedef HepGeom::Vector3D<double> HepVector3D;
54 SensitiveDetectorBase(name,
Const::CDC),
57 m_thresholdEnergyDeposit(thresholdEnergyDeposit),
58 m_thresholdKineticEnergy(thresholdKineticEnergy), m_hitNumber(0)
68 cdcSimHits.registerInDataStore();
80 B2DEBUG(150,
"CDCSensitiveDetector: Sense wire sag on(=1)/off(=0): " <<
m_wireSag);
83 B2DEBUG(150,
"CDCSensitiveDetector: Set left/right flag modified for tracking (=1)/ not set (=0): " <<
m_modifiedLeftRightFlag);
87 B2DEBUG(150,
"CDCSensitiveDetector: MinTrackLength (mm): " <<
m_minTrackLength);
150 #if defined(CDC_DEBUG)
151 std::cout <<
" " << std::endl;
152 std::cout <<
"********* step in ********" << std::endl;
155 const G4double edep = aStep->GetTotalEnergyDeposit();
162 const G4double stepLength = aStep->GetStepLength();
163 if (stepLength == 0.)
return false;
166 const G4Track& t = * aStep->GetTrack();
184 const G4int pid = t.GetDefinition()->GetPDGEncoding();
185 const G4double charge = t.GetDefinition()->GetPDGCharge();
186 const G4int trackID = t.GetTrackID();
189 const G4VPhysicalVolume& v = * t.GetVolume();
190 const G4StepPoint& in = * aStep->GetPreStepPoint();
191 const G4StepPoint& out = * aStep->GetPostStepPoint();
192 const G4ThreeVector& posIn = in.GetPosition();
193 const G4ThreeVector& posOut = out.GetPosition();
194 const G4ThreeVector momIn(in.GetMomentum().x(), in.GetMomentum().y(),
195 in.GetMomentum().z());
196 #if defined(CDC_DEBUG)
197 std::cout <<
"pid = " << pid << std::endl;
198 std::cout <<
"mass = " << t.GetDefinition()->GetPDGMass() << std::endl;
199 std::cout <<
"posIn = " << posIn << std::endl;
200 std::cout <<
"posOut= " << posOut << std::endl;
201 std::cout <<
"tof at post-step = " << out.GetGlobalTime() << std::endl;
202 std::cout <<
"stepl = " << stepLength << std::endl;
206 const unsigned layerId = v.GetCopyNo();
207 B2DEBUG(150,
"LayerID in continuous counting method: " << layerId);
211 if ((charge == 0.) && (abs(pid) != 99666))
return false;
214 TVector3 tposIn(posIn.x() / CLHEP::cm, posIn.y() / CLHEP::cm, posIn.z() / CLHEP::cm);
215 TVector3 tposOut(posOut.x() / CLHEP::cm, posOut.y() / CLHEP::cm, posOut.z() / CLHEP::cm);
218 #if defined(CDC_DEBUG)
219 std::cout <<
"edep= " << edep << std::endl;
220 std::cout <<
"idIn,idOut= " << idIn <<
" " << idOut << std::endl;
226 const G4double s_in_layer = stepLength / CLHEP::cm;
227 G4double xint[6] = {0};
229 const G4ThreeVector momOut(out.GetMomentum().x(), out.GetMomentum().y(),
230 out.GetMomentum().z());
231 const G4double speedIn = in.GetVelocity();
232 const G4double speedOut = out.GetVelocity();
233 const G4double speed = 0.5 * (speedIn + speedOut);
234 const G4double speedInCmPerNs = speed / CLHEP::cm;
236 const unsigned int nWires = wires.size();
237 G4double tofBefore = in.GetGlobalTime();
238 G4double kinEnergyBefore = in.GetKineticEnergy();
239 G4double momBefore = momIn.mag();
240 const G4double eLoss = kinEnergyBefore - out.GetKineticEnergy();
241 const G4double mass = t.GetDefinition()->GetPDGMass();
242 #if defined(CDC_DEBUG)
243 std::cout <<
"momBefore = " << momBefore << std::endl;
244 std::cout <<
"momIn = " << momIn.x() <<
" " << momIn.y() <<
" " << momIn.z() << std::endl;
245 std::cout <<
"momOut= " << momOut.x() <<
" " << momOut.y() <<
" " << momOut.z() << std::endl;
246 std::cout <<
"speedIn,speedOut= " << speedIn <<
" " << speedOut << std::endl;
247 std::cout <<
" speedInCmPerNs= " << speedInCmPerNs << std::endl;
248 std::cout <<
"tofBefore= " << tofBefore << std::endl;
251 const G4Field* field = G4TransportationManager::GetTransportationManager()->GetFieldManager()->GetDetectorField();
253 for (
unsigned i = 0; i < nWires; ++i) {
254 #if defined(CDC_DEBUG)
255 std::cout <<
"============ i,wires[i]= " << i <<
" " << wires[i] << std::endl;
258 const G4double pos[3] = {posIn.x(), posIn.y(), posIn.z()};
260 field->GetFieldValue(pos, Bfield);
262 Bfield[2] == 0.) ? false :
true;
263 #if defined(CDC_DEBUG)
264 std::cout <<
"Bfield= " << Bfield[0] <<
" " << Bfield[1] <<
" " << Bfield[2] << std::endl;
269 G4ThreeVector posW(0, 0, 0);
277 const HepPoint3D fwd(tfw3v.x(), tfw3v.y(), tfw3v.z());
278 const HepPoint3D bck(tbw3v.x(), tbw3v.y(), tbw3v.z());
285 if (Bfield[0] == 0. && Bfield[1] == 0. &&
288 const G4double B_kG[3] = {Bfield[0] / CLHEP::kilogauss,
289 Bfield[1] / CLHEP::kilogauss,
290 Bfield[2] / CLHEP::kilogauss
292 #if defined(CDC_DEBUG)
293 std::cout <<
"B_kG= " << B_kG[0] <<
" " << B_kG[1] <<
" " << B_kG[2] << std::endl;
297 const HepPoint3D x(pos[0] / CLHEP::cm, pos[1] / CLHEP::cm, pos[2] / CLHEP::cm);
298 const HepVector3D p(momIn.x() / CLHEP::GeV, momIn.y() / CLHEP::GeV, momIn.z() / CLHEP::GeV);
299 Helix tmp(x, p, charge);
300 tmp.bFieldZ(B_kG[2]);
301 tmp.ignoreErrorMatrix();
311 const HepVector3D wire = fwd - bck;
313 (x.z() - bck.z()) / wire.z() * wire + bck;
315 tryp = (tmp.x(0.).z() - bck.z()) / wire.z() * wire + bck;
317 tryp = (tmp.x(0.).z() - bck.z()) / wire.z() * wire + bck;
320 distance = std::abs(tmp.a()[0]);
327 pOnTrack = tmp.momentum(0.);
330 const G4double xwb(bck.x()), ywb(bck.y()), zwb(bck.z());
331 const G4double xwf(fwd.x()), ywf(fwd.y()), zwf(fwd.z());
332 const G4double xp(onTrack.x()), yp(onTrack.y()), zp(onTrack.z());
333 const G4double px(pOnTrack.x()), py(pOnTrack.y()), pz(pOnTrack.z());
334 G4double q2[3] = {0.}, q1[3] = {0.}, q3[3] = {0.};
335 const G4int ntryMax(50);
338 HELWIR(xwb, ywb, zwb, xwf, ywf, zwf,
339 xp, yp, zp, px, py, pz,
340 B_kG, charge, ntryMax, dist, q2, q1, q3, ntry);
342 #if defined(CDC_DEBUG)
343 std::cout <<
"ntry= " << ntry << std::endl;
344 std::cout <<
"bf distance= " << distance << std::endl;
345 std::cout <<
"onTrack = " << onTrack << std::endl;
346 std::cout <<
"posW = " << posW << std::endl;
348 if (ntry <= ntryMax) {
350 G4double ywb_sag, ywf_sag;
352 HELWIR(xwb, ywb_sag, zwb, xwf, ywf_sag, zwf,
353 xp, yp, zp, px, py, pz,
354 B_kG, charge, ntryMax, dist, q2, q1, q3, ntry);
356 if (ntry <= ntryMax) {
364 pOnTrack.setX(q3[0]);
365 pOnTrack.setY(q3[1]);
366 pOnTrack.setZ(q3[2]);
368 #if defined(CDC_DEBUG)
369 std::cout <<
" " << std::endl;
370 std::cout <<
"helix distance= " << distance << std::endl;
371 std::cout <<
"onTrack = " << onTrack << std::endl;
372 std::cout <<
"posW = " << posW << std::endl;
373 std::cout <<
"pOnTrack= " << pOnTrack << std::endl;
374 G4ThreeVector bwp(bck.x(), bck.y(), bck.z());
375 G4ThreeVector fwp(fwd.x(), fwd.y(), fwd.z());
376 G4ThreeVector hitPosition, wirePosition;
377 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
378 hitPosition, wirePosition);
380 G4double ywb_sag, ywf_sag;
384 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
385 hitPosition, wirePosition);
387 std::cout <<
"line distance= " << distance << std::endl;
388 std::cout <<
"onTrack= " << hitPosition.x() <<
" " << hitPosition.y() <<
" " << hitPosition.z() << std::endl;
389 std::cout <<
"posW = " << wirePosition.x() <<
" " << wirePosition.y() <<
" " << wirePosition.z() << std::endl;
394 G4ThreeVector bwp(bck.x(), bck.y(), bck.z());
395 G4ThreeVector fwp(fwd.x(), fwd.y(), fwd.z());
396 G4ThreeVector hitPosition, wirePosition;
397 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
398 hitPosition, wirePosition);
400 G4double ywb_sag, ywf_sag;
404 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
405 hitPosition, wirePosition);
408 onTrack.setX(hitPosition.x());
409 onTrack.setY(hitPosition.y());
410 onTrack.setZ(hitPosition.z());
411 posW.setX(wirePosition.x());
412 posW.setY(wirePosition.y());
413 posW.setZ(wirePosition.z());
415 pOnTrack.setX(0.5 * (momIn.x() + momOut.x()) / CLHEP::GeV);
416 pOnTrack.setY(0.5 * (momIn.y() + momOut.y()) / CLHEP::GeV);
417 pOnTrack.setZ(0.5 * (momIn.z() + momOut.z()) / CLHEP::GeV);
420 #if defined(CDC_DEBUG)
421 std::cout <<
"af distance= " << distance << std::endl;
422 std::cout <<
"onTrack = " << onTrack << std::endl;
423 std::cout <<
"posW = " << posW << std::endl;
424 std::cout <<
"pOnTrack = " << pOnTrack << std::endl;
425 if (distance > 2.4) {
426 std::cout <<
"toolargedriftl" << std::endl;
429 distance *= CLHEP::cm; onTrack *= CLHEP::cm; posW *= CLHEP::cm;
430 pOnTrack *= CLHEP::GeV;
432 G4ThreeVector posTrack(onTrack.x(), onTrack.y(), onTrack.z());
433 G4ThreeVector mom(pOnTrack.x(), pOnTrack.y(), pOnTrack.z());
435 const TVector3 tPosW(posW.x(), posW.y(), posW.z());
436 const TVector3 tPosTrack(posTrack.x(), posTrack.y(), posTrack.z());
437 const TVector3 tMom(mom.x(), mom.y(), mom.z());
443 G4int newLr = newLrRaw;
448 saveSimHit(layerId, wires[i], trackID, pid, distance, tofBefore, edep, s_in_layer * CLHEP::cm, pOnTrack, posW, posIn, posOut,
449 posTrack, lr, newLrRaw, newLr, speed, hitWeight);
450 #if defined(CDC_DEBUG)
451 std::cout <<
"saveSimHit" << std::endl;
452 std::cout <<
"momIn = " << momIn << std::endl;
453 std::cout <<
"pOnTrack = " << pOnTrack << std::endl;
458 G4int cel1 = wires[i] + 1;
460 if (i + 1 <= nWires - 1) {
461 cel2 = wires[i + 1] + 1;
463 const G4double s2 = t.GetTrackLength() / CLHEP::cm;
464 G4double s1 = (s2 - s_in_layer);
465 G4ThreeVector din = momIn;
466 if (din.mag() != 0.) din /= momIn.mag();
468 G4double vent[6] = {posIn.x() / CLHEP::cm, posIn.y() / CLHEP::cm, posIn.z() / CLHEP::cm, din.x(), din.y(), din.z()};
470 G4ThreeVector dot(momOut.x(), momOut.y(), momOut.z());
471 if (dot.mag() != 0.) {
478 G4double vext[6] = {posOut.x() / CLHEP::cm, posOut.y() / CLHEP::cm, posOut.z() / CLHEP::cm, dot.x(), dot.y(), dot.z()};
481 for (
int j = 0; j < 6; ++j) vent[j] = xint[j];
487 G4double edep_in_cell(0.);
488 G4double eLossInCell(0.);
491 #if defined(CDC_DEBUG)
492 std::cout <<
"layerId,cel1,cel2= " << layerId <<
" " << cel1 <<
" " << cel2 << std::endl;
493 std::cout <<
"vent= " << vent[0] <<
" " << vent[1] <<
" " << vent[2] <<
" " << vent[3] <<
" " << vent[4] <<
" " << vent[5] <<
495 std::cout <<
"vext= " << vext[0] <<
" " << vext[1] <<
" " << vext[2] <<
" " << vext[3] <<
" " << vext[4] <<
" " << vext[5] <<
497 std::cout <<
"s1,s2,ic= " << s1 <<
" " << s2 <<
" " << ic << std::endl;
499 CellBound(layerId, cel1, cel2, vent, vext, s1, s2, xint, sint, flag);
500 #if defined(CDC_DEBUG)
501 std::cout <<
"flag,sint= " << flag <<
" " << sint << std::endl;
502 std::cout <<
"xint= " << xint[0] <<
" " << xint[1] <<
" " << xint[2] <<
" " << xint[3] <<
" " << xint[4] <<
" " << xint[5] <<
506 const G4double test = (sint - s1) / s_in_layer;
507 if (test < 0. || test > 1.) {
508 B2WARNING(
"CDCSensitiveDetector: Strange path length: " <<
"s1= " << s1 <<
" sint= " << sint <<
" s_in_layer= " << s_in_layer <<
511 edep_in_cell = edep * std::abs((sint - s1)) / s_in_layer;
513 const G4ThreeVector x_In(vent[0]*CLHEP::cm, vent[1]*CLHEP::cm, vent[2]*CLHEP::cm);
514 const G4ThreeVector x_Out(xint[0]*CLHEP::cm, xint[1]*CLHEP::cm, xint[2]*CLHEP::cm);
515 const G4ThreeVector p_In(momBefore * vent[3], momBefore * vent[4], momBefore * vent[5]);
518 saveSimHit(layerId, wires[i], trackID, pid, distance, tofBefore, edep_in_cell, std::abs((sint - s1)) * CLHEP::cm, pOnTrack, posW,
520 posTrack, lr, newLrRaw, newLr, speed, hitWeight);
521 #if defined(CDC_DEBUG)
522 std::cout <<
"saveSimHit" << std::endl;
523 std::cout <<
"p_In = " << p_In << std::endl;
524 std::cout <<
"pOnTrack= " << pOnTrack << std::endl;
526 tofBefore += (sint - s1) / speedInCmPerNs;
527 eLossInCell = eLoss * (sint - s1) / s_in_layer;
528 kinEnergyBefore -= eLossInCell;
529 if (kinEnergyBefore >= 0.) {
530 momBefore = sqrt(kinEnergyBefore * (kinEnergyBefore + 2.*mass));
532 B2WARNING(
"CDCSensitiveDetector: Kinetic Energy < 0.");
538 const G4double test = (s2 - sint) / s_in_layer;
539 if (test < 0. || test > 1.) {
540 B2WARNING(
"CDCSensitiveDetector: Strange path length: " <<
"s2= " << s2 <<
" sint= " << sint <<
" s_in_layer= " << s_in_layer <<
543 edep_in_cell = edep * std::abs((s2 - sint)) / s_in_layer;
545 const G4ThreeVector x_In(vent[0]*CLHEP::cm, vent[1]*CLHEP::cm, vent[2]*CLHEP::cm);
546 const G4ThreeVector p_In(momBefore * vent[3], momBefore * vent[4], momBefore * vent[5]);
549 saveSimHit(layerId, wires[i], trackID, pid, distance, tofBefore, edep_in_cell, std::abs((s2 - sint)) * CLHEP::cm, pOnTrack, posW,
551 posOut, posTrack, lr, newLrRaw, newLr, speed, hitWeight);
552 #if defined(CDC_DEBUG)
553 std::cout <<
"saveSimHit" << std::endl;
554 std::cout <<
"p_In = " << p_In << std::endl;
555 std::cout <<
"pOnTrack= " << pOnTrack << std::endl;
593 const G4double distance,
596 const G4double stepLength,
597 const G4ThreeVector& mom,
598 const G4ThreeVector& posW,
599 const G4ThreeVector& posIn,
600 const G4ThreeVector& posOut,
601 const G4ThreeVector& posTrack,
603 const G4int newLrRaw,
605 const G4double speed,
606 const G4double hitWeight)
614 const G4double sign = (posTrack - posIn).dot(mom) < 0. ? -1. : 1.;
615 const G4double CorrectTof = tof + sign * (posTrack - posIn).mag() / speed;
617 #if defined(CDC_DEBUG)
618 std::cout <<
"posIn= " << posIn.x() <<
" " << posIn.y() <<
" " << posIn.z() << std::endl;
619 std::cout <<
"posOut= " << posOut.x() <<
" " << posOut.y() <<
" " << posOut.z() << std::endl;
620 std::cout <<
"posTrack= " << posTrack.x() <<
" " << posTrack.y() <<
" " << posTrack.z() << std::endl;
621 std::cout <<
"posW= " << posW.x() <<
" " << posW.y() <<
" " << posW.z() << std::endl;
622 std::cout <<
"tof = " << tof << std::endl;
623 std::cout <<
"deltaTof = " << (posTrack - posIn).mag() / speed << std::endl;
624 std::cout <<
"CorrectTof= " << CorrectTof << std::endl;
625 if (CorrectTof > 95) {
626 std::cout <<
"toolargecorrecttof" << std::endl;
648 TVector3 momentum(mom.getX() / CLHEP::GeV, mom.getY() / CLHEP::GeV, mom.getZ() / CLHEP::GeV);
650 TVector3 posWire(posW.getX() / CLHEP::cm, posW.getY() / CLHEP::cm, posW.getZ() / CLHEP::cm);
652 TVector3 positionIn(posIn.getX() / CLHEP::cm, posIn.getY() / CLHEP::cm, posIn.getZ() / CLHEP::cm);
654 TVector3 positionOut(posOut.getX() / CLHEP::cm, posOut.getY() / CLHEP::cm, posOut.getZ() / CLHEP::cm);
656 TVector3 positionTrack(posTrack.getX() / CLHEP::cm, posTrack.getY() / CLHEP::cm, posTrack.getZ() / CLHEP::cm);
661 #if defined(CDC_DEBUG)
662 std::cout <<
"sensitived,oldlr,newlrRaw,newlr= " << lr <<
" " << newLrRaw <<
" " << newLr << std::endl;
699 const G4double venter[6],
700 const G4double vexit[6],
701 const G4double s1,
const G4double s2,
703 G4double& sint, G4int& iflag)
733 B2ERROR(
"CDCSensitiveDetector: s1(=" << s1 <<
") > s2(=" << s2 <<
")");
735 if (std::abs(ic1 - ic2) != 1) {
736 if (ic1 == 1 && ic2 == div) {
737 }
else if (ic1 == div && ic2 == 1) {
739 B2ERROR(
"CDCSensitiveDetector: |ic1 - ic2| != 1 in CellBound; " <<
"ic1=" << ic1 <<
" " <<
"ic2=" << ic2);
763 G4double xx1[6], xx2[6];
764 for (
int i = 0; i < 6; ++i) {
770 G4double psi = double(ic2 - ic1) * CLHEP::pi / div;
771 if (ic1 == 1 && ic2 == div) {
772 psi = -CLHEP::pi / div;
773 }
else if (ic1 == div && ic2 == 1) {
774 psi = CLHEP::pi / div;
776 G4double cospsi = cos(psi);
777 G4double sinpsi = sin(psi);
779 G4double xfwb = cospsi * xwb - sinpsi * ywb;
780 G4double yfwb = sinpsi * xwb + cospsi * ywb;
781 G4double xfwf = cospsi * xwf - sinpsi * ywf;
782 G4double yfwf = sinpsi * xwf + cospsi * ywf;
787 G4double vx = xfwf - xfwb;
788 G4double vy = yfwf - yfwb;
789 G4double vz = zfwf - zfwb;
790 G4double vv = sqrt(vx * vx + vy * vy + vz * vz);
791 vx /= vv; vy /= vv; vz /= vv;
794 G4double shiftx = (xx1[0] + xx2[0]) * 0.5;
795 G4double shifty = (xx1[1] + xx2[1]) * 0.5;
796 G4double shiftz = (xx1[2] + xx2[2]) * 0.5;
797 G4double shifts = (s1 + s2) * 0.5;
798 G4double xshft = xx1[0] - shiftx;
799 G4double yshft = xx1[1] - shifty;
800 G4double zshft = xx1[2] - shiftz;
801 G4double sshft = s1 - shifts;
804 G4double pabs1 = sqrt(xx1[3] * xx1[3] + xx1[4] * xx1[4] + xx1[5] * xx1[5]);
805 G4double pabs2 = sqrt(xx2[3] * xx2[3] + xx2[4] * xx2[4] + xx2[5] * xx2[5]);
808 G4double a[4] = {0.}, b[4] = {0.}, c[4] = {0.};
811 GCUBS(sshft, xshft, xx1[3] / pabs1, xx2[3] / pabs2, a);
812 GCUBS(sshft, yshft, xx1[4] / pabs1, xx2[4] / pabs2, b);
813 GCUBS(sshft, zshft, xx1[5] / pabs1, xx2[5] / pabs2, c);
819 a[1] = xshft / sshft;
820 b[1] = yshft / sshft;
821 c[1] = zshft / sshft;
825 G4double stry(0.), xtry(0.), ytry(0.), ztry(0.);
826 G4double beta(0.), xfw(0.), yfw(0.);
827 G4double sphi(0.), cphi(0.), dphil(0.), dphih(0.);
828 const G4int maxTrials = 100;
829 const G4double eps = 5.e-4;
831 G4double sh = -sshft;
836 xtry = shiftx + a[0] + stry * (a[1] + stry * (a[2] + stry * a[3]));
837 ytry = shifty + b[0] + stry * (b[1] + stry * (b[2] + stry * b[3]));
838 ztry = shiftz + c[0] + stry * (c[1] + stry * (c[2] + stry * c[3]));
839 beta = (ztry - zfwb) / vz;
840 xfw = xfwb + beta * vx;
841 yfw = yfwb + beta * vy;
842 sphi = (xtry * yfw - ytry * xfw);
843 cphi = (xtry * xfw + ytry * yfw);
844 dphil = atan2(sphi, cphi);
848 while (((sh - sl) > eps) && (i < maxTrials)) {
849 stry = 0.5 * (sl + sh);
850 xtry = shiftx + a[0] + stry * (a[1] + stry * (a[2] + stry * a[3]));
851 ytry = shifty + b[0] + stry * (b[1] + stry * (b[2] + stry * b[3]));
852 ztry = shiftz + c[0] + stry * (c[1] + stry * (c[2] + stry * c[3]));
853 beta = (ztry - zfwb) / vz;
854 xfw = xfwb + beta * vx;
855 yfw = yfwb + beta * vy;
857 sphi = (xtry * yfw - ytry * xfw);
858 cphi = (xtry * xfw + ytry * yfw);
859 dphih = atan2(sphi, cphi);
861 if (dphil * dphih > 0.) {
870 if (i >= maxTrials - 1) {
872 B2WARNING(
"CDCSensitiveDetector: No intersection ?");
904 xint[0] = a[0] + sint * (a[1] + sint * (a[2] + sint * a[3]));
905 xint[1] = b[0] + sint * (b[1] + sint * (b[2] + sint * b[3]));
906 xint[2] = c[0] + sint * (c[1] + sint * (c[2] + sint * c[3]));
907 xint[3] = a[1] + sint * (2. * a[2] + 3. * sint * a[3]);
908 xint[4] = b[1] + sint * (2. * b[2] + 3. * sint * b[3]);
909 xint[5] = c[1] + sint * (2. * c[2] + 3. * sint * c[3]);
935 G4double p = sqrt(xint[3] * xint[3] + xint[4] * xint[4] + xint[5] * xint[5]);
936 xint[3] /= p; xint[4] /= p; xint[5] /= p;
961 if (x == 0.)
goto L10;
963 fact = (d1 - d2) * 0.25;
964 a[0] = - 1. * fact * x;
966 a[1] = (6. * y - (d1 + d2) * x) / (4. * x);
967 a[3] = ((d1 + d2) * x - 2.*y) / (4.*x * x * x);
993 G4double bxz, bfield;
994 bxz = bx * bx + bz * bz;
995 bfield = bxz + by * by;
997 bfield = sqrt(bfield);
1001 m_brot[2][0] = -bx / bxz;
1002 m_brot[0][1] = -by * bx / bxz / bfield;
1003 m_brot[1][1] = bxz / bfield;
1004 m_brot[2][1] = -by * bz / bxz / bfield;
1005 m_brot[0][2] = bx / bfield;
1006 m_brot[1][2] = by / bfield;
1007 m_brot[2][2] = bz / bfield;
1024 G4double x0(x), y0(y), z0(z);
1030 }
else if (mode == -1) {
1051 G4double x0(x[0]), y0(x[1]), z0(x[2]);
1057 }
else if (mode == -1) {
1070 const G4double zwb4,
1071 const G4double xwf4,
const G4double ywf4,
1072 const G4double zwf4,
1073 const G4double xp,
const G4double yp,
1075 const G4double px,
const G4double py,
1077 const G4double B_kG[3],
1078 const G4double charge,
const G4int ntryMax,
1080 G4double q2[3], G4double q1[3],
1106 const G4int ndim = 3;
1107 const G4double delta = 1.e-5;
1110 G4double xwb, ywb, zwb, xwf, ywf, zwf;
1111 G4double xw, yw, zw, xh, yh, zh, pxh, pyh, pzh;
1112 G4double fi, fi_corr;
1114 G4double dr, fi0, cpa, dz, tanl;
1115 G4double x0, y0, z0;
1120 G4double sinfi0, cosfi0, sinfi0fi, cosfi0fi;
1122 G4double vx, vy, vz, vv, cx, cy, cz, tt[3][3];
1125 G4double xx[3], dxx[3], ddxx[3], pp[3];
1126 G4double xxtdxx, dxxtdxx, xxtddxx;
1130 G4double f, fderiv, deltafi, fact,
eval;
1131 G4double dx1, dy1, dx2, dy2, crs, dot;
1136 xwb = xwb4; ywb = ywb4; zwb = zwb4;
1137 xwf = xwf4; ywf = ywf4; zwf = zwf4;
1139 G4double xxx(xp), yyy(yp), zzz(zp);
1140 G4double pxx(px), pyy(py), pzz(pz);
1143 Rotat(xwb, ywb, zwb, 1);
1144 Rotat(xwf, ywf, zwf, 1);
1145 Rotat(xxx, yyy, zzz, 1);
1146 Rotat(pxx, pyy, pzz, 1);
1148 G4double a[8] = {0.};
1149 G4double pt = sqrt(pxx * pxx + pyy * pyy);
1150 a[1] = atan2(-pxx, pyy);
1153 a[5] = xxx; a[6] = yyy; a[7] = zzz;
1156 vx = xwf - xwb; vy = ywf - ywb; vz = zwf - zwb;
1157 vv = sqrt(vx * vx + vy * vy + vz * vz);
1158 vx /= vv; vy /= vv; vz /= vv;
1162 if (vx == 0. && vy == 0.) iflg = 1;
1167 cx = xwb - vx * (vx * xwb + vy * ywb + vz * zwb);
1168 cy = ywb - vy * (vx * xwb + vy * ywb + vz * zwb);
1169 cz = zwb - vz * (vx * xwb + vy * ywb + vz * zwb);
1172 tt[0][0] = vx * vx - 1.; tt[1][0] = vx * vy; tt[2][0] = vx * vz;
1173 tt[0][1] = vy * vx; tt[1][1] = vy * vy - 1.; tt[2][1] = vy * vz;
1174 tt[0][2] = vz * vx; tt[1][2] = vz * vy; tt[2][2] = vz * vz - 1.;
1177 dr = a[0]; fi0 = a[1]; cpa = a[2];
1178 dz = a[3]; tanl = a[4];
1179 x0 = a[5]; y0 = a[6]; z0 = a[7];
1188 G4double bfield = sqrt(B_kG[0] * B_kG[0] +
1191 G4double alpha = 1.e4 / 2.99792458 / bfield;
1195 xc = x0 + (dr + r) * cosfi0;
1196 yc = y0 + (dr + r) * sinfi0;
1201 crs = dx1 * dy2 - dy1 * dx2;
1202 dot = dx1 * dx2 + dy1 * dy2;
1203 fi = atan2(crs, dot);
1210 cosfi0fi = cos(fi0 + fi);
1211 sinfi0fi = sin(fi0 + fi);
1214 xx[0] = x0 + dr * cosfi0 + r * (cosfi0 - cosfi0fi);
1215 xx[1] = y0 + dr * sinfi0 + r * (sinfi0 - sinfi0fi);
1216 xx[2] = z0 + dz - r * tanl * fi;
1217 pp[0] = -pt * sinfi0fi;
1218 pp[1] = pt * cosfi0fi;
1222 q2[0] = xwb; q2[1] = ywb; q2[2] = xx[2];
1223 q1[0] = xx[0]; q1[1] = xx[1]; q1[2] = xx[2];
1224 q3[0] = pp[0]; q3[1] = pp[1]; q3[2] = pp[2];
1229 distance = sqrt((q2[0] - q1[0]) * (q2[0] - q1[0]) +
1230 (q2[1] - q1[1]) * (q2[1] - q1[1]) +
1231 (q2[2] - q1[2]) * (q2[2] - q1[2]));
1237 dxx[0] = r * sinfi0fi; dxx[1] = - r * cosfi0fi; dxx[2] = - r * tanl;
1264 Mvopr(ndim, xx, tt, dxx, tmp, 1);
1266 f = cx * dxx[0] + cy * dxx[1] + cz * dxx[2] + xxtdxx;
1267 if (std::abs(f) < delta)
goto line100;
1271 eval = (1.0 - 0.25 * fact) * std::abs(fst) - std::abs(f);
1272 if (
eval <= 0.) fact *= 0.5;
1276 ddxx[0] = r * cosfi0fi; ddxx[1] = r * sinfi0fi; ddxx[2] = 0.;
1279 Mvopr(ndim, dxx, tt, dxx, tmp, 1);
1281 Mvopr(ndim, xx, tt, ddxx, tmp, 1);
1283 fderiv = cx * ddxx[0] + cy * ddxx[1] + cz * ddxx[2] + dxxtdxx + xxtddxx;
1286 deltafi = f / fderiv;
1287 fi -= fact * deltafi;
1290 if (ntry > ntryMax) {
1300 zh = z0 + dz - r * tanl * fi;
1302 if (zh < zwb) fi_corr = (zwb - zh) / (-r * tanl);
1303 if (zh > zwf) fi_corr = (zwf - zh) / (-r * tanl);
1306 cosfi0fi = cos(fi0 + fi);
1307 sinfi0fi = sin(fi0 + fi);
1309 xh = x0 + dr * cosfi0 + r * (cosfi0 - cosfi0fi);
1310 yh = y0 + dr * sinfi0 + r * (sinfi0 - sinfi0fi);
1311 zh = z0 + dz - r * tanl * fi;
1312 pxh = -pt * sinfi0fi;
1313 pyh = pt * cosfi0fi;
1319 zw = vx * vz * xh + vy * vz * yh + vz * vz * zh + zwb - vz * (vx * xwb + vy * ywb + vz * zwb);
1320 xw = xwb + vx * (zw - zwb) / vz;
1321 yw = ywb + vy * (zw - zwb) / vz;
1323 q2[0] = xw; q2[1] = yw; q2[2] = zw;
1324 q1[0] = xh; q1[1] = yh; q1[2] = zh;
1325 q3[0] = pxh; q3[1] = pyh; q3[2] = pzh;
1331 distance = sqrt((q2[0] - q1[0]) * (q2[0] - q1[0]) +
1332 (q2[1] - q1[1]) * (q2[1] - q1[1]) +
1333 (q2[2] - q1[2]) * (q2[2] - q1[2]));
1340 const G4double a[3], G4double c[3],
const G4int mode)
1361 for (
int i = 0; i < ndim; ++i) c[i] = 0.;
1363 for (
int i = 0; i < ndim; ++i) tmp[i] = 0.;
1366 for (
int i = 0; i < ndim; ++i) {
1367 for (
int j = 0; j < ndim; ++j) {
1368 c[i] += m[j][i] * a[j];
1372 }
else if (mode == 1) {
1373 for (
int i = 0; i < ndim; ++i) {
1374 for (
int j = 0; j < ndim; ++j) {
1375 tmp[i] += m[j][i] * a[j];
1377 c[0] += b[i] * tmp[i];
1390 std::vector<int> list;
1393 if (abs(i0 - i1) * 2 <
int(nWires)) {
1395 for (
int i = id0; i <= id1; ++i)
1398 for (
int i = id0; i >= id1; i--) {
1404 for (
int i = id0; i >= 0; i--)
1406 for (
int i = nWires - 1; i >= id1; i--)
1409 for (
int i = id0; i < nWires; ++i)
1411 for (
int i = 0; i <= id1; ++i)
1420 const G4ThreeVector posOut, G4ThreeVector& hitPosition, G4ThreeVector& wirePosition)
1423 TVector3 tbwp(bwp.x(), bwp.y(), bwp.z());
1424 TVector3 tfwp(fwp.x(), fwp.y(), fwp.z());
1425 TVector3 tposIn(posIn.x(), posIn.y(), posIn.z());
1426 TVector3 tposOut(posOut.x(), posOut.y(), posOut.z());
1427 TVector3 thitPosition(0., 0., 0.);
1428 TVector3 twirePosition(0., 0., 0.);
1431 G4double distance =
CDC::ClosestApproach(tbwp, tfwp, tposIn, tposOut, thitPosition, twirePosition);
1433 hitPosition.setX(thitPosition.x());
1434 hitPosition.setY(thitPosition.y());
1435 hitPosition.setZ(thitPosition.z());
1437 wirePosition.setX(twirePosition.x());
1438 wirePosition.setY(twirePosition.y());
1439 wirePosition.setZ(twirePosition.z());
1459 int nRelationsMinusOne = mcPartToSimHits.
getEntries() - 1;
1461 if (nRelationsMinusOne == -1)
return;
1473 size_t iRelation = 0;
1474 int trackIdOld = INT_MAX;
1479 for (
int it = nRelationsMinusOne; it >= 0; --it) {
1481 size_t nRelatedHits = mcPartToSimHit.
getSize();
1482 if (nRelatedHits > 1) B2FATAL(
"CDCSensitiveDetector::EndOfEvent: MCParticle<-> CDCSimHit relation is not one-to-one !");
1484 unsigned short trackId = mcPartToSimHit.
getFromIndex();
1487 trackIdOld = trackId;
1488 }
else if (weight <= 0. && trackId == trackIdOld) {
1492 trackIdOld = trackId;
1521 for (
int it = 0; it <= nRelationsMinusOne; ++it) {
1565 unsigned short sClayer = sWireId.
getICLayer();
1567 unsigned short sLayer = sWireId.
getILayer();
1568 unsigned short sWire = sWireId.
getIWire();
1571 std::multimap<unsigned short, CDCSimHit*>::iterator pItBegin =
m_hitWithPosWeight.find(sSuperLayer);
1572 std::multimap<unsigned short, CDCSimHit*>::iterator pItEnd =
m_hitWithPosWeight.find(sSuperLayer + 1);
1582 double minDistance2 = DBL_MAX;
1590 for (std::multimap<unsigned short, CDCSimHit*>::iterator pIt = pItBegin; pIt != pItEnd; ++pIt) {
1596 unsigned short neighb =
areNeighbors(sClayer, sSuperLayer, sLayer, sWire, pWireId);
1597 if (neighb != 0 || pWireId == sWireId) {
1598 double distance2 = (pHit->
getPosTrack() - sPos).Mag2();
1599 if (distance2 < minDistance2) {
1601 minDistance2 = distance2;
1623 const signed short iWire = wireId.
getIWire();
1624 const signed short iOtherWire = otherWireId.
getIWire();
1625 const signed short iCLayer = wireId.
getICLayer();
1626 const signed short iOtherCLayer = otherWireId.
getICLayer();
1629 if (iWire == iOtherWire) {
1630 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1631 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1638 if (abs(iLayerDifference) > 1)
return 0;
1640 if (iLayerDifference == 0) {
1644 }
else if (iLayerDifference == -1) {
1649 if (iWire == iOtherWire) {
1653 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1656 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1660 }
else if (iLayerDifference == 1) {
1665 if (iWire == iOtherWire) {
1669 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1672 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1681 unsigned short iWire,
const WireID& otherWireId)
const
1686 const signed short iOtherWire = otherWireId.
getIWire();
1687 const signed short iOtherCLayer = otherWireId.
getICLayer();
1690 if (iWire == iOtherWire) {
1691 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1692 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1698 signed short iLayerDifference = otherWireId.
getILayer() - iLayer;
1699 if (abs(iLayerDifference) > 1)
return 0;
1701 if (iLayerDifference == 0) {
1705 }
else if (iLayerDifference == -1) {
1710 if (iWire == iOtherWire) {
1714 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1717 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {
1721 }
else if (iLayerDifference == 1) {
1726 if (iWire == iOtherWire) {
1730 }
else if (iWire == (iOtherWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iOtherCLayer))) {
1733 }
else if ((iWire + 1) %
static_cast<signed short>(
m_cdcgp->
nWiresInLayer(iCLayer)) == iOtherWire) {