92 const G4double edep = aStep->GetTotalEnergyDeposit();
98 const G4double stepLength = aStep->GetStepLength();
99 if (stepLength == 0.)
return false;
102 const G4Track& t = * aStep->GetTrack();
111 const G4int pid = t.GetDefinition()->GetPDGEncoding();
112 const G4double charge = t.GetDefinition()->GetPDGCharge();
113 const G4int trackID = t.GetTrackID();
114 const G4VPhysicalVolume& v = * t.GetVolume();
115 const G4StepPoint& in = * aStep->GetPreStepPoint();
116 const G4StepPoint& out = * aStep->GetPostStepPoint();
117 const G4ThreeVector& posIn = in.GetPosition();
118 const G4ThreeVector& posOut = out.GetPosition();
119 const G4ThreeVector momIn(in.GetMomentum().x(), in.GetMomentum().y(),
120 in.GetMomentum().z());
123 const unsigned layerId = v.GetCopyNo();
124 const unsigned layerIDWithLayerOffset = layerId +
m_cdcgp->getOffsetOfFirstLayer();
125 B2DEBUG(150,
"LayerID in continuous counting method: " << layerId);
128 if ((charge == 0.) && (abs(pid) != 99666))
return false;
131 B2Vector3D tposIn(posIn.x() / CLHEP::cm, posIn.y() / CLHEP::cm, posIn.z() / CLHEP::cm);
132 B2Vector3D tposOut(posOut.x() / CLHEP::cm, posOut.y() / CLHEP::cm, posOut.z() / CLHEP::cm);
133 const unsigned idIn =
m_cdcgp->cellId(layerIDWithLayerOffset, tposIn);
134 const unsigned idOut =
m_cdcgp->cellId(layerIDWithLayerOffset, tposOut);
139 const G4double s_in_layer = stepLength / CLHEP::cm;
140 G4double xint[6] = {0};
142 const G4ThreeVector momOut(out.GetMomentum().x(), out.GetMomentum().y(),
143 out.GetMomentum().z());
144 const G4double speedIn = in.GetVelocity();
145 const G4double speedOut = out.GetVelocity();
146 const G4double speed = 0.5 * (speedIn + speedOut);
147 const G4double speedInCmPerNs = speed / CLHEP::cm;
149 const unsigned int nWires = wires.size();
150 G4double tofBefore = in.GetGlobalTime();
151 G4double kinEnergyBefore = in.GetKineticEnergy();
152 G4double momBefore = momIn.mag();
153 const G4double eLoss = kinEnergyBefore - out.GetKineticEnergy();
154 const G4double mass = t.GetDefinition()->GetPDGMass();
156 const G4Field* field = G4TransportationManager::GetTransportationManager()->GetFieldManager()->GetDetectorField();
158 for (
unsigned i = 0; i < nWires; ++i) {
160 const G4double pos[3] = {posIn.x(), posIn.y(), posIn.z()};
162 field->GetFieldValue(pos, Bfield);
164 Bfield[2] == 0.) ?
false :
true;
167 G4ThreeVector posW(0, 0, 0);
172 const B2Vector3D tfw3v =
m_cdcgp->wireForwardPosition(layerIDWithLayerOffset, wires[i]);
173 const B2Vector3D tbw3v =
m_cdcgp->wireBackwardPosition(layerIDWithLayerOffset, wires[i]);
175 const HepPoint3D fwd(tfw3v.
x(), tfw3v.
y(), tfw3v.
z());
176 const HepPoint3D bck(tbw3v.
x(), tbw3v.
y(), tbw3v.
z());
183 if (Bfield[0] == 0. && Bfield[1] == 0. &&
186 const G4double B_kG[3] = {Bfield[0] / CLHEP::kilogauss,
187 Bfield[1] / CLHEP::kilogauss,
188 Bfield[2] / CLHEP::kilogauss
191 const HepPoint3D x(pos[0] / CLHEP::cm, pos[1] / CLHEP::cm, pos[2] / CLHEP::cm);
192 const HepVector3D p(momIn.x() / CLHEP::GeV, momIn.y() / CLHEP::GeV, momIn.z() / CLHEP::GeV);
193 Helix tmp(x, p, charge);
197 const HepVector3D wire = fwd - bck;
199 (x.z() - bck.z()) / wire.z() * wire + bck;
201 tryp = (tmp.
x(0.).z() - bck.z()) / wire.z() * wire + bck;
203 tryp = (tmp.
x(0.).z() - bck.z()) / wire.z() * wire + bck;
206 distance = std::abs(tmp.
a()[0]);
215 const G4double xwb(bck.x()), ywb(bck.y()), zwb(bck.z());
216 const G4double xwf(fwd.x()), ywf(fwd.y()), zwf(fwd.z());
217 const G4double xp(onTrack.x()), yp(onTrack.y()), zp(onTrack.z());
218 const G4double px(pOnTrack.x()), py(pOnTrack.y()), pz(pOnTrack.z());
219 G4double q2[3] = {0.}, q1[3] = {0.}, q3[3] = {0.};
220 const G4int ntryMax(50);
223 HELWIR(xwb, ywb, zwb, xwf, ywf, zwf,
224 xp, yp, zp, px, py, pz,
225 B_kG, charge, ntryMax, dist, q2, q1, q3, ntry);
227 if (ntry <= ntryMax) {
229 G4double ywb_sag, ywf_sag;
230 m_cdcgp->getWireSagEffect(CDCGeometryPar::c_Base, layerIDWithLayerOffset, wires[i], q2[2], ywb_sag, ywf_sag);
231 HELWIR(xwb, ywb_sag, zwb, xwf, ywf_sag, zwf,
232 xp, yp, zp, px, py, pz,
233 B_kG, charge, ntryMax, dist, q2, q1, q3, ntry);
235 if (ntry <= ntryMax) {
243 pOnTrack.setX(q3[0]);
244 pOnTrack.setY(q3[1]);
245 pOnTrack.setZ(q3[2]);
250 G4ThreeVector bwp(bck.x(), bck.y(), bck.z());
251 G4ThreeVector fwp(fwd.x(), fwd.y(), fwd.z());
252 G4ThreeVector hitPosition, wirePosition;
253 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
254 hitPosition, wirePosition);
256 G4double ywb_sag, ywf_sag;
257 m_cdcgp->getWireSagEffect(CDCGeometryPar::c_Base, layerIDWithLayerOffset, wires[i], wirePosition.z(), ywb_sag, ywf_sag);
260 distance =
ClosestApproach(bwp, fwp, posIn / CLHEP::cm, posOut / CLHEP::cm,
261 hitPosition, wirePosition);
264 onTrack.setX(hitPosition.x());
265 onTrack.setY(hitPosition.y());
266 onTrack.setZ(hitPosition.z());
267 posW.setX(wirePosition.x());
268 posW.setY(wirePosition.y());
269 posW.setZ(wirePosition.z());
271 pOnTrack.setX(0.5 * (momIn.x() + momOut.x()) / CLHEP::GeV);
272 pOnTrack.setY(0.5 * (momIn.y() + momOut.y()) / CLHEP::GeV);
273 pOnTrack.setZ(0.5 * (momIn.z() + momOut.z()) / CLHEP::GeV);
276 distance *= CLHEP::cm; onTrack *= CLHEP::cm; posW *= CLHEP::cm;
277 pOnTrack *= CLHEP::GeV;
279 G4ThreeVector posTrack(onTrack.x(), onTrack.y(), onTrack.z());
280 G4ThreeVector mom(pOnTrack.x(), pOnTrack.y(), pOnTrack.z());
282 const B2Vector3D tPosW(posW.x(), posW.y(), posW.z());
283 const B2Vector3D tPosTrack(posTrack.x(), posTrack.y(), posTrack.z());
284 const B2Vector3D tMom(mom.x(), mom.y(), mom.z());
285 G4int lr =
m_cdcgp->getOldLeftRight(tPosW, tPosTrack, tMom);
286 G4int newLrRaw =
m_cdcgp->getNewLeftRightRaw(tPosW, tPosTrack, tMom);
287 G4int newLr = newLrRaw;
290 saveSimHit(layerIDWithLayerOffset, wires[i], trackID, pid, distance, tofBefore, edep, s_in_layer * CLHEP::cm, pOnTrack, posW, posIn,
292 posTrack, lr, newLrRaw, newLr, speed, hitWeight);
296 G4int cel1 = wires[i] + 1;
298 if (i + 1 <= nWires - 1) {
299 cel2 = wires[i + 1] + 1;
301 const G4double s2 = t.GetTrackLength() / CLHEP::cm;
302 G4double s1 = (s2 - s_in_layer);
303 G4ThreeVector din = momIn;
304 if (din.mag() != 0.) din /= momIn.mag();
306 G4double vent[6] = {posIn.x() / CLHEP::cm, posIn.y() / CLHEP::cm, posIn.z() / CLHEP::cm, din.x(), din.y(), din.z()};
308 G4ThreeVector
dot(momOut.x(), momOut.y(), momOut.z());
309 if (
dot.mag() != 0.) {
316 G4double vext[6] = {posOut.x() / CLHEP::cm, posOut.y() / CLHEP::cm, posOut.z() / CLHEP::cm,
dot.x(),
dot.y(),
dot.z()};
319 for (
int j = 0; j < 6; ++j) vent[j] = xint[j];
324 G4double edep_in_cell(0.);
325 G4double eLossInCell(0.);
328 CellBound(layerIDWithLayerOffset, cel1, cel2, vent, vext, s1, s2, xint, sint, flag);
329 const G4double test = (sint - s1) / s_in_layer;
330 if (test < 0. || test > 1.) {
331 B2WARNING(
"CDCSensitiveDetector: Strange path length: " <<
"s1= " << s1 <<
" sint= " << sint <<
" s_in_layer= " << s_in_layer <<
334 edep_in_cell = edep * std::abs((sint - s1)) / s_in_layer;
336 const G4ThreeVector x_In(vent[0]*CLHEP::cm, vent[1]*CLHEP::cm, vent[2]*CLHEP::cm);
337 const G4ThreeVector x_Out(xint[0]*CLHEP::cm, xint[1]*CLHEP::cm, xint[2]*CLHEP::cm);
338 const G4ThreeVector p_In(momBefore * vent[3], momBefore * vent[4], momBefore * vent[5]);
340 saveSimHit(layerIDWithLayerOffset, wires[i], trackID, pid, distance, tofBefore, edep_in_cell, std::abs((sint - s1)) * CLHEP::cm,
343 posTrack, lr, newLrRaw, newLr, speed, hitWeight);
344 tofBefore += (sint - s1) / speedInCmPerNs;
345 eLossInCell = eLoss * (sint - s1) / s_in_layer;
346 kinEnergyBefore -= eLossInCell;
347 if (kinEnergyBefore >= 0.) {
348 momBefore =
sqrt(kinEnergyBefore * (kinEnergyBefore + 2.*mass));
350 B2WARNING(
"CDCSensitiveDetector: Kinetic Energy < 0.");
356 const G4double test = (s2 - sint) / s_in_layer;
357 if (test < 0. || test > 1.) {
358 B2WARNING(
"CDCSensitiveDetector: Strange path length: " <<
"s2= " << s2 <<
" sint= " << sint <<
" s_in_layer= " << s_in_layer <<
361 edep_in_cell = edep * std::abs((s2 - sint)) / s_in_layer;
363 const G4ThreeVector x_In(vent[0]*CLHEP::cm, vent[1]*CLHEP::cm, vent[2]*CLHEP::cm);
364 const G4ThreeVector p_In(momBefore * vent[3], momBefore * vent[4], momBefore * vent[5]);
366 saveSimHit(layerIDWithLayerOffset, wires[i], trackID, pid, distance, tofBefore, edep_in_cell, std::abs((s2 - sint)) * CLHEP::cm,
369 posOut, posTrack, lr, newLrRaw, newLr, speed, hitWeight);
452 const G4double venter[6],
453 const G4double vexit[6],
454 const G4double s1,
const G4double s2,
456 G4double& sint, G4int& iflag)
482 G4double div =
m_cdcgp->nWiresInLayer(layerId);
486 B2ERROR(
"CDCSensitiveDetector: s1(=" << s1 <<
") > s2(=" << s2 <<
")");
488 if (std::abs(ic1 - ic2) != 1) {
489 if (ic1 == 1 && ic2 == div) {
490 }
else if (ic1 == div && ic2 == 1) {
492 B2ERROR(
"CDCSensitiveDetector: |ic1 - ic2| != 1 in CellBound; " <<
"ic1=" << ic1 <<
" " <<
"ic2=" << ic2);
497 G4double xwb = (
m_cdcgp->wireBackwardPosition(layerId, ic1 - 1)).x();
498 G4double ywb = (
m_cdcgp->wireBackwardPosition(layerId, ic1 - 1)).y();
499 G4double zwb = (
m_cdcgp->wireBackwardPosition(layerId, ic1 - 1)).z();
500 G4double xwf = (
m_cdcgp->wireForwardPosition(layerId, ic1 - 1)).x();
501 G4double ywf = (
m_cdcgp->wireForwardPosition(layerId, ic1 - 1)).y();
502 G4double zwf = (
m_cdcgp->wireForwardPosition(layerId, ic1 - 1)).z();
505 G4double xx1[6], xx2[6];
506 for (
int i = 0; i < 6; ++i) {
512 G4double psi = double(ic2 - ic1) * CLHEP::pi / div;
513 if (ic1 == 1 && ic2 == div) {
514 psi = -CLHEP::pi / div;
515 }
else if (ic1 == div && ic2 == 1) {
516 psi = CLHEP::pi / div;
518 G4double cospsi = cos(psi);
519 G4double sinpsi = sin(psi);
521 G4double xfwb = cospsi * xwb - sinpsi * ywb;
522 G4double yfwb = sinpsi * xwb + cospsi * ywb;
523 G4double xfwf = cospsi * xwf - sinpsi * ywf;
524 G4double yfwf = sinpsi * xwf + cospsi * ywf;
529 G4double vx = xfwf - xfwb;
530 G4double vy = yfwf - yfwb;
531 G4double vz = zfwf - zfwb;
532 G4double vv =
sqrt(vx * vx + vy * vy + vz * vz);
533 vx /= vv; vy /= vv; vz /= vv;
536 G4double shiftx = (xx1[0] + xx2[0]) * 0.5;
537 G4double shifty = (xx1[1] + xx2[1]) * 0.5;
538 G4double shiftz = (xx1[2] + xx2[2]) * 0.5;
539 G4double shifts = (s1 + s2) * 0.5;
540 G4double xshft = xx1[0] - shiftx;
541 G4double yshft = xx1[1] - shifty;
542 G4double zshft = xx1[2] - shiftz;
543 G4double sshft = s1 - shifts;
546 G4double pabs1 =
sqrt(xx1[3] * xx1[3] + xx1[4] * xx1[4] + xx1[5] * xx1[5]);
547 G4double pabs2 =
sqrt(xx2[3] * xx2[3] + xx2[4] * xx2[4] + xx2[5] * xx2[5]);
549 G4double a[4] = {0.}, b[4] = {0.}, c[4] = {0.};
552 GCUBS(sshft, xshft, xx1[3] / pabs1, xx2[3] / pabs2, a);
553 GCUBS(sshft, yshft, xx1[4] / pabs1, xx2[4] / pabs2, b);
554 GCUBS(sshft, zshft, xx1[5] / pabs1, xx2[5] / pabs2, c);
557 a[1] = xshft / sshft;
558 b[1] = yshft / sshft;
559 c[1] = zshft / sshft;
563 G4double stry(0.), xtry(0.), ytry(0.), ztry(0.);
564 G4double beta(0.), xfw(0.), yfw(0.);
565 G4double sphi(0.), cphi(0.), dphil(0.), dphih(0.);
566 const G4int maxTrials = 100;
567 const G4double eps = 5.e-4;
569 G4double sh = -sshft;
574 xtry = shiftx + a[0] + stry * (a[1] + stry * (a[2] + stry * a[3]));
575 ytry = shifty + b[0] + stry * (b[1] + stry * (b[2] + stry * b[3]));
576 ztry = shiftz + c[0] + stry * (c[1] + stry * (c[2] + stry * c[3]));
577 beta = (ztry - zfwb) / vz;
578 xfw = xfwb + beta * vx;
579 yfw = yfwb + beta * vy;
580 sphi = (xtry * yfw - ytry * xfw);
581 cphi = (xtry * xfw + ytry * yfw);
582 dphil = atan2(sphi, cphi);
586 while (((sh - sl) > eps) && (i < maxTrials)) {
587 stry = 0.5 * (sl + sh);
588 xtry = shiftx + a[0] + stry * (a[1] + stry * (a[2] + stry * a[3]));
589 ytry = shifty + b[0] + stry * (b[1] + stry * (b[2] + stry * b[3]));
590 ztry = shiftz + c[0] + stry * (c[1] + stry * (c[2] + stry * c[3]));
591 beta = (ztry - zfwb) / vz;
592 xfw = xfwb + beta * vx;
593 yfw = yfwb + beta * vy;
595 sphi = (xtry * yfw - ytry * xfw);
596 cphi = (xtry * xfw + ytry * yfw);
597 dphih = atan2(sphi, cphi);
599 if (dphil * dphih > 0.) {
607 if (i >= maxTrials - 1) {
609 B2WARNING(
"CDCSensitiveDetector: No intersection ?");
614 xint[0] = a[0] + sint * (a[1] + sint * (a[2] + sint * a[3]));
615 xint[1] = b[0] + sint * (b[1] + sint * (b[2] + sint * b[3]));
616 xint[2] = c[0] + sint * (c[1] + sint * (c[2] + sint * c[3]));
617 xint[3] = a[1] + sint * (2. * a[2] + 3. * sint * a[3]);
618 xint[4] = b[1] + sint * (2. * b[2] + 3. * sint * b[3]);
619 xint[5] = c[1] + sint * (2. * c[2] + 3. * sint * c[3]);
628 G4double p =
sqrt(xint[3] * xint[3] + xint[4] * xint[4] + xint[5] * xint[5]);
629 xint[3] /= p; xint[4] /= p; xint[5] /= p;
758 const G4double xwf4,
const G4double ywf4,
760 const G4double xp,
const G4double yp,
762 const G4double px,
const G4double py,
764 const G4double B_kG[3],
765 const G4double charge,
const G4int ntryMax,
767 G4double q2[3], G4double q1[3],
793 const G4int ndim = 3;
794 const G4double delta = 1.e-5;
797 G4double xwb, ywb, zwb, xwf, ywf, zwf;
798 G4double xw, yw, zw, xh, yh, zh, pxh, pyh, pzh;
799 G4double fi, fi_corr;
801 G4double dr, fi0, cpa, dz, tanl;
805 G4double sinfi0, cosfi0, sinfi0fi, cosfi0fi;
807 G4double vx, vy, vz, vv, cx, cy, cz, tt[3][3];
810 G4double xx[3], dxx[3], ddxx[3], pp[3];
811 G4double xxtdxx, dxxtdxx, xxtddxx;
815 G4double f, fderiv, deltafi, fact,
eval;
816 G4double dx1, dy1, dx2, dy2, crs,
dot;
821 xwb = xwb4; ywb = ywb4; zwb = zwb4;
822 xwf = xwf4; ywf = ywf4; zwf = zwf4;
824 G4double xxx(xp), yyy(yp), zzz(zp);
825 G4double pxx(px), pyy(py), pzz(pz);
828 Rotat(xwb, ywb, zwb, 1);
829 Rotat(xwf, ywf, zwf, 1);
830 Rotat(xxx, yyy, zzz, 1);
831 Rotat(pxx, pyy, pzz, 1);
833 G4double a[8] = {0.};
834 G4double pt =
sqrt(pxx * pxx + pyy * pyy);
835 a[1] = atan2(-pxx, pyy);
838 a[5] = xxx; a[6] = yyy; a[7] = zzz;
841 vx = xwf - xwb; vy = ywf - ywb; vz = zwf - zwb;
842 vv =
sqrt(vx * vx + vy * vy + vz * vz);
843 vx /= vv; vy /= vv; vz /= vv;
847 if (vx == 0. && vy == 0.) iflg = 1;
850 cx = xwb - vx * (vx * xwb + vy * ywb + vz * zwb);
851 cy = ywb - vy * (vx * xwb + vy * ywb + vz * zwb);
852 cz = zwb - vz * (vx * xwb + vy * ywb + vz * zwb);
855 tt[0][0] = vx * vx - 1.; tt[1][0] = vx * vy; tt[2][0] = vx * vz;
856 tt[0][1] = vy * vx; tt[1][1] = vy * vy - 1.; tt[2][1] = vy * vz;
857 tt[0][2] = vz * vx; tt[1][2] = vz * vy; tt[2][2] = vz * vz - 1.;
860 dr = a[0]; fi0 = a[1]; cpa = a[2];
861 dz = a[3]; tanl = a[4];
862 x0 = a[5]; y0 = a[6]; z0 = a[7];
870 G4double bfield =
sqrt(B_kG[0] * B_kG[0] +
873 G4double alpha = 1.e4 / 2.99792458 / bfield;
877 xc = x0 + (dr + r) * cosfi0;
878 yc = y0 + (dr + r) * sinfi0;
883 crs = dx1 * dy2 - dy1 * dx2;
884 dot = dx1 * dx2 + dy1 * dy2;
885 fi = atan2(crs,
dot);
892 cosfi0fi = cos(fi0 + fi);
893 sinfi0fi = sin(fi0 + fi);
896 xx[0] = x0 + dr * cosfi0 + r * (cosfi0 - cosfi0fi);
897 xx[1] = y0 + dr * sinfi0 + r * (sinfi0 - sinfi0fi);
898 xx[2] = z0 + dz - r * tanl * fi;
899 pp[0] = -pt * sinfi0fi;
900 pp[1] = pt * cosfi0fi;
904 q2[0] = xwb; q2[1] = ywb; q2[2] = xx[2];
905 q1[0] = xx[0]; q1[1] = xx[1]; q1[2] = xx[2];
906 q3[0] = pp[0]; q3[1] = pp[1]; q3[2] = pp[2];
911 distance =
sqrt((q2[0] - q1[0]) * (q2[0] - q1[0]) +
912 (q2[1] - q1[1]) * (q2[1] - q1[1]) +
913 (q2[2] - q1[2]) * (q2[2] - q1[2]));
919 dxx[0] = r * sinfi0fi; dxx[1] = - r * cosfi0fi; dxx[2] = - r * tanl;
946 Mvopr(ndim, xx, tt, dxx, tmp, 1);
948 f = cx * dxx[0] + cy * dxx[1] + cz * dxx[2] + xxtdxx;
949 if (std::abs(f) < delta)
goto line100;
953 eval = (1.0 - 0.25 * fact) * std::abs(fst) - std::abs(f);
954 if (
eval <= 0.) fact *= 0.5;
958 ddxx[0] = r * cosfi0fi; ddxx[1] = r * sinfi0fi; ddxx[2] = 0.;
961 Mvopr(ndim, dxx, tt, dxx, tmp, 1);
963 Mvopr(ndim, xx, tt, ddxx, tmp, 1);
965 fderiv = cx * ddxx[0] + cy * ddxx[1] + cz * ddxx[2] + dxxtdxx + xxtddxx;
968 deltafi = f / fderiv;
969 fi -= fact * deltafi;
972 if (ntry > ntryMax) {
982 zh = z0 + dz - r * tanl * fi;
984 if (zh < zwb) fi_corr = (zwb - zh) / (-r * tanl);
985 if (zh > zwf) fi_corr = (zwf - zh) / (-r * tanl);
988 cosfi0fi = cos(fi0 + fi);
989 sinfi0fi = sin(fi0 + fi);
991 xh = x0 + dr * cosfi0 + r * (cosfi0 - cosfi0fi);
992 yh = y0 + dr * sinfi0 + r * (sinfi0 - sinfi0fi);
993 zh = z0 + dz - r * tanl * fi;
994 pxh = -pt * sinfi0fi;
998 zw = vx * vz * xh + vy * vz * yh + vz * vz * zh + zwb - vz * (vx * xwb + vy * ywb + vz * zwb);
999 xw = xwb + vx * (zw - zwb) / vz;
1000 yw = ywb + vy * (zw - zwb) / vz;
1002 q2[0] = xw; q2[1] = yw; q2[2] = zw;
1003 q1[0] = xh; q1[1] = yh; q1[2] = zh;
1004 q3[0] = pxh; q3[1] = pyh; q3[2] = pzh;
1010 distance =
sqrt((q2[0] - q1[0]) * (q2[0] - q1[0]) +
1011 (q2[1] - q1[1]) * (q2[1] - q1[1]) +
1012 (q2[2] - q1[2]) * (q2[2] - q1[2]));