9 #include <framework/gearbox/Gearbox.h>
10 #include <framework/gearbox/GearDir.h>
11 #include <framework/logging/Logger.h>
12 #include <framework/utilities/FileSystem.h>
14 #include <cdc/geometry/CDCGeometryPar.h>
15 #include <cdc/geometry/CDCGeoControlPar.h>
16 #include <cdc/simulation/CDCSimControlPar.h>
17 #include <cdc/utilities/OpenFile.h>
22 #include <boost/format.hpp>
26 #include <boost/iostreams/filtering_stream.hpp>
30 #include <Math/ChebyshevPol.h>
33 using namespace boost;
41 if (!m_B4CDCGeometryParDB) m_B4CDCGeometryParDB =
new CDCGeometryPar(geom);
42 return *m_B4CDCGeometryParDB;
52 if ((*m_t0FromDB).isValid()) {
53 (*m_t0FromDB).
addCallback(
this, &CDCGeometryPar::setT0);
59 if ((*m_badWireFromDB).isValid()) {
60 (*m_badWireFromDB).
addCallback(
this, &CDCGeometryPar::setBadWire);
66 if ((*m_propSpeedFromDB).isValid()) {
67 (*m_propSpeedFromDB).
addCallback(
this, &CDCGeometryPar::setPropSpeed);
73 if ((*m_timeWalkFromDB).isValid()) {
74 (*m_timeWalkFromDB).
addCallback(
this, &CDCGeometryPar::setTW);
80 if ((*m_xtRelFromDB).isValid()) {
81 (*m_xtRelFromDB).
addCallback(
this, &CDCGeometryPar::setXtRel);
87 if ((*m_sResolFromDB).isValid()) {
88 (*m_sResolFromDB).
addCallback(
this, &CDCGeometryPar::setSResol);
94 if ((*m_fFactorFromDB).isValid()) {
95 (*m_fFactorFromDB).
addCallback(
this, &CDCGeometryPar::setFFactor);
101 if ((*m_chMapFromDB).isValid()) {
102 (*m_chMapFromDB).
addCallback(
this, &CDCGeometryPar::setChMap);
108 if ((*m_displacementFromDB).isValid()) {
109 (*m_displacementFromDB).
addCallback(
this, &CDCGeometryPar::setDisplacement);
115 if ((*m_alignmentFromDB).isValid()) {
116 (*m_alignmentFromDB).
addCallback(
this, &CDCGeometryPar::setWirPosAlignParams);
123 if ((*m_misalignmentFromDB).isValid()) {
124 (*m_misalignmentFromDB).
addCallback(
this, &CDCGeometryPar::setWirPosMisalignParams);
132 if ((*m_eDepToADCConversionsFromDB).isValid()) {
133 (*m_eDepToADCConversionsFromDB).
addCallback(
this, &CDCGeometryPar::setEDepToADCConversions);
145 B2WARNING(
"CDCGeometryPar: Strange that readFromDB is not called! Please make sure that CDC is included in Geometry.");
149 CDCGeometryPar::~CDCGeometryPar()
167 void CDCGeometryPar::clear()
169 m_version =
"unknown";
172 m_senseWireDiameter = 0.0;
173 m_senseWireTension = 0.0;
174 m_senseWireDensity = 0.0;
175 m_fieldWireDiameter = 0.0;
178 m_clockFreq4TDC = 0.0;
180 m_nominalDriftV = 0.0;
181 m_nominalPropSpeed = 0.0;
182 m_nominalSpaceResol = 0.0;
184 for (
unsigned i = 0; i < 4; ++i) {
186 for (
unsigned j = 0; j < 2; ++j)
189 for (
unsigned i = 0; i < MAX_N_SLAYERS; ++i) {
191 m_zSForwardLayer[i] = 0;
192 m_zSBackwardLayer[i] = 0;
198 for (
unsigned i = 0; i < MAX_N_FLAYERS; ++i) {
200 m_zFForwardLayer[i] = 0;
201 m_zFBackwardLayer[i] = 0;
204 for (
unsigned L = 0; L < MAX_N_SLAYERS; ++L) {
205 for (
unsigned C = 0; C < MAX_N_SCELLS; ++C) {
206 for (
unsigned i = 0; i < 3; ++i) {
207 m_FWirPos [L][C][i] = 0.;
208 m_BWirPos [L][C][i] = 0.;
209 m_FWirPosMisalign[L][C][i] = 0.;
210 m_BWirPosMisalign[L][C][i] = 0.;
211 m_FWirPosAlign [L][C][i] = 0.;
212 m_BWirPosAlign [L][C][i] = 0.;
214 m_WireSagCoef [L][C] = 0.;
215 m_WireSagCoefMisalign[L][C] = 0.;
216 m_WireSagCoefAlign [L][C] = 0.;
224 m_globalPhiRotation = geom.getGlobalPhiRotation();
228 m_rWall[0] = geom.getInnerWall(2).getRmin();
229 m_zWall[0][0] = geom.getInnerWall(0).getZbwd();
230 m_zWall[0][1] = geom.getInnerWall(0).getZfwd();
232 m_rWall[1] = geom.getInnerWall(0).getRmax();
233 m_zWall[1][0] = geom.getInnerWall(0).getZbwd();
234 m_zWall[1][1] = geom.getInnerWall(0).getZbwd();
237 m_rWall[2] = geom.getOuterWall(0).getRmin();
238 m_zWall[2][0] = geom.getOuterWall(0).getZbwd();
239 m_zWall[2][1] = geom.getOuterWall(0).getZfwd();
241 m_rWall[3] = geom.getOuterWall(1).getRmax();
242 m_zWall[3][0] = geom.getOuterWall(0).getZbwd();
243 m_zWall[3][1] = geom.getOuterWall(0).getZfwd();
246 m_debug = CDCGeoControlPar::getInstance().getDebug();
247 m_nSLayer = geom.getNSenseLayers();
249 m_materialDefinitionMode = CDCGeoControlPar::getInstance().getMaterialDefinitionMode();
251 if (m_materialDefinitionMode == 0) {
252 B2DEBUG(100,
"CDCGeometryPar: Define a mixture of gases and wires in the tracking volume.");
253 }
else if (m_materialDefinitionMode == 2) {
255 B2FATAL(
"CDCGeometryPar: Materialdefinition=2 is disabled for now.");
257 B2FATAL(
"CDCGeometryPar: Materialdefinition mode you specify is invalid.");
261 m_senseWireZposMode = CDCGeoControlPar::getInstance().getSenseWireZposMode();
263 B2DEBUG(100,
"CDCGeometryPar: Sense wire z mode:" << m_senseWireZposMode);
268 GearDir content =
GearDir(
"/Detector/DetectorComponent[@name=\"CDC\"]/Content/");
276 for (
const auto& sense : geom.getSenseLayers()) {
277 int layerId = sense.getId();
278 m_rSLayer[layerId] = sense.getR();
279 m_zSBackwardLayer[layerId] = sense.getZbwd();
280 m_zSForwardLayer[layerId] = sense.getZfwd();
281 m_nWires[layerId] = sense.getNWires();
282 m_nShifts[layerId] = sense.getNShifts();
283 m_offSet[layerId] = sense.getOffset();
284 m_cellSize[layerId] = 2 * M_PI * m_rSLayer[layerId] / (double) m_nWires[layerId];
285 m_dzSBackwardLayer[layerId] = sense.getDZbwd();
286 m_dzSForwardLayer[layerId] = sense.getDZfwd();
289 if (m_senseWireZposMode == 0) {
290 }
else if (m_senseWireZposMode == 1) {
293 m_zSBackwardLayer[layerId] += m_dzSBackwardLayer[layerId];
294 m_zSForwardLayer [layerId] -= m_dzSForwardLayer [layerId];
296 B2FATAL(
"CDCGeometryPar: invalid wire z definition mode specified");
300 const int nWires = m_nWires[layerId];
301 for (
int iCell = 0; iCell < nWires; ++iCell) {
302 setDesignWirParam(layerId, iCell);
308 for (
const auto& field : geom.getFieldLayers()) {
309 int layerId = field.getId();
310 m_rFLayer[layerId] = field.getR();
311 m_zFBackwardLayer[layerId] = field.getZbwd();
312 m_zFForwardLayer[layerId] = field.getZfwd();
316 m_senseWireDiameter = geom.getSenseDiameter();
319 m_senseWireTension = geom.getSenseTension();
322 m_senseWireDensity = 19.3;
325 m_fieldWireDiameter = geom.getFieldDiameter();
328 m_clockFreq4TDC = geom.getClockFrequency();
329 const double officialClockFreq4TDC = 2 * m_clockSettings->getAcceleratorRF();
330 if (m_clockFreq4TDC != officialClockFreq4TDC) {
331 B2WARNING(
"ClockFreq4TDC changed from cdclocal " << scientific << setprecision(6) << m_clockFreq4TDC <<
" to official " <<
332 officialClockFreq4TDC <<
" (GHz)!");
333 m_clockFreq4TDC = officialClockFreq4TDC;
335 B2DEBUG(100,
"CDCGeometryPar: Clock freq. for TDC= " << m_clockFreq4TDC <<
" (GHz).");
336 m_tdcBinWidth = 1. / m_clockFreq4TDC;
337 B2DEBUG(100,
"CDCGeometryPar: TDC bin width= " << m_tdcBinWidth <<
" (ns).");
339 m_nominalDriftV = 4.e-3;
340 m_nominalDriftVInv = 1. / m_nominalDriftV;
341 m_nominalPropSpeed = 27.25;
343 m_nominalSpaceResol = geom.getNominalSpaceResolution();
347 m_displacement = CDCGeoControlPar::getInstance().getDisplacement();
348 B2DEBUG(100,
"CDCGeometryPar: Load displacement params. (=1); not load (=0):" << m_displacement);
349 if (m_displacement) {
351 B2DEBUG(100,
"CDCGeometryPar: Read displacement from DB");
354 readWirePositionParams(c_Base, &geom);
359 m_alignment = CDCGeoControlPar::getInstance().getAlignment();
360 B2DEBUG(100,
"CDCGeometryPar: Load alignment params. (=1); not load (=0):" <<
364 B2DEBUG(100,
"CDCGeometryPar: Read alignment from DB");
365 setWirPosAlignParams();
367 readWirePositionParams(c_Aligned, &geom);
372 m_misalignment = CDCGeoControlPar::getInstance().getMisalignment();
373 B2DEBUG(100,
"CDCGeometryPar: Load misalignment params. (=1); not load (=0):" <<
375 if (m_misalignment) {
377 B2DEBUG(100,
"CDCGeometryPar: Read misalignment from DB");
378 setWirPosMisalignParams();
380 readWirePositionParams(c_Misaligned, &geom);
385 m_thresholdEnergyDeposit = CDCSimControlPar::getInstance().getThresholdEnergyDeposit();
386 m_minTrackLength = CDCSimControlPar::getInstance().getMinTrackLength();
387 m_wireSag = CDCSimControlPar::getInstance().getWireSag();
388 m_modLeftRightFlag = CDCSimControlPar::getInstance().getModLeftRightFlag();
389 if (m_modLeftRightFlag) {
390 B2FATAL(
"ModifiedLeftRightFlag = true is disabled for now; need to update a G4-related code in framework...");
394 m_sigmaFileFormat = 1;
399 B2DEBUG(100,
"CDCGeometryPar: Read xt from DB");
406 B2DEBUG(100,
"CDCGeometryPar: Read sigma from DB");
409 readSigma(gbxParams);
413 B2DEBUG(100,
"CDCGeometryPar: Read fudge factors from DB");
416 readFFactor(gbxParams);
420 B2DEBUG(100,
"CDCGeometryPar: Read prop-speed from DB");
423 readPropSpeed(gbxParams);
427 B2DEBUG(100,
"CDCGeometryPar: Read t0 from DB");
434 B2DEBUG(100,
"CDCGeometryPar: Read badwire from DB");
438 B2FATAL(
"Text file input mode for bdwires is disabled now!");
442 B2DEBUG(100,
"CDCGeometryPar: Read ch-map from DB");
449 B2DEBUG(100,
"CDCGeometryPar: Read time-walk from DB");
454 B2DEBUG(100,
"CDCGeometryPar: Time-walk param. mode= " << m_twParamMode);
457 B2DEBUG(29,
"CDCGeometryPar: Read EDepToADC from DB");
458 if ((*m_eDepToADCConversionsFromDB).isValid()) {
459 setEDepToADCConversions();
462 readEDepToADC(gbxParams);
470 readXT(gbxParams, 1);
471 readSigma(gbxParams, 1);
472 readPropSpeed(gbxParams, 1);
473 readT0(gbxParams, 1);
474 readTW(gbxParams, 1);
478 setShiftInSuperLayer();
530 std::string fileName0;
535 }
else if (set == c_Misaligned) {
537 }
else if (set == c_Aligned) {
543 }
else if (set == c_Misaligned) {
545 }
else if (set == c_Aligned) {
552 boost::iostreams::filtering_istream ifs;
557 double back[np], fwrd[np], tension;
562 for (
int i = 0; i < np; ++i) {
565 for (
int i = 0; i < np; ++i) {
571 if (ifs.eof())
break;
575 for (
int i = 0; i < np; ++i) {
577 m_BWirPos[iL][iC][i] += back[i];
578 m_FWirPos[iL][iC][i] += fwrd[i];
579 }
else if (set == c_Misaligned) {
580 m_BWirPosMisalign[iL][iC][i] = m_BWirPos[iL][iC][i] + back[i];
581 m_FWirPosMisalign[iL][iC][i] = m_FWirPos[iL][iC][i] + fwrd[i];
582 }
else if (set == c_Aligned) {
583 m_BWirPosAlign[iL][iC][i] = m_BWirPos[iL][iC][i] + back[i];
584 m_FWirPosAlign[iL][iC][i] = m_FWirPos[iL][iC][i] + fwrd[i];
591 m_WireSagCoef[iL][iC] = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.*(m_senseWireTension + tension));
593 }
else if (set == c_Misaligned) {
594 double baseTension = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.* m_WireSagCoef[iL][iC]);
595 m_WireSagCoefMisalign[iL][iC] = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.*
596 (baseTension + tension));
598 }
else if (set == c_Aligned) {
599 double baseTension = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.* m_WireSagCoef[iL][iC]);
600 m_WireSagCoefAlign[iL][iC] = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.*(baseTension + tension));
616 if (nRead != nSenseWires) B2FATAL(
"CDCGeometryPar::readWirePositionParams: #lines read-in (=" << nRead <<
617 ") is inconsistent with total #sense wires (=" << nSenseWires <<
") !");
620 boost::iostreams::close(ifs);
625 void CDCGeometryPar::setWirPosAlignParams()
628 for (
unsigned iL = 0; iL < MAX_N_SLAYERS; ++iL) {
630 auto layerID =
WireID(iL, 511);
633 double d_layerXbwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerX);
634 double d_layerYbwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerY);
635 double d_layerPhiBwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerPhi);
637 double d_layerXfwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerDx) + d_layerXbwd;
638 double d_layerYfwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerDy) + d_layerYbwd;
639 double d_layerPhiFwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerDPhi) + d_layerPhiBwd;
641 for (
unsigned iC = 0; iC < m_nWires[iL]; ++iC) {
643 double wireXbwd = m_BWirPos[iL][iC][0];
644 double wireYbwd = m_BWirPos[iL][iC][1];
645 double wireZbwd = m_BWirPos[iL][iC][2];
647 double wireXfwd = m_FWirPos[iL][iC][0];
648 double wireYfwd = m_FWirPos[iL][iC][1];
649 double wireZfwd = m_FWirPos[iL][iC][2];
653 m_BWirPosAlign[iL][iC][0] = d_layerXbwd + cos(d_layerPhiBwd) * wireXbwd + sin(d_layerPhiBwd) * wireYbwd;
654 m_BWirPosAlign[iL][iC][1] = d_layerYbwd - sin(d_layerPhiBwd) * wireXbwd + cos(d_layerPhiBwd) * wireYbwd;
655 m_BWirPosAlign[iL][iC][2] = wireZbwd;
657 m_FWirPosAlign[iL][iC][0] = d_layerXfwd + cos(d_layerPhiFwd) * wireXfwd + sin(d_layerPhiFwd) * wireYfwd;
658 m_FWirPosAlign[iL][iC][1] = d_layerYfwd - sin(d_layerPhiFwd) * wireXfwd + cos(d_layerPhiFwd) * wireYfwd;
659 m_FWirPosAlign[iL][iC][2] = wireZfwd;
664 double back[np], fwrd[np];
666 for (
unsigned iL = 0; iL < MAX_N_SLAYERS; ++iL) {
667 for (
unsigned iC = 0; iC < m_nWires[iL]; ++iC) {
670 back[0] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireBwdX);
671 back[1] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireBwdY);
672 back[2] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireBwdZ);
674 fwrd[0] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireFwdX);
675 fwrd[1] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireFwdY);
676 fwrd[2] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireFwdZ);
678 for (
int i = 0; i < np; ++i) {
681 m_BWirPosAlign[iL][iC][i] += back[i];
682 m_FWirPosAlign[iL][iC][i] += fwrd[i];
686 double baseTension = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.* m_WireSagCoef[iL][iC]);
687 double tension = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireTension);
689 m_WireSagCoefAlign[iL][iC] = M_PI * m_senseWireDensity *
690 m_senseWireDiameter * m_senseWireDiameter / (8.*(baseTension + tension));
699 void CDCGeometryPar::setWirPosMisalignParams()
702 double back[np], fwrd[np];
704 for (
unsigned iL = 0; iL < MAX_N_SLAYERS; ++iL) {
705 for (
unsigned iC = 0; iC < m_nWires[iL]; ++iC) {
708 back[0] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireBwdX);
709 back[1] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireBwdY);
710 back[2] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireBwdZ);
712 fwrd[0] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireFwdX);
713 fwrd[1] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireFwdY);
714 fwrd[2] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireFwdZ);
716 for (
int i = 0; i < np; ++i) {
717 m_BWirPosMisalign[iL][iC][i] = m_BWirPos[iL][iC][i] + back[i];
718 m_FWirPosMisalign[iL][iC][i] = m_FWirPos[iL][iC][i] + fwrd[i];
722 double baseTension = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.* m_WireSagCoef[iL][iC]);
723 double tension = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireTension);
725 m_WireSagCoefMisalign[iL][iC] = M_PI * m_senseWireDensity *
726 m_senseWireDiameter * m_senseWireDiameter / (8.*(baseTension + tension));
734 void CDCGeometryPar::readXT(
const GearDir& gbxParams,
const int mode)
736 if (m_xtFileFormat == 0) {
739 newReadXT(gbxParams, mode);
745 void CDCGeometryPar::newReadXT(
const GearDir& gbxParams,
const int mode)
747 m_linearInterpolationOfXT =
true;
749 std::string fileName0 = CDCGeoControlPar::getInstance().getXtFile();
751 fileName0 = gbxParams.
getString(
"xt4ReconFileName");
754 boost::iostreams::filtering_istream ifs;
778 unsigned short nAlphaBins = 0;
779 if (ifs >> nAlphaBins) {
780 if (nAlphaBins == 0 || nAlphaBins > maxNAlphaPoints) B2FATAL(
"Fail to read alpha bins !");
782 B2FATAL(
"Fail to read alpha bins !");
784 m_nAlphaPoints = nAlphaBins;
785 double alpha0, alpha1, alpha2;
786 for (
unsigned short i = 0; i < nAlphaBins; ++i) {
787 ifs >> alpha0 >> alpha1 >> alpha2;
788 m_alphaPoints[i] = alpha2;
792 unsigned short nThetaBins = 0;
793 if (ifs >> nThetaBins) {
794 if (nThetaBins == 0 || nThetaBins > maxNThetaPoints) B2FATAL(
"CDCGeometryPar: fail to read theta bins !");
796 B2FATAL(
"CDCGeometryPar: fail to read theta bins !");
798 m_nThetaPoints = nThetaBins;
799 double theta0, theta1, theta2;
801 for (
unsigned short i = 0; i < nThetaBins; ++i) {
802 ifs >> theta0 >> theta1 >> theta2;
803 m_thetaPoints[i] = theta2;
807 unsigned short iCL, iLR;
808 const unsigned short npx = nXTParams - 1;
810 double theta, alpha, dummy1;
813 ifs >> m_xtParamMode >> np;
814 if (m_xtParamMode < 0 || m_xtParamMode > 3) B2FATAL(
"CDCGeometryPar: invalid xt-parameterization mode read !");
816 if (np <= 0 || np > npx) B2FATAL(
"CDCGeometryPar: no. of xt-params. outside limits !");
818 const double epsi = 0.1;
821 ifs >> theta >> alpha >> dummy1 >> iLR;
822 for (
int i = 0; i < np; ++i) {
828 for (
unsigned short i = 0; i < nThetaBins; ++i) {
829 if (fabs(theta - m_thetaPoints[i]) < epsi) {
834 if (itheta < 0) B2FATAL(
"CDCGeometryPar: thetas in xt.dat are inconsistent !");
837 for (
unsigned short i = 0; i < nAlphaBins; ++i) {
838 if (fabs(alpha - m_alphaPoints[i]) < epsi) {
843 if (ialpha < 0) B2FATAL(
"CDCGeometryPar: alphas in xt.dat are inconsistent !");
845 for (
int i = 0; i < np; ++i) {
846 m_XT[iCL][iLR][ialpha][itheta][i] = xtc[i];
849 double boundT = xtc[6];
850 if (m_xtParamMode == 1) {
851 m_XT[iCL][iLR][ialpha][itheta][np] = ROOT::Math::Chebyshev5(boundT, xtc[0], xtc[1], xtc[2], xtc[3], xtc[4], xtc[5]);
853 m_XT[iCL][iLR][ialpha][itheta][np] =
864 boost::iostreams::close(ifs);
867 const double degrad = M_PI / 180.;
868 for (
unsigned i = 0; i < nAlphaBins; ++i) {
869 m_alphaPoints[i] *= degrad;
871 for (
unsigned i = 0; i < nThetaBins; ++i) {
872 m_thetaPoints[i] *= degrad;
879 void CDCGeometryPar::readSigma(
const GearDir& gbxParams,
const int mode)
881 if (m_sigmaFileFormat == 0) {
884 newReadSigma(gbxParams, mode);
888 void CDCGeometryPar::newReadSigma(
const GearDir& gbxParams,
const int mode)
890 m_linearInterpolationOfSgm =
true;
892 std::string fileName0 = CDCGeoControlPar::getInstance().getSigmaFile();
894 fileName0 = gbxParams.
getString(
"sigma4ReconFileName");
902 unsigned short nAlphaBins = 0;
903 if (ifs >> nAlphaBins) {
904 if (nAlphaBins == 0 || nAlphaBins > maxNAlphaPoints) B2FATAL(
"Fail to read alpha bins !");
906 B2FATAL(
"Fail to read alpha bins !");
908 m_nAlphaPoints4Sgm = nAlphaBins;
910 double alpha0, alpha1, alpha2;
911 for (
unsigned short i = 0; i < nAlphaBins; ++i) {
912 ifs >> alpha0 >> alpha1 >> alpha2;
913 m_alphaPoints4Sgm[i] = alpha2;
918 unsigned short nThetaBins = 0;
919 if (ifs >> nThetaBins) {
920 if (nThetaBins == 0 || nThetaBins > maxNThetaPoints) B2FATAL(
"CDCGeometryPar: fail to read theta bins !");
922 B2FATAL(
"CDCGeometryPar: fail to read theta bins !");
924 m_nThetaPoints4Sgm = nThetaBins;
926 double theta0, theta1, theta2;
928 for (
unsigned short i = 0; i < nThetaBins; ++i) {
929 ifs >> theta0 >> theta1 >> theta2;
930 m_thetaPoints4Sgm[i] = theta2;
934 unsigned short np = 0;
935 unsigned short iCL, iLR;
936 double sigma[nSigmaParams];
940 ifs >> m_sigmaParamMode >> np;
942 if (m_sigmaParamMode < 0 || m_sigmaParamMode > 4) B2FATAL(
"CDCGeometryPar: invalid sigma-parameterization mode read !");
944 if (np > nSigmaParams) B2FATAL(
"CDCGeometryPar: no. of sigma-params. outside limits !");
946 ifs >> m_maxSpaceResol;
948 const double epsi = 0.1;
951 ifs >> theta >> alpha >> iLR;
953 for (
int i = 0; i < np; ++i) {
959 for (
unsigned short i = 0; i < nThetaBins; ++i) {
960 if (fabs(theta - m_thetaPoints4Sgm[i]) < epsi) {
965 if (itheta < 0) B2FATAL(
"CDCGeometryPar: thetas in sigma.dat are inconsistent !");
968 for (
unsigned short i = 0; i < nAlphaBins; ++i) {
969 if (fabs(alpha - m_alphaPoints4Sgm[i]) < epsi) {
974 if (ialpha < 0) B2FATAL(
"CDCGeometryPar: alphas in sigma.dat are inconsistent !");
976 for (
int i = 0; i < np; ++i) {
977 m_Sigma[iCL][iLR][ialpha][itheta][i] = sigma[i];
984 const double degrad = M_PI / 180.;
985 for (
unsigned i = 0; i < nAlphaBins; ++i) {
986 m_alphaPoints4Sgm[i] *= degrad;
988 for (
unsigned i = 0; i < nThetaBins; ++i) {
989 m_thetaPoints4Sgm[i] *= degrad;
997 void CDCGeometryPar::readFFactor(
const GearDir& gbxParams,
const int mode)
999 std::string fileName0 = CDCGeoControlPar::getInstance().getFFactorFile();
1001 fileName0 = gbxParams.
getString(
"fudgeFactorFileName");
1003 B2WARNING(
"readFFactor is not ready! " << fileName0);
1009 void CDCGeometryPar::readPropSpeed(
const GearDir& gbxParams,
const int mode)
1011 std::string fileName0 = CDCGeoControlPar::getInstance().getPropSpeedFile();
1013 fileName0 = gbxParams.
getString(
"propSpeed4ReconFileName");
1026 if (ifs.eof())
break;
1030 m_propSpeedInv[iL] = 1. / speed;
1032 if (m_debug) B2DEBUG(150, iL <<
" " << speed);
1035 if (nRead != MAX_N_SLAYERS) B2FATAL(
"CDCGeometryPar::readPropSpeed: #lines read-in (=" << nRead <<
1036 ") is inconsistent with total #layers (=" << MAX_N_SLAYERS <<
") !");
1077 void CDCGeometryPar::readT0(
const GearDir& gbxParams,
int mode)
1079 std::string fileName0 = CDCGeoControlPar::getInstance().getT0File();
1081 fileName0 = gbxParams.
getString(
"t04ReconFileName");
1093 ifs >> iL >> iC >> t0;
1095 if (ifs.eof())
break;
1102 B2DEBUG(150, iL <<
" " << iC <<
" " << t0);
1106 if (nRead != nSenseWires) B2FATAL(
"CDCGeometryPar::readT0: #lines read-in (=" << nRead <<
1107 ") is inconsistent with total #sense wires (=" << nSenseWires <<
") !");
1154 void CDCGeometryPar::readTW(
const GearDir& gbxParams,
const int mode)
1156 std::string fileName0 = CDCGeoControlPar::getInstance().getTwFile();
1158 fileName0 = gbxParams.
getString(
"tw4ReconFileName");
1165 unsigned short nPars(0);
1166 ifs >> m_twParamMode >> nPars;
1167 if (m_twParamMode > 1) {
1168 B2FATAL(
"CDCGeometryPar::readTW: invalid mode specified!");
1171 B2FATAL(
"CDCGeometryPar::readTW: invalid #params specified!");
1174 unsigned iBoard = 0;
1177 while (ifs >> iBoard) {
1178 for (
unsigned short i = 0; i < nPars; ++i) {
1179 ifs >> m_timeWalkCoef[iBoard][i];
1184 if (nRead != nBoards) B2FATAL(
"CDCGeometryPar::readTW: #lines read-in (=" << nRead <<
") is inconsistent with #boards (=" << nBoards
1193 void CDCGeometryPar::readChMap()
1195 std::string fileName0 = CDCGeoControlPar::getInstance().getChMapFile();
1201 unsigned short iSL, iL, iW, iB, iC;
1206 ifs >> iSL >> iL >> iW >> iB >> iC;
1207 if (ifs.eof())
break;
1209 if (iSL >= nSuperLayers)
continue;
1212 m_wireToBoard.insert(pair<WireID, unsigned short>(wID, iB));
1215 if (nRead != nSenseWires) B2FATAL(
"CDCGeometryPar::readChMap: #lines read-in (=" << nRead <<
1216 ") is inconsistent with #sense-wires (="
1217 << nSenseWires <<
") !");
1224 void CDCGeometryPar::readEDepToADC(
const GearDir& gbxParams,
const int mode)
1227 std::string fileName0 = CDCGeoControlPar::getInstance().getEDepToADCFile();
1229 fileName0 = gbxParams.
getString(
"fudgeFactorFileName");
1234 std::string fileName1 =
"/data/cdc/" + fileName0;
1235 std::string fileName = FileSystem::findFile(fileName1,
true);
1237 if (fileName ==
"") {
1238 fileName = FileSystem::findFile(fileName0,
true);
1241 if (fileName ==
"") {
1242 B2FATAL(
"CDC::openFile: " << fileName0 <<
" not exist!");
1245 B2DEBUG(29,
"CDC::openFile: open " << fileName);
1246 ifs.open(fileName.c_str());
1247 if (!ifs) B2FATAL(
"CDC::openFile: cannot open " << fileName <<
" !");
1250 unsigned short paramMode(0), nParams(0);
1251 ifs >> paramMode >> nParams;
1252 if (paramMode > 1) B2FATAL(
"Param mode > 1!");
1253 if (nParams > 7) B2FATAL(
"No. of params. > 7!");
1254 unsigned short groupId(0);
1256 B2DEBUG(29, paramMode <<
" " << nParams <<
" " << groupId);
1257 if (groupId > 0) B2FATAL(
"GgroupId > 0!");
1260 unsigned short cLMin[nSuperLayers], cLMax[nSuperLayers];
1263 for (
unsigned int sl = 1; sl < nSuperLayers; ++sl) {
1264 cLMin[sl] = cLMax[0] + 6 * sl - 5;
1265 cLMax[sl] = cLMax[0] + 6 * sl;
1268 unsigned short id = 0;
1270 unsigned short nRead = 0;
1272 for (
unsigned short i = 0; i < nParams; ++i) {
1274 for (
unsigned short cL = cLMin[
id]; cL <= cLMax[id]; ++cL) {
1275 for (
unsigned short cell = 0; cell < m_nWires[cL]; ++cell) {
1276 m_eDepToADCParams[cL][cell][i] = coef;
1282 if (nRead > nSuperLayers) B2FATAL(
"No. of read in lines > " << nSuperLayers <<
" !");
1290 void CDCGeometryPar::setT0()
1292 for (
unsigned short iCL = 0; iCL < MAX_N_SLAYERS; ++iCL) {
1293 for (
unsigned short iW = 0; iW < MAX_N_SCELLS; ++iW) {
1298 for (
auto const& ent : (*m_t0FromDB)->getT0s()) {
1301 const unsigned short iW = wid.
getIWire();
1302 m_t0[iCL][iW] = ent.second;
1310 void CDCGeometryPar::calcMeanT0(
double minT0,
double maxT0,
int maxIt,
double nStdv,
double epsi)
1312 double oldMeanT0 = 0;
1313 unsigned short it1 = 0;
1314 for (
unsigned short it = 0; it < maxIt; ++it) {
1316 double effiSum = 0.;
1319 for (
unsigned short iCL = 0; iCL < MAX_N_SLAYERS; ++iCL) {
1320 for (
unsigned short iW = 0; iW < m_nWires[iCL]; ++iW) {
1321 if (m_t0[iCL][iW] < minT0 || m_t0[iCL][iW] > maxT0)
continue;
1323 if (isHotWire(wid))
continue;
1324 if (isBadWire(wid))
continue;
1326 isDeadWire(wid, effi);
1328 m_meanT0 += effi * m_t0[iCL][iW];
1329 stdvT0 += effi * m_t0[iCL][iW] * m_t0[iCL][iW];
1333 m_meanT0 /= effiSum;
1335 stdvT0 = sqrt(fabs(stdvT0 - m_meanT0 * m_meanT0));
1336 B2DEBUG(29, it <<
" " << effiSum <<
" " << m_meanT0 <<
" " << stdvT0);
1337 if (fabs(m_meanT0 - oldMeanT0) < epsi)
break;
1338 oldMeanT0 = m_meanT0;
1339 minT0 = m_meanT0 - nStdv * stdvT0;
1340 maxT0 = m_meanT0 + nStdv * stdvT0;
1342 B2FATAL(
"Wire efficiency sum <= 0!");
1345 if (it1 == maxIt - 1) B2WARNING(
"Max. iterations(=" << maxIt <<
") needed to calculte the mean t0. Strange.");
1350 void CDCGeometryPar::setBadWire()
1358 void CDCGeometryPar::setPropSpeed()
1360 for (
unsigned short iCL = 0; iCL < (*m_propSpeedFromDB)->getEntries(); ++iCL) {
1361 m_propSpeedInv[iCL] = 1. / (*m_propSpeedFromDB)->getSpeed(iCL);
1367 void CDCGeometryPar::setTW()
1370 m_twParamMode = (*m_timeWalkFromDB)->getTwParamMode();
1372 for (
unsigned short iBd = 0; iBd < (*m_timeWalkFromDB)->getEntries(); ++iBd) {
1373 int np = ((*m_timeWalkFromDB)->getTimeWalkParams(iBd)).size();
1374 for (
int i = 0; i < np; ++i) {
1375 m_timeWalkCoef[iBd][i] = ((*m_timeWalkFromDB)->getTimeWalkParams(iBd))[i];
1382 void CDCGeometryPar::setXtRel()
1384 m_linearInterpolationOfXT =
true;
1387 m_nAlphaPoints = (*m_xtRelFromDB)->getNoOfAlphaBins();
1388 for (
unsigned short i = 0; i < m_nAlphaPoints; ++i) {
1389 m_alphaPoints[i] = (*m_xtRelFromDB)->getAlphaPoint(i);
1393 m_nThetaPoints = (*m_xtRelFromDB)->getNoOfThetaBins();
1394 for (
unsigned short i = 0; i < m_nThetaPoints; ++i) {
1395 m_thetaPoints[i] = (*m_xtRelFromDB)->getThetaPoint(i);
1399 m_xtParamMode = (*m_xtRelFromDB)->getXtParamMode();
1401 for (
unsigned short iCL = 0; iCL < MAX_N_SLAYERS; ++iCL) {
1402 for (
unsigned short iLR = 0; iLR < 2; ++iLR) {
1403 for (
unsigned short iA = 0; iA < m_nAlphaPoints; ++iA) {
1404 for (
unsigned short iT = 0; iT < m_nThetaPoints; ++iT) {
1405 const std::vector<float> params = (*m_xtRelFromDB)->getXtParams(iCL, iLR, iA, iT);
1406 unsigned short np = params.size();
1408 for (
unsigned short i = 0; i < np; ++i) {
1409 m_XT[iCL][iLR][iA][iT][i] = params[i];
1412 double boundT = m_XT[iCL][iLR][iA][iT][6];
1413 if (m_xtParamMode == 1) {
1414 m_XT[iCL][iLR][iA][iT][np] = ROOT::Math::Chebyshev5(boundT, m_XT[iCL][iLR][iA][iT][0], m_XT[iCL][iLR][iA][iT][1],
1415 m_XT[iCL][iLR][iA][iT][2], m_XT[iCL][iLR][iA][iT][3], m_XT[iCL][iLR][iA][iT][4], m_XT[iCL][iLR][iA][iT][5]);
1417 m_XT[iCL][iLR][iA][iT][np] =
1418 m_XT[iCL][iLR][iA][iT][0] + boundT
1419 * (m_XT[iCL][iLR][iA][iT][1] + boundT
1420 * (m_XT[iCL][iLR][iA][iT][2] + boundT
1421 * (m_XT[iCL][iLR][iA][iT][3] + boundT
1422 * (m_XT[iCL][iLR][iA][iT][4] + boundT
1423 * (m_XT[iCL][iLR][iA][iT][5])))));
1434 void CDCGeometryPar::setSResol()
1436 m_linearInterpolationOfSgm =
true;
1439 m_nAlphaPoints4Sgm = (*m_sResolFromDB)->getNoOfAlphaBins();
1440 for (
unsigned short i = 0; i < m_nAlphaPoints4Sgm; ++i) {
1441 m_alphaPoints4Sgm[i] = (*m_sResolFromDB)->getAlphaPoint(i);
1445 m_nThetaPoints4Sgm = (*m_sResolFromDB)->getNoOfThetaBins();
1446 for (
unsigned short i = 0; i < m_nThetaPoints4Sgm; ++i) {
1447 m_thetaPoints4Sgm[i] = (*m_sResolFromDB)->getThetaPoint(i);
1454 m_sigmaParamMode = (*m_sResolFromDB)->getSigmaParamMode();
1456 m_maxSpaceResol = (*m_sResolFromDB)->getMaxSpaceResol();
1458 for (
unsigned short iCL = 0; iCL < MAX_N_SLAYERS; ++iCL) {
1459 for (
unsigned short iLR = 0; iLR < 2; ++iLR) {
1460 for (
unsigned short iA = 0; iA < m_nAlphaPoints4Sgm; ++iA) {
1461 for (
unsigned short iT = 0; iT < m_nThetaPoints4Sgm; ++iT) {
1462 const std::vector<float> params = (*m_sResolFromDB)->getSigmaParams(iCL, iLR, iA, iT);
1463 unsigned short np = params.size();
1465 for (
unsigned short i = 0; i < np; ++i) {
1466 m_Sigma[iCL][iLR][iA][iT][i] = params[i];
1477 void CDCGeometryPar::setFFactor()
1479 unsigned short groupId = (*m_fFactorFromDB)->getGroupID();
1480 unsigned short nEnt = (*m_fFactorFromDB)->getEntries();
1481 B2DEBUG(29,
"setFFactor called: groupId,nEnt= " << groupId <<
" " << nEnt);
1485 B2FATAL(
"CDCGeometryPar:: Invalid group-id " << groupId <<
" specified!");
1488 for (
unsigned short id = 0;
id < nEnt; ++id) {
1489 unsigned short np = ((*m_fFactorFromDB)->getFactors(
id)).size();
1490 if (np != 3) B2FATAL(
"CDCGeometryPar:: No. of fudge factors != 3!");
1492 for (
unsigned short i = 0; i < np; ++i) {
1493 m_fudgeFactorForSigma[i] = ((*m_fFactorFromDB)->getFactors(
id))[i];
1494 B2DEBUG(29, i <<
" " << m_fudgeFactorForSigma[i]);
1502 B2DEBUG(29,
"fudge factors= " << m_fudgeFactorForSigma[0] <<
" " << m_fudgeFactorForSigma[1] <<
" " << m_fudgeFactorForSigma[2]);
1507 void CDCGeometryPar::setChMap()
1509 for (
const auto& cm : (*m_chMapFromDB)) {
1510 const unsigned short isl = cm.getISuperLayer();
1511 if (isl >= nSuperLayers)
continue;
1512 const int il = cm.getILayer();
1513 const int iw = cm.getIWire();
1514 const int iBd = cm.getBoardID();
1515 const WireID wID(isl, il, iw);
1516 m_wireToBoard.insert(pair<WireID, unsigned short>(wID, iBd));
1517 const int iCh = cm.getBoardChannel();
1518 m_wireToChannel.insert(pair<WireID, unsigned short>(wID, iCh));
1519 m_boardAndChannelToWire[iBd][iCh] = wID.
getEWire();
1524 void CDCGeometryPar::setEDepToADCConversions()
1526 unsigned short groupId = (*m_eDepToADCConversionsFromDB)->getGroupID();
1527 unsigned short nEnt = (*m_eDepToADCConversionsFromDB)->getEntries();
1529 if (nEnt > nSuperLayers) B2FATAL(
"CDCGeometryPar:: group-id " << groupId <<
" and #entries " << nEnt <<
" are inconsistent!");
1530 }
else if (groupId == 1) {
1531 if (nEnt > MAX_N_SLAYERS) B2FATAL(
"CDCGeometryPar:: group-id " << groupId <<
" and #entries " << nEnt <<
" are inconsistent!");
1533 B2FATAL(
"CDCGeometryPar:: Invalid group-id " << groupId <<
" specified !");
1536 unsigned short cLMin[nSuperLayers], cLMax[nSuperLayers];
1539 for (
unsigned int sl = 1; sl < nSuperLayers; ++sl) {
1540 cLMin[sl] = cLMax[0] + 6 * sl - 5;
1541 cLMax[sl] = cLMax[0] + 6 * sl;
1544 for (
unsigned short id = 0;
id < nEnt; ++id) {
1545 unsigned short np = ((*m_eDepToADCConversionsFromDB)->getParams(
id)).size();
1546 if (np > 7) B2FATAL(
"CDCGeometryPar:: No. of edep-to-ADC conversion params. > 7");
1548 for (
unsigned short cL = cLMin[
id]; cL <= cLMax[id]; ++cL) {
1549 for (
unsigned short cell = 0; cell < m_nWires[cL]; ++cell) {
1550 for (
unsigned short i = 0; i < np; ++i) {
1551 m_eDepToADCParams[cL][cell][i] = ((*m_eDepToADCConversionsFromDB)->getParams(
id))[i];
1555 }
else if (groupId == 1) {
1556 for (
unsigned short cell = 0; cell < m_nWires[id]; ++cell) {
1557 for (
unsigned short i = 0; i < np; ++i) {
1558 m_eDepToADCParams[id][cell][i] = ((*m_eDepToADCConversionsFromDB)->getParams(
id))[i];
1561 }
else if (groupId == 2) {
1563 B2FATAL(
"CDCGeometryPar::setEDepToADCConversions(): groupId=2 not ready!");
1569 double CDCGeometryPar::getEDepToADCConvFactor(
unsigned short iCL,
unsigned short iW,
double edep,
double dx,
double costh)
1576 const double mainF = m_eDepToADCParams[iCL][iW][0];
1577 const double& alf = m_eDepToADCParams[iCL][iW][1];
1578 const double& gam = m_eDepToADCParams[iCL][iW][2];
1579 const double& dlt = m_eDepToADCParams[iCL][iW][3];
1580 const double& a = m_eDepToADCParams[iCL][iW][4];
1581 const double& b = m_eDepToADCParams[iCL][iW][5];
1582 const double cth = fabs(costh) + dlt;
1583 const double iGen = edep / dx;
1584 const double tmp = cth - gam * iGen;
1585 const double disc = tmp * tmp + 4.*alf * cth * iGen;
1589 iMea = cth * iGen / tmp;
1590 }
else if (disc >= 0.) {
1591 iMea = (-tmp + sqrt(disc)) / (2.*alf);
1599 double convF = mainF;
1601 convF = mainF * std::min(iMea / iGen, 1.);
1610 convF *= 1. + a * (costh - b);
1615 void CDCGeometryPar::Print()
const
1618 const TVector3 CDCGeometryPar::wireForwardPosition(
int layerID,
int cellID,
EWirePosition set)
const
1621 TVector3 wPos(m_FWirPosAlign[layerID][cellID][0],
1622 m_FWirPosAlign[layerID][cellID][1],
1623 m_FWirPosAlign[layerID][cellID][2]);
1625 if (set == c_Misaligned) {
1626 wPos.SetX(m_FWirPosMisalign[layerID][cellID][0]);
1627 wPos.SetY(m_FWirPosMisalign[layerID][cellID][1]);
1628 wPos.SetZ(m_FWirPosMisalign[layerID][cellID][2]);
1629 }
else if (set == c_Base) {
1630 wPos.SetX(m_FWirPos [layerID][cellID][0]);
1631 wPos.SetY(m_FWirPos [layerID][cellID][1]);
1632 wPos.SetZ(m_FWirPos [layerID][cellID][2]);
1637 const TVector3 CDCGeometryPar::wireForwardPosition(
int layerID,
int cellID,
double z,
EWirePosition set)
const
1641 getWireSagEffect(set, layerID, cellID, z, yb_sag, yf_sag);
1643 TVector3 wPos(m_FWirPosAlign[layerID][cellID][0], yf_sag,
1644 m_FWirPosAlign[layerID][cellID][2]);
1645 if (set == c_Misaligned) {
1646 wPos.SetX(m_FWirPosMisalign[layerID][cellID][0]);
1647 wPos.SetZ(m_FWirPosMisalign[layerID][cellID][2]);
1648 }
else if (set == c_Base) {
1649 wPos.SetX(m_FWirPos [layerID][cellID][0]);
1650 wPos.SetZ(m_FWirPos [layerID][cellID][2]);
1655 const TVector3 CDCGeometryPar::wireBackwardPosition(
int layerID,
int cellID,
EWirePosition set)
const
1657 TVector3 wPos(m_BWirPosAlign[layerID][cellID][0],
1658 m_BWirPosAlign[layerID][cellID][1],
1659 m_BWirPosAlign[layerID][cellID][2]);
1661 if (set == c_Misaligned) {
1662 wPos.SetX(m_BWirPosMisalign[layerID][cellID][0]);
1663 wPos.SetY(m_BWirPosMisalign[layerID][cellID][1]);
1664 wPos.SetZ(m_BWirPosMisalign[layerID][cellID][2]);
1665 }
else if (set == c_Base) {
1666 wPos.SetX(m_BWirPos [layerID][cellID][0]);
1667 wPos.SetY(m_BWirPos [layerID][cellID][1]);
1668 wPos.SetZ(m_BWirPos [layerID][cellID][2]);
1673 const TVector3 CDCGeometryPar::wireBackwardPosition(
int layerID,
int cellID,
double z,
EWirePosition set)
const
1677 getWireSagEffect(set, layerID, cellID, z, yb_sag, yf_sag);
1679 TVector3 wPos(m_BWirPosAlign[layerID][cellID][0], yb_sag,
1680 m_BWirPosAlign[layerID][cellID][2]);
1681 if (set == c_Misaligned) {
1682 wPos.SetX(m_BWirPosMisalign[layerID][cellID][0]);
1683 wPos.SetZ(m_BWirPosMisalign[layerID][cellID][2]);
1684 }
else if (set == c_Base) {
1685 wPos.SetX(m_BWirPos [layerID][cellID][0]);
1686 wPos.SetZ(m_BWirPos [layerID][cellID][2]);
1691 double CDCGeometryPar::getWireSagCoef(
EWirePosition set,
int layerID,
int cellID)
const
1693 double coef = m_WireSagCoef[layerID][cellID];
1694 if (set == c_Misaligned) {
1695 coef = m_WireSagCoefMisalign[layerID][cellID];
1696 }
else if (set == c_Aligned) {
1697 coef = m_WireSagCoefAlign [layerID][cellID];
1702 const double* CDCGeometryPar::innerRadiusWireLayer()
const
1704 static double IRWL[MAX_N_SLAYERS] = {0};
1706 IRWL[0] = outerRadiusInnerWall();
1707 for (
unsigned i = 1; i < nWireLayers(); i++)
1709 IRWL[i] = m_rFLayer[i - 1];
1714 const double* CDCGeometryPar::outerRadiusWireLayer()
const
1716 static double ORWL[MAX_N_SLAYERS] = {0};
1718 ORWL[nWireLayers() - 1] = innerRadiusOuterWall();
1719 for (
unsigned i = 0; i < nWireLayers() - 1; i++)
1721 ORWL[i] = m_rFLayer[i];
1726 unsigned CDCGeometryPar::cellId(
unsigned layerId,
const TVector3& position)
const
1728 const unsigned nWires = m_nWires[layerId];
1730 double offset = m_offSet[layerId];
1732 const double phiSize = 2 * M_PI / double(nWires);
1749 for (
unsigned i = 0; i < 1; ++i) {
1750 const double phiF = phiSize * (double(i) + offset)
1751 + phiSize * 0.5 *
double(m_nShifts[layerId]) + m_globalPhiRotation;
1752 const double phiB = phiSize * (double(i) + offset) + m_globalPhiRotation;
1753 const TVector3 f(m_rSLayer[layerId] * cos(phiF), m_rSLayer[layerId] * sin(phiF), m_zSForwardLayer[layerId]);
1754 const TVector3 b(m_rSLayer[layerId] * cos(phiB), m_rSLayer[layerId] * sin(phiB), m_zSBackwardLayer[layerId]);
1755 const TVector3 v = f - b;
1756 const TVector3 u = v.Unit();
1757 const double beta = (position.z() - b.z()) / u.z();
1758 const TVector3 p = b + beta * u;
1759 double dPhi = std::atan2(position.y(), position.x())
1760 - std::atan2(p.y(), p.x())
1762 while (dPhi < 0) dPhi += (2. * M_PI);
1763 j = int(dPhi / phiSize);
1764 while (j >= nWires) j -= nWires;
1770 void CDCGeometryPar::generateXML(
const string& of)
1773 std::ofstream ofs(of.c_str(), std::ios::out);
1775 B2ERROR(
"CDCGeometryPar::read !!! can not open file : "
1778 ofs <<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1780 <<
"<Subdetector type=\"CDC\">"
1782 <<
" <Name>CDC BelleII </Name>"
1784 <<
" <Description>CDC geometry parameters</Description>"
1786 <<
" <Version>0</Version>"
1788 <<
" <GeoCreator>CDCBelleII</GeoCreator>"
1792 <<
" <Rotation desc=\"Rotation of the whole cdc detector (should be the same as beampipe)\" unit=\"mrad\">0.0</Rotation>"
1794 <<
" <OffsetZ desc=\"The offset of the whole cdc in z with respect to the IP (should be the same as beampipe)\" unit=\"mm\">0.0</OffsetZ>"
1796 <<
" <Material>CDCGas</Material>"
1800 ofs <<
" <SLayers>" << endl;
1802 for (
int i = 0; i < m_nSLayer; i++) {
1803 ofs <<
" <SLayer id=\"" << i <<
"\">" << endl;
1804 ofs <<
" <Radius desc=\"Radius of wires in this layer\" unit=\"mm\">" << senseWireR(i) <<
"</Radius>" << endl;
1805 ofs <<
" <BackwardZ desc=\"z position of this wire layer at backward endplate\" unit=\"mm\">" << senseWireBZ(
1806 i) <<
"</BackwardZ>" << endl;
1807 ofs <<
" <ForwardZ desc=\"z position of this wire layer at forward endplate\" unit=\"mm\">" << senseWireFZ(
1808 i) <<
"</ForwardZ>" << endl;
1811 ofs <<
" <NHoles desc=\"the number of holes in this layer, 2*(cell number)\">" << nWiresInLayer(
1812 i) * 2 <<
"</NHoles>" << endl;
1813 ofs <<
" <NShift desc=\"the shifted hole number of each wire in this layer\">" << nShifts(i) <<
"</NShift>" << endl;
1814 ofs <<
" <Offset desc=\"wire offset in phi direction at endplate\">" << m_offSet[i] <<
"</Offset>" << endl;
1815 ofs <<
" </SLayer>" << endl;
1818 ofs <<
" </SLayers>" << endl;
1819 ofs <<
" <FLayers>" << endl;
1821 for (
int i = 0; i < m_nFLayer; i++) {
1822 ofs <<
" <FLayer id=\"" << i <<
"\">" << endl;
1823 ofs <<
" <Radius desc=\"Radius of field wires in this layer\" unit=\"mm\">" << fieldWireR(i) <<
"</Radius>" << endl;
1824 ofs <<
" <BackwardZ desc=\"z position of this field wire layer at backward endplate\" unit=\"mm\">" << fieldWireBZ(
1825 i) <<
"</BackwardZ>" << endl;
1826 ofs <<
" <ForwardZ desc=\"z position of this field wire layer at forward endplate\" unit=\"mm\">" << fieldWireFZ(
1827 i) <<
"</ForwardZ>" << endl;
1828 ofs <<
" </FLayer>" << endl;
1831 ofs <<
" </FLayers>" << endl;
1833 ofs <<
" <InnerWall name=\"InnerWall\">" << endl;
1834 ofs <<
" <InnerR desc=\"Inner radius\" unit=\"mm\">" << innerRadiusInnerWall() <<
"</InnerR>" << endl;
1835 ofs <<
" <OuterR desc=\"Outer radius\" unit=\"mm\">" << outerRadiusInnerWall() <<
"</OuterR>" << endl;
1836 ofs <<
" <BackwardZ desc=\"z position at backward endplate\" unit=\"mm\">" << m_zWall[0][0] <<
"</BackwardZ>" << endl;
1837 ofs <<
" <ForwardZ desc=\"z position at forward endplate\" unit=\"mm\">" << m_zWall[0][1] <<
"</ForwardZ>" << endl;
1838 ofs <<
" </InnerWall>" << endl;
1840 ofs <<
" <OuterWall name=\"OuterWall\">" << endl;
1841 ofs <<
" <InnerR desc=\"Inner radius\" unit=\"mm\">" << innerRadiusOuterWall() <<
"</InnerR>" << endl;
1842 ofs <<
" <OuterR desc=\"Outer radius\" unit=\"mm\">" << outerRadiusOuterWall() <<
"</OuterR>" << endl;
1843 ofs <<
" <BackwardZ desc=\"z position at backward endplate\" unit=\"mm\">" << m_zWall[2][0] <<
"</BackwardZ>" << endl;
1844 ofs <<
" <ForwardZ desc=\"z position at forward endplate\" unit=\"mm\">" << m_zWall[2][1] <<
"</ForwardZ>" << endl;
1845 ofs <<
" </OuterWall>" << endl;
1847 ofs <<
" </Content>" << endl
1848 <<
"</Subdetector>" << endl;
1851 void CDCGeometryPar::getWireSagEffect(
const EWirePosition set,
const unsigned layerID,
const unsigned cellID,
const double Z,
1852 double& Yb_sag,
double& Yf_sag)
const
1876 if (set == c_Aligned) {
1877 Coef = m_WireSagCoefAlign[layerID][cellID];
1878 Yb = m_BWirPosAlign[layerID][cellID][1];
1879 Yf = m_FWirPosAlign[layerID][cellID][1];
1885 Xb = m_BWirPosAlign[layerID][cellID][0];
1886 Xf = m_FWirPosAlign[layerID][cellID][0];
1887 Zb = m_BWirPosAlign[layerID][cellID][2];
1888 Zf = m_FWirPosAlign[layerID][cellID][2];
1890 }
else if (set == c_Misaligned) {
1891 Coef = m_WireSagCoefMisalign[layerID][cellID];
1892 Yb = m_BWirPosMisalign[layerID][cellID][1];
1893 Yf = m_FWirPosMisalign[layerID][cellID][1];
1899 Xb = m_BWirPosMisalign[layerID][cellID][0];
1900 Xf = m_FWirPosMisalign[layerID][cellID][0];
1901 Zb = m_BWirPosMisalign[layerID][cellID][2];
1902 Zf = m_FWirPosMisalign[layerID][cellID][2];
1904 }
else if (set == c_Base) {
1905 Coef = m_WireSagCoef[layerID][cellID];
1906 Yb = m_BWirPos[layerID][cellID][1];
1907 Yf = m_FWirPos[layerID][cellID][1];
1913 Xb = m_BWirPos[layerID][cellID][0];
1914 Xf = m_FWirPos[layerID][cellID][0];
1915 Zb = m_BWirPos[layerID][cellID][2];
1916 Zf = m_FWirPos[layerID][cellID][2];
1919 B2FATAL(
"CDCGeometryPar::getWireSagEffect: called with an invalid set: " <<
" " << set);
1922 const double dx = Xf - Xb;
1923 const double dy = Yf - Yb;
1924 const double dz = Zf - Zb;
1926 const double Zfp = sqrt(dz * dz + dx * dx);
1927 const double Zp = (Z - Zb) * Zfp / dz;
1929 const double Y_sag = (Coef * (Zp - Zfp) + dy / Zfp) * Zp + Yb;
1930 const double dydz = (Coef * (2.*Zp - Zfp) * Zfp + dy) / dz;
1932 Yb_sag = Y_sag + dydz * (Zb - Z);
1933 Yf_sag = Y_sag + dydz * (Zf - Z);
1937 void CDCGeometryPar::setDesignWirParam(
const unsigned layerID,
const unsigned cellID)
1939 const unsigned L = layerID;
1940 const unsigned C = cellID;
1942 const double offset = m_offSet[L];
1944 const double phiSize = 2 * M_PI / double(m_nWires[L]);
1946 const double phiF = phiSize * (double(C) + offset)
1947 + phiSize * 0.5 *
double(m_nShifts[L]) + m_globalPhiRotation;
1949 m_FWirPos[L][C][0] = m_rSLayer[L] * cos(phiF);
1950 m_FWirPos[L][C][1] = m_rSLayer[L] * sin(phiF);
1951 m_FWirPos[L][C][2] = m_zSForwardLayer[L];
1953 const double phiB = phiSize * (double(C) + offset) + m_globalPhiRotation;
1955 m_BWirPos[L][C][0] = m_rSLayer[L] * cos(phiB);
1956 m_BWirPos[L][C][1] = m_rSLayer[L] * sin(phiB);
1957 m_BWirPos[L][C][2] = m_zSBackwardLayer[L];
1959 for (
int i = 0; i < 3; ++i) {
1960 m_FWirPosMisalign[L][C][i] = m_FWirPos[L][C][i];
1961 m_BWirPosMisalign[L][C][i] = m_BWirPos[L][C][i];
1962 m_FWirPosAlign [L][C][i] = m_FWirPos[L][C][i];
1963 m_BWirPosAlign [L][C][i] = m_BWirPos[L][C][i];
1966 m_WireSagCoef[L][C] = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8. * m_senseWireTension);
1968 m_WireSagCoefMisalign[L][C] = m_WireSagCoef[L][C];
1969 m_WireSagCoefAlign [L][C] = m_WireSagCoef [L][C];
1973 void CDCGeometryPar::outputDesignWirParam(
const unsigned layerID,
const unsigned cellID)
const
1976 const unsigned L = layerID;
1977 const unsigned C = cellID;
1979 static bool first =
true;
1980 static ofstream ofs;
1983 ofs.open(
"alignment.dat");
1986 ofs << L <<
" " << C;
1988 ofs << setiosflags(ios::showpoint | ios::uppercase);
1990 for (
int i = 0; i < 3; ++i) ofs <<
" " << setw(15) << setprecision(8) << m_BWirPos[L][C][i];
1992 for (
int i = 0; i < 3; ++i) ofs <<
" " << setw(15) << setprecision(8) << m_FWirPos[L][C][i];
1993 ofs << setiosflags(ios::fixed);
1994 ofs <<
" " << setw(4) << setprecision(1) << m_senseWireTension;
1999 double CDCGeometryPar::getDriftV(
const double time,
const unsigned short iCLayer,
const unsigned short lr,
const double alpha,
2000 const double theta)
const
2005 double minTime = getMinDriftTime(iCLayer, lr, alpha, theta);
2006 double delta = time - minTime;
2009 unsigned short lro = getOutgoingLR(lr, alpha);
2011 if (!m_linearInterpolationOfXT) {
2012 B2FATAL(
"linearInterpolationOfXT = false is not allowed now !");
2015 unsigned short ial[2] = {0};
2016 unsigned short ilr[2] = {lro, lro};
2017 getClosestAlphaPoints(alpha, wal, ial, ilr);
2019 unsigned short ith[2] = {0};
2020 getClosestThetaPoints(alpha, theta, wth, ith);
2022 unsigned short jal(0), jlr(0), jth(0);
2026 double timep = delta < 0. ? minTime - delta : time;
2029 for (
unsigned k = 0; k < 4; ++k) {
2034 w = (1. - wal) * (1. - wth);
2035 }
else if (k == 1) {
2039 w = (1. - wal) * wth;
2040 }
else if (k == 2) {
2044 w = wal * (1. - wth);
2045 }
else if (k == 3) {
2052 double boundary = m_XT[iCLayer][jlr][jal][jth][6];
2054 if (timep < boundary) {
2055 if (m_xtParamMode == 1) {
2056 const double& c1 = m_XT[iCLayer][jlr][jal][jth][1];
2057 const double& c2 = m_XT[iCLayer][jlr][jal][jth][2];
2058 const double& c3 = m_XT[iCLayer][jlr][jal][jth][3];
2059 const double& c4 = m_XT[iCLayer][jlr][jal][jth][4];
2060 const double& c5 = m_XT[iCLayer][jlr][jal][jth][5];
2061 dDdt += w * ROOT::Math::Chebyshev4(timep, c1 + 3.*c3 + 5.*c5, 4.*c2 + 8.*c4, 6.*c3 + 10.*c5, 8.*c4, 10.*c5);
2063 dDdt += w * (m_XT[iCLayer][jlr][jal][jth][1] + timep
2064 * (2.*m_XT[iCLayer][jlr][jal][jth][2] + timep
2065 * (3.*m_XT[iCLayer][jlr][jal][jth][3] + timep
2066 * (4.*m_XT[iCLayer][jlr][jal][jth][4] + timep
2067 * (5.*m_XT[iCLayer][jlr][jal][jth][5])))));
2070 dDdt += w * m_XT[iCLayer][jlr][jal][jth][7];
2083 double CDCGeometryPar::getDriftLength0(
const double time,
const unsigned short iCLayer,
const unsigned short lr,
const double alpha,
2084 const double theta)
const
2089 unsigned short lro = getOutgoingLR(lr, alpha);
2093 if (!m_linearInterpolationOfXT) {
2094 B2FATAL(
"linearInterpolationOfXT = false is not allowed now !");
2097 unsigned short ial[2] = {0};
2098 unsigned short ilr[2] = {lro, lro};
2099 getClosestAlphaPoints(alpha, wal, ial, ilr);
2101 unsigned short ith[2] = {0};
2102 getClosestThetaPoints(alpha, theta, wth, ith);
2104 unsigned short jal(0), jlr(0), jth(0);
2108 double timep = time;
2112 for (
unsigned k = 0; k < 4; ++k) {
2117 w = (1. - wal) * (1. - wth);
2118 }
else if (k == 1) {
2122 w = (1. - wal) * wth;
2123 }
else if (k == 2) {
2127 w = wal * (1. - wth);
2128 }
else if (k == 3) {
2135 double boundary = m_XT[iCLayer][jlr][jal][jth][6];
2137 if (timep < boundary) {
2138 if (m_xtParamMode == 1) {
2139 dist += w * ROOT::Math::Chebyshev5(timep, m_XT[iCLayer][jlr][jal][jth][0], m_XT[iCLayer][jlr][jal][jth][1],
2140 m_XT[iCLayer][jlr][jal][jth][2], m_XT[iCLayer][jlr][jal][jth][3], m_XT[iCLayer][jlr][jal][jth][4], m_XT[iCLayer][jlr][jal][jth][5]);
2142 dist += w * (m_XT[iCLayer][jlr][jal][jth][0] + timep
2143 * (m_XT[iCLayer][jlr][jal][jth][1] + timep
2144 * (m_XT[iCLayer][jlr][jal][jth][2] + timep
2145 * (m_XT[iCLayer][jlr][jal][jth][3] + timep
2146 * (m_XT[iCLayer][jlr][jal][jth][4] + timep
2147 * (m_XT[iCLayer][jlr][jal][jth][5]))))));
2150 dist += w * (m_XT[iCLayer][jlr][jal][jth][7] * (timep - boundary) + m_XT[iCLayer][jlr][jal][jth][8]);
2161 double CDCGeometryPar::getDriftLength(
const double time,
const unsigned short iCLayer,
const unsigned short lr,
const double alpha,
2163 const bool calculateMinTime,
2164 const double inputMinTime)
const
2169 double minTime = calculateMinTime ? getMinDriftTime(iCLayer, lr, alpha, theta) : inputMinTime;
2170 double delta = time - minTime;
2173 unsigned short lro = getOutgoingLR(lr, alpha);
2177 if (!m_linearInterpolationOfXT) {
2178 B2FATAL(
"linearInterpolationOfXT = false is not allowed now !");
2181 unsigned short ial[2] = {0};
2182 unsigned short ilr[2] = {lro, lro};
2183 getClosestAlphaPoints(alpha, wal, ial, ilr);
2185 unsigned short ith[2] = {0};
2186 getClosestThetaPoints(alpha, theta, wth, ith);
2188 unsigned short jal(0), jlr(0), jth(0);
2192 double timep = delta < 0. ? minTime - delta : time;
2197 for (
unsigned k = 0; k < 4; ++k) {
2202 w = (1. - wal) * (1. - wth);
2203 }
else if (k == 1) {
2207 w = (1. - wal) * wth;
2208 }
else if (k == 2) {
2212 w = wal * (1. - wth);
2213 }
else if (k == 3) {
2233 double boundary = m_XT[iCLayer][jlr][jal][jth][6];
2235 if (timep < boundary) {
2236 if (m_xtParamMode == 1) {
2237 dist += w * ROOT::Math::Chebyshev5(timep, m_XT[iCLayer][jlr][jal][jth][0], m_XT[iCLayer][jlr][jal][jth][1],
2238 m_XT[iCLayer][jlr][jal][jth][2], m_XT[iCLayer][jlr][jal][jth][3], m_XT[iCLayer][jlr][jal][jth][4], m_XT[iCLayer][jlr][jal][jth][5]);
2240 dist += w * (m_XT[iCLayer][jlr][jal][jth][0] + timep
2241 * (m_XT[iCLayer][jlr][jal][jth][1] + timep
2242 * (m_XT[iCLayer][jlr][jal][jth][2] + timep
2243 * (m_XT[iCLayer][jlr][jal][jth][3] + timep
2244 * (m_XT[iCLayer][jlr][jal][jth][4] + timep
2245 * (m_XT[iCLayer][jlr][jal][jth][5]))))));
2248 dist += w * (m_XT[iCLayer][jlr][jal][jth][7] * (timep - boundary) + m_XT[iCLayer][jlr][jal][jth][8]);
2255 if (delta < 0.) dist *= -1.;
2260 double CDCGeometryPar::getMinDriftTime(
const unsigned short iCLayer,
const unsigned short lr,
const double alpha,
2261 const double theta)
const
2263 double minTime = 0.;
2266 unsigned short lro = getOutgoingLR(lr, alpha);
2268 if (!m_linearInterpolationOfXT) {
2269 B2FATAL(
"linearInterpolationOfXT = false is not allowed now !");
2272 unsigned short ial[2] = {0};
2273 unsigned short ilr[2] = {lro, lro};
2274 getClosestAlphaPoints(alpha, wal, ial, ilr);
2276 unsigned short ith[2] = {0};
2277 getClosestThetaPoints(alpha, theta, wth, ith);
2279 unsigned short jal(0), jlr(0), jth(0);
2282 double c[6] = {0.}, a[6] = {0.};
2283 for (
unsigned k = 0; k < 4; ++k) {
2288 w = (1. - wal) * (1. - wth);
2289 }
else if (k == 1) {
2293 w = (1. - wal) * wth;
2294 }
else if (k == 2) {
2298 w = wal * (1. - wth);
2299 }
else if (k == 3) {
2306 for (
int i = 0; i < 5; ++i) {
2307 c[i] += w * m_XT[iCLayer][jlr][jal][jth][i];
2311 if (m_xtParamMode == 1) {
2312 a[0] = c[0] - c[2] + c[4];
2313 a[1] = c[1] - 3.*c[3] + 5.*c[5];
2314 a[2] = 2.*c[2] - 8.*c[4];
2315 a[3] = 4.*c[3] - 20.*c[5];
2319 for (
int i = 0; i < 5; ++i) a[i] = c[i];
2326 const double det = a[1] * a[1] - 4.*a[2] * a[0];
2329 minTime = (-a[1] + sqrt(det)) / (2.*a[2]);
2333 minTime = -a[1] / (2.*a[2]);
2336 }
else if (a[1] != 0.) {
2337 minTime = -a[0] / a[1];
2339 B2WARNING(
"CDCGeometryPar::getMinDriftTime: minDriftTime not determined; assume zero.\n" <<
"layer(#0-55),lr,alpha(rad),theta= " <<
2340 iCLayer <<
" " << lr <<
" " << alpha <<
" " << theta);
2349 const double epsi4x = 5.e-6;
2351 const unsigned short maxIter = 8;
2352 const double maxDt = 20.;
2353 unsigned short nIter = 0;
2354 double minXsq = 1.e10;
2355 double minMinTime = minTime;
2358 for (nIter = 0; nIter <= maxIter; ++nIter) {
2361 double x = a[0] + t * (a[1] + t * (a[2] + t * (a[3] + t * (a[4] + t * a[5]))));
2367 double xp = a[1] + t * (2 * a[2] + t * (3 * a[3] + t * (4 * a[4] + t * 5 * a[5])));
2368 double xpp = 2 * a[2] + t * (6 * a[3] + t * (12 * a[4] + t * 20 * a[5]));
2369 double den = xp * xp + x * xpp;
2376 edm = fabs(x * xp) / sqrt(den);
2377 if (edm < epsi4x)
break;
2384 dt = std::min(dt, maxDt);
2386 dt = std::max(dt, -maxDt);
2389 B2WARNING(
"CDCGeometryPar::getMinDriftTime: den = 0\n" <<
"layer(#0-55),lr,alpha(rad),theta= " <<
2392 " " << alpha <<
" " << theta);
2398 if (nIter == (maxIter + 1)) minTime = minMinTime;
2450 double CDCGeometryPar::getDriftTime(
const double dist,
const unsigned short iCLayer,
const unsigned short lr,
const double alpha,
2451 const double theta)
const
2455 const double eps = 2.5e-1;
2456 const double maxTrials = 100;
2464 double maxTime = 2000.;
2469 double minTime = getMinDriftTime(iCLayer, lr, alpha, theta);
2470 double t0 = minTime;
2472 const bool calMinTime =
false;
2477 double t1 = maxTime;
2478 double time = dist * m_nominalDriftVInv;
2479 while (((t1 - t0) > eps) && (i < maxTrials)) {
2480 time = 0.5 * (t0 + t1);
2481 double d1 = getDriftLength(time, iCLayer, lr, alpha, theta, calMinTime, minTime) - dist;
2491 if (i >= maxTrials - 1 || time > maxTime) {
2492 B2WARNING(
"CDCGeometryPar::getDriftTime " << dist <<
" " << iCLayer <<
" " << alpha <<
" " << lr <<
" " << t0 <<
" " << t1 <<
" " <<
2502 double CDCGeometryPar::getSigma(
const double DriftL0,
const unsigned short iCLayer,
const unsigned short lr,
const double alpha,
2503 const double theta)
const
2508 const double driftL = fabs(DriftL0);
2511 unsigned short lro = getOutgoingLR(lr, alpha);
2513 if (!m_linearInterpolationOfSgm) {
2514 B2FATAL(
"linearInterpolationOfSgm = false is not allowed now !");
2516 if (m_linearInterpolationOfSgm) {
2518 unsigned short ial[2] = {0};
2519 unsigned short ilr[2] = {lro, lro};
2520 getClosestAlphaPoints4Sgm(alpha, wal, ial, ilr);
2522 unsigned short ith[2] = {0};
2523 getClosestThetaPoints4Sgm(alpha, theta, wth, ith);
2526 unsigned short jal(0), jlr(0), jth(0);
2528 for (
unsigned k = 0; k < 4; ++k) {
2533 w = (1. - wal) * (1. - wth);
2534 }
else if (k == 1) {
2538 w = (1. - wal) * wth;
2539 }
else if (k == 2) {
2543 w = wal * (1. - wth);
2544 }
else if (k == 3) {
2562 const double& P0 = m_Sigma[iCLayer][jlr][jal][jth][0];
2563 const double& P1 = m_Sigma[iCLayer][jlr][jal][jth][1];
2564 const double& P2 = m_Sigma[iCLayer][jlr][jal][jth][2];
2565 const double& P3 = m_Sigma[iCLayer][jlr][jal][jth][3];
2566 const double& P4 = m_Sigma[iCLayer][jlr][jal][jth][4];
2567 const double& P5 = m_Sigma[iCLayer][jlr][jal][jth][5];
2568 const double& P6 = m_Sigma[iCLayer][jlr][jal][jth][6];
2570 #if defined(CDC_DEBUG)
2571 cout <<
"driftL= " << driftL << endl;
2572 cout <<
"iCLayer= " << iCLayer <<
" " << jlr <<
" " << jal <<
" " << jth << endl;
2573 cout <<
"P0= " << P0 << endl;
2574 cout <<
"P1= " << P1 << endl;
2575 cout <<
"P2= " << P2 << endl;
2576 cout <<
"P3= " << P3 << endl;
2577 cout <<
"P4= " << P4 << endl;
2578 cout <<
"P5= " << P5 << endl;
2579 cout <<
"P6= " << P6 << endl;
2581 const double P7 = m_sigmaParamMode == 0 ? DBL_MAX : m_Sigma[iCLayer][jlr][jal][jth][7];
2584 sigma += w * sqrt(P0 / (driftL * driftL + P1) + P2 * driftL + P3 +
2585 P4 * exp(P5 * (driftL - P6) * (driftL - P6)));
2587 double forthTermAtP7 = P4 * exp(P5 * (P7 - P6) * (P7 - P6));
2588 const double& P8 = m_Sigma[iCLayer][jlr][jal][jth][8];
2589 if (m_sigmaParamMode == 1) {
2590 double sigmaAtP7 = sqrt(P0 / (P7 * P7 + P1) + P2 * P7 + P3 + forthTermAtP7);
2591 sigma += w * (P8 * (driftL - P7) + sigmaAtP7);
2592 }
else if (m_sigmaParamMode == 2) {
2593 double onePls4AtP7 = sqrt(P0 / (P7 * P7 + P1) + forthTermAtP7);
2594 const double onePls4 = P8 * (driftL - P7) + onePls4AtP7;
2595 sigma += w * sqrt(P2 * driftL + P3 + onePls4 * onePls4);
2596 }
else if (m_sigmaParamMode == 3) {
2597 forthTermAtP7 = sqrt(forthTermAtP7);
2598 const double forthTerm = P8 * (driftL - P7) + forthTermAtP7;
2599 sigma += w * sqrt(P0 / (driftL * driftL + P1) + P2 * driftL + P3 +
2600 forthTerm * forthTerm);
2606 sigma = std::min(sigma, m_maxSpaceResol);
2610 unsigned short CDCGeometryPar::getOldLeftRight(
const TVector3& posOnWire,
const TVector3& posOnTrack,
2611 const TVector3& momentum)
const
2613 unsigned short lr = 0;
2614 double wCrossT = (posOnWire.Cross(posOnTrack)).z();
2618 }
else if (wCrossT > 0.) {
2621 if ((posOnTrack - posOnWire).Perp() != 0.) {
2622 double wCrossP = (posOnWire.Cross(momentum)).z();
2624 if (posOnTrack.Perp() > posOnWire.Perp()) {
2629 }
else if (wCrossP < 0.) {
2630 if (posOnTrack.Perp() < posOnWire.Perp()) {
2645 unsigned short CDCGeometryPar::getNewLeftRightRaw(
const TVector3& posOnWire,
const TVector3& posOnTrack,
2646 const TVector3& momentum)
const
2648 const double distanceCrossP = ((posOnWire - posOnTrack).Cross(momentum)).z();
2649 unsigned short int lr = (distanceCrossP > 0.) ? 1 : 0;
2654 double CDCGeometryPar::getAlpha(
const TVector3& posOnWire,
const TVector3& momentum)
const
2656 const double wx = posOnWire.x();
2657 const double wy = posOnWire.y();
2658 const double px = momentum.x();
2659 const double py = momentum.y();
2661 const double cross = wx * py - wy * px;
2662 const double dot = wx * px + wy * py;
2664 return atan2(cross, dot);
2667 double CDCGeometryPar::getTheta(
const TVector3& momentum)
const
2669 return atan2(momentum.Perp(), momentum.z());
2673 unsigned short CDCGeometryPar::getOutgoingLR(
const unsigned short lr,
const double alpha)
const
2675 unsigned short lro = (fabs(alpha) <= 0.5 * M_PI) ? lr : abs(lr - 1);
2680 double CDCGeometryPar::getOutgoingAlpha(
const double alpha)
const
2683 double alphao = alpha;
2684 if (alpha > 0.5 * M_PI) {
2686 }
else if (alpha < -0.5 * M_PI) {
2693 double CDCGeometryPar::getOutgoingTheta(
const double alpha,
const double theta)
const
2696 double thetao = fabs(alpha) > 0.5 * M_PI ? M_PI - theta : theta;
2701 void CDCGeometryPar::getClosestAlphaPoints(
const double alpha,
double& weight,
unsigned short points[2],
2702 unsigned short lrs[2])
const
2704 double alphao = getOutgoingAlpha(alpha);
2707 if (alphao < m_alphaPoints[0]) {
2708 points[0] = m_nAlphaPoints - 1;
2710 if (m_nAlphaPoints > 1) {
2711 lrs[0] = abs(lrs[0] - 1);
2712 weight = (alphao - (m_alphaPoints[points[0]] - M_PI)) / (m_alphaPoints[points[1]] - (m_alphaPoints[points[0]] - M_PI));
2714 }
else if (m_alphaPoints[m_nAlphaPoints - 1] <= alphao) {
2715 points[0] = m_nAlphaPoints - 1;
2717 if (m_nAlphaPoints > 1) {
2718 lrs[1] = abs(lrs[1] - 1);
2719 weight = (alphao - m_alphaPoints[points[0]]) / (m_alphaPoints[points[1]] + M_PI - m_alphaPoints[points[0]]);
2722 for (
unsigned short i = 0; i <= m_nAlphaPoints - 2; ++i) {
2723 if (m_alphaPoints[i] <= alphao && alphao < m_alphaPoints[i + 1]) {
2726 weight = (alphao - m_alphaPoints[points[0]]) / (m_alphaPoints[points[1]] - m_alphaPoints[points[0]]);
2735 void CDCGeometryPar::getClosestAlphaPoints4Sgm(
const double alpha,
double& weight,
unsigned short points[2],
2736 unsigned short lrs[2])
const
2738 double alphao = getOutgoingAlpha(alpha);
2741 if (alphao < m_alphaPoints4Sgm[0]) {
2742 points[0] = m_nAlphaPoints4Sgm - 1;
2744 if (m_nAlphaPoints4Sgm > 1) {
2745 lrs[0] = abs(lrs[0] - 1);
2746 weight = (alphao - (m_alphaPoints4Sgm[points[0]] - M_PI)) / (m_alphaPoints4Sgm[points[1]] - (m_alphaPoints4Sgm[points[0]] - M_PI));
2748 }
else if (m_alphaPoints4Sgm[m_nAlphaPoints4Sgm - 1] <= alphao) {
2749 points[0] = m_nAlphaPoints4Sgm - 1;
2751 if (m_nAlphaPoints4Sgm > 1) {
2752 lrs[1] = abs(lrs[1] - 1);
2753 weight = (alphao - m_alphaPoints4Sgm[points[0]]) / (m_alphaPoints4Sgm[points[1]] + M_PI - m_alphaPoints4Sgm[points[0]]);
2756 for (
unsigned short i = 0; i <= m_nAlphaPoints4Sgm - 2; ++i) {
2757 if (m_alphaPoints4Sgm[i] <= alphao && alphao < m_alphaPoints4Sgm[i + 1]) {
2760 weight = (alphao - m_alphaPoints4Sgm[points[0]]) / (m_alphaPoints4Sgm[points[1]] - m_alphaPoints4Sgm[points[0]]);
2768 void CDCGeometryPar::getClosestThetaPoints(
const double alpha,
const double theta,
double& weight,
unsigned short points[2])
const
2770 const double thetao = getOutgoingTheta(alpha, theta);
2772 if (thetao < m_thetaPoints[0]) {
2778 }
else if (m_thetaPoints[m_nThetaPoints - 1] <= thetao) {
2781 points[0] = m_nThetaPoints - 1;
2782 points[1] = m_nThetaPoints - 1;
2785 for (
unsigned short i = 0; i <= m_nThetaPoints - 2; ++i) {
2786 if (m_thetaPoints[i] <= thetao && thetao < m_thetaPoints[i + 1]) {
2789 weight = (thetao - m_thetaPoints[points[0]]) / (m_thetaPoints[points[1]] - m_thetaPoints[points[0]]);
2798 void CDCGeometryPar::getClosestThetaPoints4Sgm(
const double alpha,
const double theta,
double& weight,
2799 unsigned short points[2])
const
2801 const double thetao = getOutgoingTheta(alpha, theta);
2803 if (thetao < m_thetaPoints4Sgm[0]) {
2807 }
else if (m_thetaPoints4Sgm[m_nThetaPoints4Sgm - 1] <= thetao) {
2808 points[0] = m_nThetaPoints4Sgm - 1;
2809 points[1] = m_nThetaPoints4Sgm - 1;
2812 for (
unsigned short i = 0; i <= m_nThetaPoints4Sgm - 2; ++i) {
2813 if (m_thetaPoints4Sgm[i] <= thetao && thetao < m_thetaPoints4Sgm[i + 1]) {
2816 weight = (thetao - m_thetaPoints4Sgm[points[0]]) / (m_thetaPoints4Sgm[points[1]] - m_thetaPoints4Sgm[points[0]]);
2824 void CDCGeometryPar::setDisplacement()
2827 for (
const auto& disp : (*m_displacementFromDB)) {
2834 m_FWirPos[iLayer][iWire][0] += disp.getXFwd();
2835 m_FWirPos[iLayer][iWire][1] += disp.getYFwd();
2836 m_FWirPos[iLayer][iWire][2] += disp.getZFwd();
2837 m_BWirPos[iLayer][iWire][0] += disp.getXBwd();
2838 m_BWirPos[iLayer][iWire][1] += disp.getYBwd();
2839 m_BWirPos[iLayer][iWire][2] += disp.getZBwd();
2840 m_WireSagCoef[iLayer][iWire] = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.*
2841 (m_senseWireTension + disp.getTension()));
2847 void CDCGeometryPar::setShiftInSuperLayer()
2849 const unsigned short nLayers[nSuperLayers] = {8, 6, 6, 6, 6, 6, 6, 6, 6};
2851 for (
unsigned short SLayer = 0; SLayer < nSuperLayers; ++SLayer) {
2852 unsigned short firstCLayer = 0;
2853 for (
unsigned short i = 0; i < SLayer; ++i) {
2854 firstCLayer += nLayers[i];
2858 TVector3 firstBPos = wireBackwardPosition(firstCLayer, 0);
2859 for (
unsigned short Layer = 0; Layer < nLayers[SLayer]; ++Layer) {
2860 unsigned short CLayer = firstCLayer + Layer;
2862 if (CLayer == firstCLayer) {
2863 m_shiftInSuperLayer[SLayer][Layer] = 0;
2865 }
else if (CLayer == firstCLayer + 1) {
2866 TVector3 BPos = wireBackwardPosition(CLayer, 0);
2867 m_shiftInSuperLayer[SLayer][Layer] = (BPos.Cross(firstBPos)).Z() > 0. ? -1 : 1;
2871 if (Layer % 2 == 0) {
2872 m_shiftInSuperLayer[SLayer][Layer] = 0;
2874 m_shiftInSuperLayer[SLayer][Layer] = m_shiftInSuperLayer[SLayer][1];
2882 signed short CDCGeometryPar::getShiftInSuperLayer(
unsigned short iSuperLayer,
unsigned short iLayer)
const
2884 return m_shiftInSuperLayer[iSuperLayer][iLayer];
The Class for CDC geometry.
The Class for CDC Geometry Control Parameters.
bool getSigmaInputType()
Get input type for sigma.
bool getMisalignmentInputType()
Get input type for wire misalignment.
bool getDisplacementInputType()
Get input type for wire displacement.
double getAddFudgeFactorForSigmaForMC() const
Get additional fudge factor for space resol for MC.
std::string getDisplacementFile() const
Get input file name for wire displacement.
std::string getMisalignmentFile() const
Get input file name for wire misalignment.
std::string getAlignmentFile() const
Get input file name for wire alignment.
bool getAlignmentInputType()
Get input type for wire alignment.
bool getT0InputType()
Get input type for t0.
bool getEDepToADCInputType()
Get input type for edeptoadc.
bool getMisalignment() const
Get misalignment switch.
double getAddFudgeFactorForSigmaForData() const
Get additional fudge factor for space resol for data.
bool getTwInputType()
Get input type for time-walk.
bool getChMapInputType()
Get input type for channel map.
bool getFFactorInputType()
Get input type for fuge factor.
bool getXtInputType()
Get input type for xt.
bool getBwInputType()
Get input type for bad wire.
bool getPropSpeedInputType()
Get input type for prop.
The Class for CDC Geometry Parameters.
EWirePosition
Wire position set.
void addCallback(std::function< void(const std::string &)> callback, bool onDestruction=false)
Add a callback method.
Class for accessing arrays of objects in the database.
Class for accessing objects in the database.
GearDir is the basic class used for accessing the parameter store.
virtual std::string getString(const std::string &path="") const noexcept(false) override
Get the parameter path as a string.
Optional DBObjPtr: This class behaves the same as the DBObjPtr except that it will not raise errors w...
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 getEWire() const
Getter for encoded wire number.
void openFileB(boost::iostreams::filtering_istream &ifs, const std::string &fileName0)
Open a file using boost (to be able to read a gzipped file)
void openFileA(std::ifstream &ifs, const std::string &fileName0)
Open a file.
Abstract base class for different kinds of events.