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 < c_maxNSenseLayers; ++i) {
191 m_zSForwardLayer[i] = 0;
192 m_dzSForwardLayer[i] = 0;
193 m_zSBackwardLayer[i] = 0;
194 m_dzSBackwardLayer[i] = 0;
199 m_propSpeedInv[i] = 0.;
201 for (
unsigned i = 0; i < c_maxNFieldLayers; ++i) {
203 m_zFForwardLayer[i] = 0;
204 m_zFBackwardLayer[i] = 0;
207 for (
unsigned L = 0; L < c_maxNSenseLayers; ++L) {
208 for (
unsigned C = 0; C < c_maxNDriftCells; ++C) {
209 for (
unsigned i = 0; i < 3; ++i) {
210 m_FWirPos [L][C][i] = 0.;
211 m_BWirPos [L][C][i] = 0.;
212 m_FWirPosMisalign[L][C][i] = 0.;
213 m_BWirPosMisalign[L][C][i] = 0.;
214 m_FWirPosAlign [L][C][i] = 0.;
215 m_BWirPosAlign [L][C][i] = 0.;
217 for (
unsigned i = 0; i < 7; ++i) {
218 m_eDepToADCParams[L][C][i] = 0.;
220 m_WireSagCoef [L][C] = 0.;
221 m_WireSagCoefMisalign[L][C] = 0.;
222 m_WireSagCoefAlign [L][C] = 0.;
227 for (
unsigned L = 0; L < c_maxNSenseLayers; ++L) {
228 for (
unsigned i = 0; i < 2; ++i) {
229 for (
unsigned alpha = 0; alpha < c_maxNAlphaPoints; ++alpha) {
230 for (
unsigned theta = 0; theta < c_maxNThetaPoints; ++theta) {
231 for (
unsigned xtparam = 0; xtparam < c_nXTParams; ++xtparam) {
232 m_XT[L][i][alpha][theta][xtparam] = 0.;
235 for (
unsigned sigmaparam = 0; sigmaparam < c_nSigmaParams; ++sigmaparam) {
236 m_Sigma[L][i][alpha][theta][sigmaparam] = 0.;
243 for (
unsigned board = 0; board < c_nBoards; ++board) {
244 for (
unsigned i = 0; i < 2; ++i) {
245 m_timeWalkCoef[board][i] = 0.;
247 for (
unsigned channel = 0; channel < 48; ++channel) {
248 m_boardAndChannelToWire[board][channel] = 0.;
252 for (
unsigned superLayer = 0; superLayer < c_nSuperLayers; ++superLayer) {
253 for (
unsigned layer = 0; layer < 8; ++layer) {
254 m_shiftInSuperLayer[superLayer][layer] = 0;
262 m_globalPhiRotation = geom.getGlobalPhiRotation();
266 m_rWall[0] = geom.getInnerWall(2).getRmin();
267 m_zWall[0][0] = geom.getInnerWall(0).getZbwd();
268 m_zWall[0][1] = geom.getInnerWall(0).getZfwd();
270 m_rWall[1] = geom.getInnerWall(0).getRmax();
271 m_zWall[1][0] = geom.getInnerWall(0).getZbwd();
272 m_zWall[1][1] = geom.getInnerWall(0).getZbwd();
275 m_rWall[2] = geom.getOuterWall(0).getRmin();
276 m_zWall[2][0] = geom.getOuterWall(0).getZbwd();
277 m_zWall[2][1] = geom.getOuterWall(0).getZfwd();
279 m_rWall[3] = geom.getOuterWall(1).getRmax();
280 m_zWall[3][0] = geom.getOuterWall(0).getZbwd();
281 m_zWall[3][1] = geom.getOuterWall(0).getZfwd();
284 m_debug = CDCGeoControlPar::getInstance().getDebug();
285 m_nSLayer = geom.getNSenseLayers();
287 m_materialDefinitionMode = CDCGeoControlPar::getInstance().getMaterialDefinitionMode();
289 if (m_materialDefinitionMode == 0) {
290 B2DEBUG(100,
"CDCGeometryPar: Define a mixture of gases and wires in the tracking volume.");
291 }
else if (m_materialDefinitionMode == 2) {
293 B2FATAL(
"CDCGeometryPar: Materialdefinition=2 is disabled for now.");
295 B2FATAL(
"CDCGeometryPar: Materialdefinition mode you specify is invalid.");
299 m_senseWireZposMode = CDCGeoControlPar::getInstance().getSenseWireZposMode();
301 B2DEBUG(100,
"CDCGeometryPar: Sense wire z mode:" << m_senseWireZposMode);
306 GearDir content =
GearDir(
"/Detector/DetectorComponent[@name=\"CDC\"]/Content/");
314 for (
const auto& sense : geom.getSenseLayers()) {
315 uint layerId = sense.getId();
317 m_rSLayer[layerId] = sense.getR();
318 m_zSBackwardLayer[layerId] = sense.getZbwd();
319 m_zSForwardLayer[layerId] = sense.getZfwd();
320 m_nWires[layerId] = sense.getNWires();
321 m_nShifts[layerId] = sense.getNShifts();
322 m_offSet[layerId] = sense.getOffset();
323 m_cellSize[layerId] = 2 * M_PI * m_rSLayer[layerId] / (double) m_nWires[layerId];
324 m_dzSBackwardLayer[layerId] = sense.getDZbwd();
325 m_dzSForwardLayer[layerId] = sense.getDZfwd();
328 if (m_senseWireZposMode == 0) {
329 }
else if (m_senseWireZposMode == 1) {
332 m_zSBackwardLayer[layerId] += m_dzSBackwardLayer[layerId];
333 m_zSForwardLayer [layerId] -= m_dzSForwardLayer [layerId];
335 B2FATAL(
"CDCGeometryPar: invalid wire z definition mode specified");
339 const int nWires = m_nWires[layerId];
340 for (
int iCell = 0; iCell < nWires; ++iCell) {
341 setDesignWirParam(layerId, iCell);
347 for (
const auto& field : geom.getFieldLayers()) {
348 uint layerId = field.getId();
350 m_rFLayer[layerId] = field.getR();
351 m_zFBackwardLayer[layerId] = field.getZbwd();
352 m_zFForwardLayer[layerId] = field.getZfwd();
356 m_senseWireDiameter = geom.getSenseDiameter();
359 m_senseWireTension = geom.getSenseTension();
362 m_senseWireDensity = 19.3;
365 m_fieldWireDiameter = geom.getFieldDiameter();
368 m_nSenseWires = geom.getNSenseWires();
369 m_nFieldWires = geom.getNFieldWires();
370 m_maxNSenseLayers = geom.getNumberOfSenseLayers();
371 m_maxNFieldLayers = geom.getNumberOfFieldLayers();
372 m_maxNSuperLayers = geom.getMaxNumberOfSuperLayers();
373 m_firstLayerOffset = geom.getOffsetOfFirstLayer();
374 m_firstSuperLayerOffset = geom.getOffsetOfFirstSuperLayer();
375 m_maxNCellsPerLayer = geom.getMaxNumberOfCellsPerLayer();
378 m_clockFreq4TDC = geom.getClockFrequency();
379 if (not m_clockSettings.isValid())
380 B2FATAL(
"HardwareClockSettings payloads are not valid.");
381 const double officialClockFreq4TDC = 2 * m_clockSettings->getAcceleratorRF();
382 if (abs(m_clockFreq4TDC - officialClockFreq4TDC) / m_clockFreq4TDC > 1.e-4) {
383 B2WARNING(
"ClockFreq4TDC changed from cdclocal " << scientific << setprecision(6) << m_clockFreq4TDC <<
" to official " <<
384 officialClockFreq4TDC <<
" (GHz) (difference larger than 0.01%)");
385 m_clockFreq4TDC = officialClockFreq4TDC;
387 B2DEBUG(100,
"CDCGeometryPar: Clock freq. for TDC= " << m_clockFreq4TDC <<
" (GHz).");
388 m_tdcBinWidth = 1. / m_clockFreq4TDC;
389 B2DEBUG(100,
"CDCGeometryPar: TDC bin width= " << m_tdcBinWidth <<
" (ns).");
391 m_nominalDriftV = 4.e-3;
392 m_nominalDriftVInv = 1. / m_nominalDriftV;
393 m_nominalPropSpeed = 27.25;
395 m_nominalSpaceResol = geom.getNominalSpaceResolution();
399 m_displacement = CDCGeoControlPar::getInstance().getDisplacement();
400 B2DEBUG(100,
"CDCGeometryPar: Load displacement params. (=1); not load (=0):" << m_displacement);
401 if (m_displacement) {
403 B2DEBUG(100,
"CDCGeometryPar: Read displacement from DB");
406 readWirePositionParams(c_Base, &geom);
411 m_alignment = CDCGeoControlPar::getInstance().getAlignment();
412 B2DEBUG(100,
"CDCGeometryPar: Load alignment params. (=1); not load (=0):" <<
416 B2DEBUG(100,
"CDCGeometryPar: Read alignment from DB");
417 setWirPosAlignParams();
419 readWirePositionParams(c_Aligned, &geom);
424 m_misalignment = CDCGeoControlPar::getInstance().getMisalignment();
425 B2DEBUG(100,
"CDCGeometryPar: Load misalignment params. (=1); not load (=0):" <<
427 if (m_misalignment) {
429 B2DEBUG(100,
"CDCGeometryPar: Read misalignment from DB");
430 setWirPosMisalignParams();
432 readWirePositionParams(c_Misaligned, &geom);
437 m_thresholdEnergyDeposit = CDCSimControlPar::getInstance().getThresholdEnergyDeposit();
438 m_minTrackLength = CDCSimControlPar::getInstance().getMinTrackLength();
439 m_wireSag = CDCSimControlPar::getInstance().getWireSag();
440 m_modLeftRightFlag = CDCSimControlPar::getInstance().getModLeftRightFlag();
441 if (m_modLeftRightFlag) {
442 B2FATAL(
"ModifiedLeftRightFlag = true is disabled for now; need to update a G4-related code in framework...");
446 m_sigmaFileFormat = 1;
451 B2DEBUG(100,
"CDCGeometryPar: Read xt from DB");
458 B2DEBUG(100,
"CDCGeometryPar: Read sigma from DB");
461 readSigma(gbxParams);
465 B2DEBUG(100,
"CDCGeometryPar: Read fudge factors from DB");
468 readFFactor(gbxParams);
472 B2DEBUG(100,
"CDCGeometryPar: Read prop-speed from DB");
475 readPropSpeed(gbxParams);
479 B2DEBUG(100,
"CDCGeometryPar: Read t0 from DB");
486 B2DEBUG(100,
"CDCGeometryPar: Read badwire from DB");
490 B2FATAL(
"Text file input mode for bdwires is disabled now!");
494 B2DEBUG(100,
"CDCGeometryPar: Read ch-map from DB");
501 B2DEBUG(100,
"CDCGeometryPar: Read time-walk from DB");
506 B2DEBUG(100,
"CDCGeometryPar: Time-walk param. mode= " << m_twParamMode);
509 B2DEBUG(29,
"CDCGeometryPar: Read EDepToADC from DB");
510 if ((*m_eDepToADCConversionsFromDB).isValid()) {
511 setEDepToADCConversions();
514 readEDepToADC(gbxParams);
522 readXT(gbxParams, 1);
523 readSigma(gbxParams, 1);
524 readPropSpeed(gbxParams, 1);
525 readT0(gbxParams, 1);
526 readTW(gbxParams, 1);
530 setShiftInSuperLayer();
582 std::string fileName0;
587 }
else if (set == c_Misaligned) {
589 }
else if (set == c_Aligned) {
595 }
else if (set == c_Misaligned) {
597 }
else if (set == c_Aligned) {
604 boost::iostreams::filtering_istream ifs;
609 double back[np], fwrd[np], tension;
614 for (
int i = 0; i < np; ++i) {
617 for (
int i = 0; i < np; ++i) {
623 if (ifs.eof())
break;
625 if (iL < m_firstLayerOffset) {
631 for (
int i = 0; i < np; ++i) {
633 m_BWirPos[iL][iC][i] += (iL < m_firstLayerOffset) ? 0 : back[i];
634 m_FWirPos[iL][iC][i] += (iL < m_firstLayerOffset) ? 0 : fwrd[i];
635 }
else if (set == c_Misaligned) {
636 m_BWirPosMisalign[iL][iC][i] = m_BWirPos[iL][iC][i] + ((iL < m_firstLayerOffset) ? 0 : back[i]);
637 m_FWirPosMisalign[iL][iC][i] = m_FWirPos[iL][iC][i] + ((iL < m_firstLayerOffset) ? 0 : fwrd[i]);
638 }
else if (set == c_Aligned) {
639 m_BWirPosAlign[iL][iC][i] = m_BWirPos[iL][iC][i] + ((iL < m_firstLayerOffset) ? 0 : back[i]);
640 m_FWirPosAlign[iL][iC][i] = m_FWirPos[iL][iC][i] + ((iL < m_firstLayerOffset) ? 0 : fwrd[i]);
647 m_WireSagCoef[iL][iC] = (iL < m_firstLayerOffset) ? 0 : M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter /
648 (8.*(m_senseWireTension + tension));
650 }
else if (set == c_Misaligned) {
651 double baseTension = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.* m_WireSagCoef[iL][iC]);
652 m_WireSagCoefMisalign[iL][iC] = (iL < m_firstLayerOffset) ? 0 : M_PI * m_senseWireDensity * m_senseWireDiameter *
653 m_senseWireDiameter / (8.* (baseTension + tension));
655 }
else if (set == c_Aligned) {
656 double baseTension = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.* m_WireSagCoef[iL][iC]);
657 m_WireSagCoefAlign[iL][iC] = (iL < m_firstLayerOffset) ? 0 : M_PI * m_senseWireDensity * m_senseWireDiameter *
658 m_senseWireDiameter / (8.*(baseTension + tension));
674 if (nRead != m_nSenseWires) B2FATAL(
"CDCGeometryPar::readWirePositionParams: #lines read-in (=" << nRead <<
675 ") is inconsistent with total #sense wires (=" << m_nSenseWires <<
") !");
678 boost::iostreams::close(ifs);
683 void CDCGeometryPar::setWirPosAlignParams()
686 for (
unsigned iL = 0; iL < c_maxNSenseLayers; ++iL) {
688 if (iL < m_firstLayerOffset) {
693 auto layerID =
WireID(iL, 511);
696 double d_layerXbwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerX);
697 double d_layerYbwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerY);
698 double d_layerPhiBwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerPhi);
700 double d_layerXfwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerDx) + d_layerXbwd;
701 double d_layerYfwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerDy) + d_layerYbwd;
702 double d_layerPhiFwd = (*m_alignmentFromDB)->get(layerID, CDCAlignment::layerDPhi) + d_layerPhiBwd;
704 for (
unsigned iC = 0; iC < m_nWires[iL]; ++iC) {
706 double wireXbwd = m_BWirPos[iL][iC][0];
707 double wireYbwd = m_BWirPos[iL][iC][1];
708 double wireZbwd = m_BWirPos[iL][iC][2];
710 double wireXfwd = m_FWirPos[iL][iC][0];
711 double wireYfwd = m_FWirPos[iL][iC][1];
712 double wireZfwd = m_FWirPos[iL][iC][2];
716 m_BWirPosAlign[iL][iC][0] = d_layerXbwd + cos(d_layerPhiBwd) * wireXbwd + sin(d_layerPhiBwd) * wireYbwd;
717 m_BWirPosAlign[iL][iC][1] = d_layerYbwd - sin(d_layerPhiBwd) * wireXbwd + cos(d_layerPhiBwd) * wireYbwd;
718 m_BWirPosAlign[iL][iC][2] = wireZbwd;
720 m_FWirPosAlign[iL][iC][0] = d_layerXfwd + cos(d_layerPhiFwd) * wireXfwd + sin(d_layerPhiFwd) * wireYfwd;
721 m_FWirPosAlign[iL][iC][1] = d_layerYfwd - sin(d_layerPhiFwd) * wireXfwd + cos(d_layerPhiFwd) * wireYfwd;
722 m_FWirPosAlign[iL][iC][2] = wireZfwd;
727 double back[np], fwrd[np];
729 for (
unsigned iL = 0; iL < c_maxNSenseLayers; ++iL) {
731 if (iL < m_firstLayerOffset) {
735 for (
unsigned iC = 0; iC < m_nWires[iL]; ++iC) {
738 back[0] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireBwdX);
739 back[1] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireBwdY);
740 back[2] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireBwdZ);
742 fwrd[0] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireFwdX);
743 fwrd[1] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireFwdY);
744 fwrd[2] = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireFwdZ);
746 for (
int i = 0; i < np; ++i) {
749 m_BWirPosAlign[iL][iC][i] += back[i];
750 m_FWirPosAlign[iL][iC][i] += fwrd[i];
754 double baseTension = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.* m_WireSagCoef[iL][iC]);
755 double tension = (*m_alignmentFromDB)->get(wire, CDCAlignment::wireTension);
757 m_WireSagCoefAlign[iL][iC] = M_PI * m_senseWireDensity *
758 m_senseWireDiameter * m_senseWireDiameter / (8.*(baseTension + tension));
767 void CDCGeometryPar::setWirPosMisalignParams()
770 double back[np], fwrd[np];
772 for (
unsigned iL = 0; iL < c_maxNSenseLayers; ++iL) {
774 if (iL < m_firstLayerOffset) {
778 for (
unsigned iC = 0; iC < m_nWires[iL]; ++iC) {
781 back[0] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireBwdX);
782 back[1] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireBwdY);
783 back[2] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireBwdZ);
785 fwrd[0] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireFwdX);
786 fwrd[1] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireFwdY);
787 fwrd[2] = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireFwdZ);
789 for (
int i = 0; i < np; ++i) {
790 m_BWirPosMisalign[iL][iC][i] = m_BWirPos[iL][iC][i] + back[i];
791 m_FWirPosMisalign[iL][iC][i] = m_FWirPos[iL][iC][i] + fwrd[i];
795 double baseTension = M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter / (8.* m_WireSagCoef[iL][iC]);
796 double tension = (*m_misalignmentFromDB)->get(wire, CDCMisalignment::wireTension);
798 m_WireSagCoefMisalign[iL][iC] = M_PI * m_senseWireDensity *
799 m_senseWireDiameter * m_senseWireDiameter / (8.*(baseTension + tension));
807 void CDCGeometryPar::readXT(
const GearDir& gbxParams,
const int mode)
809 if (m_xtFileFormat == 0) {
812 newReadXT(gbxParams, mode);
818 void CDCGeometryPar::newReadXT(
const GearDir& gbxParams,
const int mode)
820 m_linearInterpolationOfXT =
true;
822 std::string fileName0 = CDCGeoControlPar::getInstance().getXtFile();
824 fileName0 = gbxParams.
getString(
"xt4ReconFileName");
827 boost::iostreams::filtering_istream ifs;
851 unsigned short nAlphaBins = 0;
852 if (ifs >> nAlphaBins) {
853 if (nAlphaBins == 0 || nAlphaBins > c_maxNAlphaPoints) B2FATAL(
"Fail to read alpha bins !");
855 B2FATAL(
"Fail to read alpha bins !");
857 m_nAlphaPoints = nAlphaBins;
858 double alpha0, alpha1, alpha2;
859 for (
unsigned short i = 0; i < nAlphaBins; ++i) {
860 ifs >> alpha0 >> alpha1 >> alpha2;
861 m_alphaPoints[i] = alpha2;
865 unsigned short nThetaBins = 0;
866 if (ifs >> nThetaBins) {
867 if (nThetaBins == 0 || nThetaBins > c_maxNThetaPoints) B2FATAL(
"CDCGeometryPar: fail to read theta bins !");
869 B2FATAL(
"CDCGeometryPar: fail to read theta bins !");
871 m_nThetaPoints = nThetaBins;
872 double theta0, theta1, theta2;
874 for (
unsigned short i = 0; i < nThetaBins; ++i) {
875 ifs >> theta0 >> theta1 >> theta2;
876 m_thetaPoints[i] = theta2;
880 unsigned short iCL, iLR;
881 const unsigned short npx = c_nXTParams - 1;
883 double theta, alpha, dummy1;
885 ifs >> m_xtParamMode >> np;
886 if (m_xtParamMode < 0 || m_xtParamMode > 3) B2FATAL(
"CDCGeometryPar: invalid xt-parameterization mode read !");
888 if (np <= 0 || np > npx) B2FATAL(
"CDCGeometryPar: no. of xt-params. outside limits !");
890 const double epsi = 0.1;
894 if (iCL < m_firstLayerOffset) {
898 ifs >> theta >> alpha >> dummy1 >> iLR;
899 for (
int i = 0; i < np; ++i) {
904 for (
unsigned short i = 0; i < nThetaBins; ++i) {
905 if (fabs(theta - m_thetaPoints[i]) < epsi) {
910 if (itheta < 0) B2FATAL(
"CDCGeometryPar: thetas in xt.dat are inconsistent !");
913 for (
unsigned short i = 0; i < nAlphaBins; ++i) {
914 if (fabs(alpha - m_alphaPoints[i]) < epsi) {
919 if (ialpha < 0) B2FATAL(
"CDCGeometryPar: alphas in xt.dat are inconsistent !");
921 for (
int i = 0; i < np; ++i) {
922 m_XT[iCL][iLR][ialpha][itheta][i] = xtc[i];
925 double boundT = xtc[6];
926 if (m_xtParamMode == 1) {
927 m_XT[iCL][iLR][ialpha][itheta][np] = ROOT::Math::Chebyshev5(boundT, xtc[0], xtc[1], xtc[2], xtc[3], xtc[4], xtc[5]);
929 m_XT[iCL][iLR][ialpha][itheta][np] =
940 boost::iostreams::close(ifs);
943 const double degrad = M_PI / 180.;
944 for (
unsigned i = 0; i < nAlphaBins; ++i) {
945 m_alphaPoints[i] *= degrad;
947 for (
unsigned i = 0; i < nThetaBins; ++i) {
948 m_thetaPoints[i] *= degrad;
955 void CDCGeometryPar::readSigma(
const GearDir& gbxParams,
const int mode)
957 if (m_sigmaFileFormat == 0) {
960 newReadSigma(gbxParams, mode);
964 void CDCGeometryPar::newReadSigma(
const GearDir& gbxParams,
const int mode)
966 m_linearInterpolationOfSgm =
true;
968 std::string fileName0 = CDCGeoControlPar::getInstance().getSigmaFile();
970 fileName0 = gbxParams.
getString(
"sigma4ReconFileName");
978 unsigned short nAlphaBins = 0;
979 if (ifs >> nAlphaBins) {
980 if (nAlphaBins == 0 || nAlphaBins > c_maxNAlphaPoints) B2FATAL(
"Fail to read alpha bins !");
982 B2FATAL(
"Fail to read alpha bins !");
984 m_nAlphaPoints4Sgm = nAlphaBins;
986 double alpha0, alpha1, alpha2;
987 for (
unsigned short i = 0; i < nAlphaBins; ++i) {
988 ifs >> alpha0 >> alpha1 >> alpha2;
989 m_alphaPoints4Sgm[i] = alpha2;
994 unsigned short nThetaBins = 0;
995 if (ifs >> nThetaBins) {
996 if (nThetaBins == 0 || nThetaBins > c_maxNThetaPoints) B2FATAL(
"CDCGeometryPar: fail to read theta bins !");
998 B2FATAL(
"CDCGeometryPar: fail to read theta bins !");
1000 m_nThetaPoints4Sgm = nThetaBins;
1002 double theta0, theta1, theta2;
1004 for (
unsigned short i = 0; i < nThetaBins; ++i) {
1005 ifs >> theta0 >> theta1 >> theta2;
1006 m_thetaPoints4Sgm[i] = theta2;
1010 unsigned short np = 0;
1011 unsigned short iCL, iLR;
1012 double sigma[c_nSigmaParams];
1013 double theta, alpha;
1015 ifs >> m_sigmaParamMode >> np;
1017 if (m_sigmaParamMode < 0 || m_sigmaParamMode > 4) B2FATAL(
"CDCGeometryPar: invalid sigma-parameterization mode read !");
1019 if (np > c_nSigmaParams) B2FATAL(
"CDCGeometryPar: no. of sigma-params. outside limits !");
1021 ifs >> m_maxSpaceResol;
1023 const double epsi = 0.1;
1025 while (ifs >> iCL) {
1027 if (iCL < m_firstLayerOffset) {
1031 ifs >> theta >> alpha >> iLR;
1033 for (
int i = 0; i < np; ++i) {
1038 for (
unsigned short i = 0; i < nThetaBins; ++i) {
1039 if (fabs(theta - m_thetaPoints4Sgm[i]) < epsi) {
1044 if (itheta < 0) B2FATAL(
"CDCGeometryPar: thetas in sigma.dat are inconsistent !");
1047 for (
unsigned short i = 0; i < nAlphaBins; ++i) {
1048 if (fabs(alpha - m_alphaPoints4Sgm[i]) < epsi) {
1053 if (ialpha < 0) B2FATAL(
"CDCGeometryPar: alphas in sigma.dat are inconsistent !");
1055 for (
int i = 0; i < np; ++i) {
1056 m_Sigma[iCL][iLR][ialpha][itheta][i] = sigma[i];
1063 const double degrad = M_PI / 180.;
1064 for (
unsigned i = 0; i < nAlphaBins; ++i) {
1065 m_alphaPoints4Sgm[i] *= degrad;
1067 for (
unsigned i = 0; i < nThetaBins; ++i) {
1068 m_thetaPoints4Sgm[i] *= degrad;
1076 void CDCGeometryPar::readFFactor(
const GearDir& gbxParams,
const int mode)
1078 std::string fileName0 = CDCGeoControlPar::getInstance().getFFactorFile();
1080 fileName0 = gbxParams.
getString(
"fudgeFactorFileName");
1082 B2WARNING(
"readFFactor is not ready! " << fileName0);
1088 void CDCGeometryPar::readPropSpeed(
const GearDir& gbxParams,
const int mode)
1090 std::string fileName0 = CDCGeoControlPar::getInstance().getPropSpeedFile();
1092 fileName0 = gbxParams.
getString(
"propSpeed4ReconFileName");
1105 if (ifs.eof())
break;
1109 m_propSpeedInv[iL] = (iL < m_firstLayerOffset) ? 0 : 1. / speed;
1111 if (m_debug) B2DEBUG(150, iL <<
" " << speed);
1114 if (nRead != c_maxNSenseLayers) B2FATAL(
"CDCGeometryPar::readPropSpeed: #lines read-in (=" << nRead <<
1115 ") is inconsistent with total #layers (=" << c_maxNSenseLayers <<
") !");
1156 void CDCGeometryPar::readT0(
const GearDir& gbxParams,
int mode)
1158 std::string fileName0 = CDCGeoControlPar::getInstance().getT0File();
1160 fileName0 = gbxParams.
getString(
"t04ReconFileName");
1172 ifs >> iL >> iC >> t0;
1174 if (iL < m_firstLayerOffset) {
1178 if (ifs.eof())
break;
1182 m_t0[iL][iC] = (iL < m_firstLayerOffset) ? 0. : t0;
1185 B2DEBUG(150, iL <<
" " << iC <<
" " << t0);
1189 if (nRead != m_nSenseWires) B2FATAL(
"CDCGeometryPar::readT0: #lines read-in (=" << nRead <<
1190 ") is inconsistent with total #sense wires (=" << m_nSenseWires <<
") !");
1237 void CDCGeometryPar::readTW(
const GearDir& gbxParams,
const int mode)
1239 std::string fileName0 = CDCGeoControlPar::getInstance().getTwFile();
1241 fileName0 = gbxParams.
getString(
"tw4ReconFileName");
1248 unsigned short nPars(0);
1249 ifs >> m_twParamMode >> nPars;
1250 if (m_twParamMode > 1) {
1251 B2FATAL(
"CDCGeometryPar::readTW: invalid mode specified!");
1254 B2FATAL(
"CDCGeometryPar::readTW: invalid #params specified!");
1257 unsigned iBoard = 0;
1260 while (ifs >> iBoard) {
1261 for (
unsigned short i = 0; i < nPars; ++i) {
1262 ifs >> m_timeWalkCoef[iBoard][i];
1267 if (nRead != c_nBoards) B2FATAL(
"CDCGeometryPar::readTW: #lines read-in (=" << nRead <<
") is inconsistent with #boards (=" <<
1277 void CDCGeometryPar::readChMap()
1279 std::string fileName0 = CDCGeoControlPar::getInstance().getChMapFile();
1285 unsigned short iSL, iL, iW, iB, iC;
1290 ifs >> iSL >> iL >> iW >> iB >> iC;
1291 if (ifs.eof())
break;
1292 if (iSL >= c_nSuperLayers or iSL < m_firstSuperLayerOffset)
continue;
1296 m_wireToBoard.insert(pair<WireID, unsigned short>(wID, iB));
1299 if (nRead != m_nSenseWires) B2FATAL(
"CDCGeometryPar::readChMap: #lines read-in (=" << nRead <<
1300 ") is inconsistent with #sense-wires (="
1301 << m_nSenseWires <<
") !");
1308 void CDCGeometryPar::readEDepToADC(
const GearDir& gbxParams,
const int mode)
1311 std::string fileName0 = CDCGeoControlPar::getInstance().getEDepToADCFile();
1313 fileName0 = gbxParams.
getString(
"fudgeFactorFileName");
1318 std::string fileName1 =
"/data/cdc/" + fileName0;
1319 std::string fileName = FileSystem::findFile(fileName1,
true);
1321 if (fileName ==
"") {
1322 fileName = FileSystem::findFile(fileName0,
true);
1325 if (fileName ==
"") {
1326 B2FATAL(
"CDC::openFile: " << fileName0 <<
" not exist!");
1329 B2DEBUG(29,
"CDC::openFile: open " << fileName);
1330 ifs.open(fileName.c_str());
1331 if (!ifs) B2FATAL(
"CDC::openFile: cannot open " << fileName <<
" !");
1334 unsigned short paramMode(0), nParams(0);
1335 ifs >> paramMode >> nParams;
1336 if (paramMode > 1) B2FATAL(
"Param mode > 1!");
1337 if (nParams > 7) B2FATAL(
"No. of params. > 7!");
1338 unsigned short groupId(0);
1340 B2DEBUG(29, paramMode <<
" " << nParams <<
" " << groupId);
1341 if (groupId > 0) B2FATAL(
"GgroupId > 0!");
1344 unsigned short cLMin[c_nSuperLayers], cLMax[c_nSuperLayers];
1347 for (
unsigned int sl = 1; sl < c_nSuperLayers; ++sl) {
1348 cLMin[sl] = cLMax[0] + 6 * sl - 5;
1349 cLMax[sl] = cLMax[0] + 6 * sl;
1352 unsigned short id = 0;
1354 unsigned short nRead = 0;
1356 for (
unsigned short i = 0; i < nParams; ++i) {
1358 for (
unsigned short cL = cLMin[
id]; cL <= cLMax[id]; ++cL) {
1359 for (
unsigned short cell = 0; cell < m_nWires[cL]; ++cell) {
1360 m_eDepToADCParams[cL][cell][i] = (cL < m_firstLayerOffset) ? 0 : coef;
1366 if (nRead > c_nSuperLayers) B2FATAL(
"No. of read in lines > " << c_nSuperLayers <<
" !");
1374 void CDCGeometryPar::setT0()
1376 for (
unsigned short iCL = 0; iCL < c_maxNSenseLayers; ++iCL) {
1377 for (
unsigned short iW = 0; iW < c_maxNDriftCells; ++iW) {
1382 for (
auto const& ent : (*m_t0FromDB)->getT0s()) {
1385 const unsigned short iW = wid.
getIWire();
1386 m_t0[iCL][iW] = (iCL < m_firstLayerOffset) ? 0. : ent.second;
1394 void CDCGeometryPar::calcMeanT0(
double minT0,
double maxT0,
int maxIt,
double nStdv,
double epsi)
1396 double oldMeanT0 = 0;
1397 unsigned short it1 = 0;
1398 for (
unsigned short it = 0; it < maxIt; ++it) {
1400 double effiSum = 0.;
1403 for (
unsigned short iCL = 0; iCL < c_maxNSenseLayers; ++iCL) {
1404 for (
unsigned short iW = 0; iW < m_nWires[iCL]; ++iW) {
1405 if (m_t0[iCL][iW] < minT0 || m_t0[iCL][iW] > maxT0)
continue;
1407 if (isHotWire(wid))
continue;
1408 if (isBadWire(wid))
continue;
1410 isDeadWire(wid, effi);
1412 m_meanT0 += (iCL < m_firstLayerOffset) ? 0. : effi * m_t0[iCL][iW];
1413 stdvT0 += (iCL < m_firstLayerOffset) ? 0. : effi * m_t0[iCL][iW] * m_t0[iCL][iW];
1417 m_meanT0 /= effiSum;
1419 stdvT0 =
sqrt(fabs(stdvT0 - m_meanT0 * m_meanT0));
1420 B2DEBUG(29, it <<
" " << effiSum <<
" " << m_meanT0 <<
" " << stdvT0);
1421 if (fabs(m_meanT0 - oldMeanT0) < epsi)
break;
1422 oldMeanT0 = m_meanT0;
1423 minT0 = m_meanT0 - nStdv * stdvT0;
1424 maxT0 = m_meanT0 + nStdv * stdvT0;
1426 B2FATAL(
"Wire efficiency sum <= 0!");
1429 if (it1 == maxIt - 1) B2WARNING(
"Max. iterations(=" << maxIt <<
") needed to calculte the mean t0. Strange.");
1434 void CDCGeometryPar::setBadWire()
1442 void CDCGeometryPar::setPropSpeed()
1444 for (
unsigned short iCL = 0; iCL < (*m_propSpeedFromDB)->getEntries(); ++iCL) {
1445 m_propSpeedInv[iCL] = (iCL < m_firstLayerOffset) ? 0. : 1. / (*m_propSpeedFromDB)->getSpeed(iCL);
1451 void CDCGeometryPar::setTW()
1454 m_twParamMode = (*m_timeWalkFromDB)->getTwParamMode();
1456 for (
unsigned short iBd = 0; iBd < (*m_timeWalkFromDB)->getEntries(); ++iBd) {
1457 int np = ((*m_timeWalkFromDB)->getTimeWalkParams(iBd)).size();
1458 for (
int i = 0; i < np; ++i) {
1459 m_timeWalkCoef[iBd][i] = ((*m_timeWalkFromDB)->getTimeWalkParams(iBd))[i];
1466 void CDCGeometryPar::setXtRel()
1468 m_linearInterpolationOfXT =
true;
1471 m_nAlphaPoints = (*m_xtRelFromDB)->getNoOfAlphaBins();
1472 for (
unsigned short i = 0; i < m_nAlphaPoints; ++i) {
1473 m_alphaPoints[i] = (*m_xtRelFromDB)->getAlphaPoint(i);
1477 m_nThetaPoints = (*m_xtRelFromDB)->getNoOfThetaBins();
1478 for (
unsigned short i = 0; i < m_nThetaPoints; ++i) {
1479 m_thetaPoints[i] = (*m_xtRelFromDB)->getThetaPoint(i);
1483 m_xtParamMode = (*m_xtRelFromDB)->getXtParamMode();
1485 for (
unsigned short iCL = 0; iCL < c_maxNSenseLayers; ++iCL) {
1486 if (iCL < m_firstLayerOffset) {
1492 for (
unsigned short iLR = 0; iLR < 2; ++iLR) {
1493 for (
unsigned short iA = 0; iA < m_nAlphaPoints; ++iA) {
1494 for (
unsigned short iT = 0; iT < m_nThetaPoints; ++iT) {
1495 const std::vector<float> params = (*m_xtRelFromDB)->getXtParams(iCL, iLR, iA, iT);
1496 unsigned short np = params.size();
1498 for (
unsigned short i = 0; i < np; ++i) {
1499 m_XT[iCL][iLR][iA][iT][i] = params[i];
1502 double boundT = m_XT[iCL][iLR][iA][iT][6];
1503 if (m_xtParamMode == 1) {
1504 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],
1505 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]);
1507 m_XT[iCL][iLR][iA][iT][np] =
1508 m_XT[iCL][iLR][iA][iT][0] + boundT
1509 * (m_XT[iCL][iLR][iA][iT][1] + boundT
1510 * (m_XT[iCL][iLR][iA][iT][2] + boundT
1511 * (m_XT[iCL][iLR][iA][iT][3] + boundT
1512 * (m_XT[iCL][iLR][iA][iT][4] + boundT
1513 * (m_XT[iCL][iLR][iA][iT][5])))));
1524 void CDCGeometryPar::setSResol()
1526 m_linearInterpolationOfSgm =
true;
1529 m_nAlphaPoints4Sgm = (*m_sResolFromDB)->getNoOfAlphaBins();
1530 for (
unsigned short i = 0; i < m_nAlphaPoints4Sgm; ++i) {
1531 m_alphaPoints4Sgm[i] = (*m_sResolFromDB)->getAlphaPoint(i);
1535 m_nThetaPoints4Sgm = (*m_sResolFromDB)->getNoOfThetaBins();
1536 for (
unsigned short i = 0; i < m_nThetaPoints4Sgm; ++i) {
1537 m_thetaPoints4Sgm[i] = (*m_sResolFromDB)->getThetaPoint(i);
1544 m_sigmaParamMode = (*m_sResolFromDB)->getSigmaParamMode();
1546 m_maxSpaceResol = (*m_sResolFromDB)->getMaxSpaceResol();
1548 for (
unsigned short iCL = 0; iCL < c_maxNSenseLayers; ++iCL) {
1549 for (
unsigned short iLR = 0; iLR < 2; ++iLR) {
1550 for (
unsigned short iA = 0; iA < m_nAlphaPoints4Sgm; ++iA) {
1551 for (
unsigned short iT = 0; iT < m_nThetaPoints4Sgm; ++iT) {
1552 const std::vector<float> params = (*m_sResolFromDB)->getSigmaParams(iCL, iLR, iA, iT);
1553 unsigned short np = params.size();
1555 for (
unsigned short i = 0; i < np; ++i) {
1556 m_Sigma[iCL][iLR][iA][iT][i] = (iCL < m_firstLayerOffset) ? 0. : params[i];
1567 void CDCGeometryPar::setFFactor()
1569 unsigned short groupId = (*m_fFactorFromDB)->getGroupID();
1570 unsigned short nEnt = (*m_fFactorFromDB)->getEntries();
1571 B2DEBUG(29,
"setFFactor called: groupId,nEnt= " << groupId <<
" " << nEnt);
1575 B2FATAL(
"CDCGeometryPar:: Invalid group-id " << groupId <<
" specified!");
1578 for (
unsigned short id = 0;
id < nEnt; ++id) {
1579 unsigned short np = ((*m_fFactorFromDB)->getFactors(
id)).size();
1580 if (np != 3) B2FATAL(
"CDCGeometryPar:: No. of fudge factors != 3!");
1581 for (
unsigned short i = 0; i < np; ++i) {
1582 m_fudgeFactorForSigma[i] = ((*m_fFactorFromDB)->getFactors(
id))[i];
1583 B2DEBUG(29, i <<
" " << m_fudgeFactorForSigma[i]);
1590 B2DEBUG(29,
"fudge factors= " << m_fudgeFactorForSigma[0] <<
" " << m_fudgeFactorForSigma[1] <<
" " << m_fudgeFactorForSigma[2]);
1595 void CDCGeometryPar::setChMap()
1597 for (
const auto& cm : (*m_chMapFromDB)) {
1598 const unsigned short isl = cm.getISuperLayer();
1599 if (isl >= c_nSuperLayers or isl < m_firstSuperLayerOffset)
continue;
1600 const uint il = cm.getILayer();
1601 const int iw = cm.getIWire();
1602 const int iBd = cm.getBoardID();
1603 const WireID wID(isl, il, iw);
1604 m_wireToBoard.insert(pair<WireID, unsigned short>(wID, iBd));
1605 const int iCh = cm.getBoardChannel();
1606 m_wireToChannel.insert(pair<WireID, unsigned short>(wID, iCh));
1607 m_boardAndChannelToWire[iBd][iCh] = wID.
getEWire();
1612 void CDCGeometryPar::setEDepToADCConversions()
1614 unsigned short groupId = (*m_eDepToADCConversionsFromDB)->getGroupID();
1615 unsigned short nEnt = (*m_eDepToADCConversionsFromDB)->getEntries();
1617 if (nEnt > c_nSuperLayers) B2FATAL(
"CDCGeometryPar:: group-id " << groupId <<
" and #entries " << nEnt <<
" are inconsistent!");
1618 }
else if (groupId == 1) {
1619 if (nEnt > c_maxNSenseLayers) B2FATAL(
"CDCGeometryPar:: group-id " << groupId <<
" and #entries " << nEnt <<
" are inconsistent!");
1621 B2FATAL(
"CDCGeometryPar:: Invalid group-id " << groupId <<
" specified !");
1624 unsigned short cLMin[c_nSuperLayers], cLMax[c_nSuperLayers];
1627 for (
unsigned int sl = 1; sl < c_nSuperLayers; ++sl) {
1628 cLMin[sl] = cLMax[0] + 6 * sl - 5;
1629 cLMax[sl] = cLMax[0] + 6 * sl;
1632 for (
unsigned short id = 0;
id < nEnt; ++id) {
1633 unsigned short np = ((*m_eDepToADCConversionsFromDB)->getParams(
id)).size();
1634 if (np > 7) B2FATAL(
"CDCGeometryPar:: No. of edep-to-ADC conversion params. > 7");
1636 for (
unsigned short cL = cLMin[
id]; cL <= cLMax[id]; ++cL) {
1637 for (
unsigned short cell = 0; cell < m_nWires[cL]; ++cell) {
1638 for (
unsigned short i = 0; i < np; ++i) {
1639 m_eDepToADCParams[cL][cell][i] = (cL < m_firstLayerOffset) ? 0. : ((*m_eDepToADCConversionsFromDB)->getParams(
id))[i];
1643 }
else if (groupId == 1) {
1644 for (
unsigned short cell = 0; cell < m_nWires[id]; ++cell) {
1645 for (
unsigned short i = 0; i < np; ++i) {
1646 m_eDepToADCParams[id][cell][i] = (
id < m_firstLayerOffset) ? 0. : ((*m_eDepToADCConversionsFromDB)->getParams(
id))[i];
1649 }
else if (groupId == 2) {
1651 B2FATAL(
"CDCGeometryPar::setEDepToADCConversions(): groupId=2 not ready!");
1657 double CDCGeometryPar::getEDepToADCConvFactor(
unsigned short iCL,
unsigned short iW,
double edep,
double dx,
double costh)
1664 const double mainF = (iCL < m_firstLayerOffset) ? 0. : m_eDepToADCParams[iCL][iW][0];
1665 const double& alf = (iCL < m_firstLayerOffset) ? 0. : m_eDepToADCParams[iCL][iW][1];
1666 const double& gam = (iCL < m_firstLayerOffset) ? 0. : m_eDepToADCParams[iCL][iW][2];
1667 const double& dlt = (iCL < m_firstLayerOffset) ? 0. : m_eDepToADCParams[iCL][iW][3];
1668 const double& a = (iCL < m_firstLayerOffset) ? 0. : m_eDepToADCParams[iCL][iW][4];
1669 const double& b = (iCL < m_firstLayerOffset) ? 0. : m_eDepToADCParams[iCL][iW][5];
1670 const double cth = fabs(costh) + dlt;
1671 const double iGen = edep / dx;
1672 const double tmp = cth - gam * iGen;
1673 const double disc = tmp * tmp + 4.*alf * cth * iGen;
1677 iMea = cth * iGen / tmp;
1678 }
else if (disc >= 0.) {
1679 iMea = (-tmp +
sqrt(disc)) / (2.*alf);
1687 double convF = mainF;
1689 convF = mainF * std::min(iMea / iGen, 1.);
1698 convF *= 1. + a * (costh - b);
1703 void CDCGeometryPar::Print()
const
1709 if (layerID < m_firstLayerOffset) {
1714 B2Vector3D wPos(m_FWirPosAlign[layerID][cellID][0],
1715 m_FWirPosAlign[layerID][cellID][1],
1716 m_FWirPosAlign[layerID][cellID][2]);
1718 if (set == c_Misaligned) {
1719 wPos.
SetX(m_FWirPosMisalign[layerID][cellID][0]);
1720 wPos.
SetY(m_FWirPosMisalign[layerID][cellID][1]);
1721 wPos.
SetZ(m_FWirPosMisalign[layerID][cellID][2]);
1722 }
else if (set == c_Base) {
1723 wPos.
SetX(m_FWirPos [layerID][cellID][0]);
1724 wPos.
SetY(m_FWirPos [layerID][cellID][1]);
1725 wPos.
SetZ(m_FWirPos [layerID][cellID][2]);
1734 if (layerID < m_firstLayerOffset) {
1740 getWireSagEffect(set, layerID, cellID, z, yb_sag, yf_sag);
1742 B2Vector3D wPos(m_FWirPosAlign[layerID][cellID][0], yf_sag,
1743 m_FWirPosAlign[layerID][cellID][2]);
1744 if (set == c_Misaligned) {
1745 wPos.
SetX(m_FWirPosMisalign[layerID][cellID][0]);
1746 wPos.
SetZ(m_FWirPosMisalign[layerID][cellID][2]);
1747 }
else if (set == c_Base) {
1748 wPos.
SetX(m_FWirPos [layerID][cellID][0]);
1749 wPos.
SetZ(m_FWirPos [layerID][cellID][2]);
1758 if (layerID < m_firstLayerOffset) {
1762 B2Vector3D wPos(m_BWirPosAlign[layerID][cellID][0],
1763 m_BWirPosAlign[layerID][cellID][1],
1764 m_BWirPosAlign[layerID][cellID][2]);
1766 if (set == c_Misaligned) {
1767 wPos.
SetX(m_BWirPosMisalign[layerID][cellID][0]);
1768 wPos.
SetY(m_BWirPosMisalign[layerID][cellID][1]);
1769 wPos.
SetZ(m_BWirPosMisalign[layerID][cellID][2]);
1770 }
else if (set == c_Base) {
1771 wPos.
SetX(m_BWirPos [layerID][cellID][0]);
1772 wPos.
SetY(m_BWirPos [layerID][cellID][1]);
1773 wPos.
SetZ(m_BWirPos [layerID][cellID][2]);
1782 if (layerID < m_firstLayerOffset) {
1788 getWireSagEffect(set, layerID, cellID, z, yb_sag, yf_sag);
1790 B2Vector3D wPos(m_BWirPosAlign[layerID][cellID][0], yb_sag,
1791 m_BWirPosAlign[layerID][cellID][2]);
1792 if (set == c_Misaligned) {
1793 wPos.
SetX(m_BWirPosMisalign[layerID][cellID][0]);
1794 wPos.
SetZ(m_BWirPosMisalign[layerID][cellID][2]);
1795 }
else if (set == c_Base) {
1796 wPos.
SetX(m_BWirPos [layerID][cellID][0]);
1797 wPos.
SetZ(m_BWirPos [layerID][cellID][2]);
1803 double CDCGeometryPar::getWireSagCoef(
EWirePosition set, uint layerID,
int cellID)
const
1805 double coef = m_WireSagCoef[layerID][cellID];
1806 if (set == c_Misaligned) {
1807 coef = m_WireSagCoefMisalign[layerID][cellID];
1808 }
else if (set == c_Aligned) {
1809 coef = m_WireSagCoefAlign [layerID][cellID];
1814 const double* CDCGeometryPar::innerRadiusWireLayer()
const
1816 static double IRWL[c_maxNSenseLayers] = {0};
1818 IRWL[0] = outerRadiusInnerWall();
1819 for (
unsigned i = 1; i < nWireLayers(); i++)
1821 IRWL[i] = (i == m_firstLayerOffset) ? outerRadiusInnerWall() : m_rFLayer[i - 1];
1826 const double* CDCGeometryPar::outerRadiusWireLayer()
const
1828 static double ORWL[c_maxNSenseLayers] = {0};
1830 ORWL[nWireLayers() - 1] = innerRadiusOuterWall();
1831 for (
unsigned i = 0; i < nWireLayers() - 1; i++)
1833 ORWL[i] = m_rFLayer[i];
1838 unsigned CDCGeometryPar::cellId(
unsigned layerId,
const B2Vector3D& position)
const
1840 if (layerId < m_firstLayerOffset) {
1844 const unsigned nWires = m_nWires[layerId];
1846 double offset = m_offSet[layerId];
1848 const double phiSize = 2 * M_PI / double(nWires);
1865 for (
unsigned i = 0; i < 1; ++i) {
1866 const double phiF = phiSize * (double(i) + offset)
1867 + phiSize * 0.5 *
double(m_nShifts[layerId]) + m_globalPhiRotation;
1868 const double phiB = phiSize * (double(i) + offset) + m_globalPhiRotation;
1869 const B2Vector3D f(m_rSLayer[layerId] * cos(phiF), m_rSLayer[layerId] * sin(phiF), m_zSForwardLayer[layerId]);
1870 const B2Vector3D b(m_rSLayer[layerId] * cos(phiB), m_rSLayer[layerId] * sin(phiB), m_zSBackwardLayer[layerId]);
1873 const double beta = (position.
Z() - b.Z()) / u.Z();
1875 double dPhi = std::atan2(position.
Y(), position.
X())
1876 - std::atan2(p.Y(), p.X())
1878 while (dPhi < 0) dPhi += (2. * M_PI);
1879 j = int(dPhi / phiSize);
1880 while (j >= nWires) j -= nWires;
1886 void CDCGeometryPar::generateXML(
const string& of)
1889 std::ofstream ofs(of.c_str(), std::ios::out);
1891 B2ERROR(
"CDCGeometryPar::read !!! can not open file : "
1894 ofs <<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1896 <<
"<Subdetector type=\"CDC\">"
1898 <<
" <Name>CDC BelleII </Name>"
1900 <<
" <Description>CDC geometry parameters</Description>"
1902 <<
" <Version>0</Version>"
1904 <<
" <GeoCreator>CDCBelleII</GeoCreator>"
1908 <<
" <Rotation desc=\"Rotation of the whole cdc detector (should be the same as beampipe)\" unit=\"mrad\">0.0</Rotation>"
1910 <<
" <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>"
1912 <<
" <Material>CDCGas</Material>"
1916 ofs <<
" <SLayers>" << endl;
1918 for (
int i = 0; i < m_nSLayer; i++) {
1919 ofs <<
" <SLayer id=\"" << i <<
"\">" << endl;
1920 ofs <<
" <Radius desc=\"Radius of wires in this layer\" unit=\"mm\">" << senseWireR(i) <<
"</Radius>" << endl;
1921 ofs <<
" <BackwardZ desc=\"z position of this wire layer at backward endplate\" unit=\"mm\">" << senseWireBZ(
1922 i) <<
"</BackwardZ>" << endl;
1923 ofs <<
" <ForwardZ desc=\"z position of this wire layer at forward endplate\" unit=\"mm\">" << senseWireFZ(
1924 i) <<
"</ForwardZ>" << endl;
1927 ofs <<
" <NHoles desc=\"the number of holes in this layer, 2*(cell number)\">" << nWiresInLayer(
1928 i) * 2 <<
"</NHoles>" << endl;
1929 ofs <<
" <NShift desc=\"the shifted hole number of each wire in this layer\">" << nShifts(i) <<
"</NShift>" << endl;
1930 ofs <<
" <Offset desc=\"wire offset in phi direction at endplate\">" << m_offSet[i] <<
"</Offset>" << endl;
1931 ofs <<
" </SLayer>" << endl;
1934 ofs <<
" </SLayers>" << endl;
1935 ofs <<
" <FLayers>" << endl;
1937 for (
int i = 0; i < m_nFLayer; i++) {
1938 ofs <<
" <FLayer id=\"" << i <<
"\">" << endl;
1939 ofs <<
" <Radius desc=\"Radius of field wires in this layer\" unit=\"mm\">" << fieldWireR(i) <<
"</Radius>" << endl;
1940 ofs <<
" <BackwardZ desc=\"z position of this field wire layer at backward endplate\" unit=\"mm\">" << fieldWireBZ(
1941 i) <<
"</BackwardZ>" << endl;
1942 ofs <<
" <ForwardZ desc=\"z position of this field wire layer at forward endplate\" unit=\"mm\">" << fieldWireFZ(
1943 i) <<
"</ForwardZ>" << endl;
1944 ofs <<
" </FLayer>" << endl;
1947 ofs <<
" </FLayers>" << endl;
1949 ofs <<
" <InnerWall name=\"InnerWall\">" << endl;
1950 ofs <<
" <InnerR desc=\"Inner radius\" unit=\"mm\">" << innerRadiusInnerWall() <<
"</InnerR>" << endl;
1951 ofs <<
" <OuterR desc=\"Outer radius\" unit=\"mm\">" << outerRadiusInnerWall() <<
"</OuterR>" << endl;
1952 ofs <<
" <BackwardZ desc=\"z position at backward endplate\" unit=\"mm\">" << m_zWall[0][0] <<
"</BackwardZ>" << endl;
1953 ofs <<
" <ForwardZ desc=\"z position at forward endplate\" unit=\"mm\">" << m_zWall[0][1] <<
"</ForwardZ>" << endl;
1954 ofs <<
" </InnerWall>" << endl;
1956 ofs <<
" <OuterWall name=\"OuterWall\">" << endl;
1957 ofs <<
" <InnerR desc=\"Inner radius\" unit=\"mm\">" << innerRadiusOuterWall() <<
"</InnerR>" << endl;
1958 ofs <<
" <OuterR desc=\"Outer radius\" unit=\"mm\">" << outerRadiusOuterWall() <<
"</OuterR>" << endl;
1959 ofs <<
" <BackwardZ desc=\"z position at backward endplate\" unit=\"mm\">" << m_zWall[2][0] <<
"</BackwardZ>" << endl;
1960 ofs <<
" <ForwardZ desc=\"z position at forward endplate\" unit=\"mm\">" << m_zWall[2][1] <<
"</ForwardZ>" << endl;
1961 ofs <<
" </OuterWall>" << endl;
1963 ofs <<
" </Content>" << endl
1964 <<
"</Subdetector>" << endl;
1967 void CDCGeometryPar::getWireSagEffect(
const EWirePosition set,
const unsigned layerID,
const unsigned cellID,
const double Z,
1968 double& Yb_sag,
double& Yf_sag)
const
1985 if (layerID < m_firstLayerOffset) {
1999 if (set == c_Aligned) {
2000 Coef = m_WireSagCoefAlign[layerID][cellID];
2001 Yb = m_BWirPosAlign[layerID][cellID][1];
2002 Yf = m_FWirPosAlign[layerID][cellID][1];
2008 Xb = m_BWirPosAlign[layerID][cellID][0];
2009 Xf = m_FWirPosAlign[layerID][cellID][0];
2010 Zb = m_BWirPosAlign[layerID][cellID][2];
2011 Zf = m_FWirPosAlign[layerID][cellID][2];
2013 }
else if (set == c_Misaligned) {
2014 Coef = m_WireSagCoefMisalign[layerID][cellID];
2015 Yb = m_BWirPosMisalign[layerID][cellID][1];
2016 Yf = m_FWirPosMisalign[layerID][cellID][1];
2022 Xb = m_BWirPosMisalign[layerID][cellID][0];
2023 Xf = m_FWirPosMisalign[layerID][cellID][0];
2024 Zb = m_BWirPosMisalign[layerID][cellID][2];
2025 Zf = m_FWirPosMisalign[layerID][cellID][2];
2027 }
else if (set == c_Base) {
2028 Coef = m_WireSagCoef[layerID][cellID];
2029 Yb = m_BWirPos[layerID][cellID][1];
2030 Yf = m_FWirPos[layerID][cellID][1];
2036 Xb = m_BWirPos[layerID][cellID][0];
2037 Xf = m_FWirPos[layerID][cellID][0];
2038 Zb = m_BWirPos[layerID][cellID][2];
2039 Zf = m_FWirPos[layerID][cellID][2];
2042 B2FATAL(
"CDCGeometryPar::getWireSagEffect: called with an invalid set: " <<
" " << set);
2045 const double dx = Xf - Xb;
2046 const double dy = Yf - Yb;
2047 const double dz = Zf - Zb;
2049 const double Zfp =
sqrt(dz * dz + dx * dx);
2050 const double Zp = (Z - Zb) * Zfp / dz;
2052 const double Y_sag = (Coef * (Zp - Zfp) + dy / Zfp) * Zp + Yb;
2053 const double dydz = (Coef * (2.*Zp - Zfp) * Zfp + dy) / dz;
2055 Yb_sag = Y_sag + dydz * (Zb - Z);
2056 Yf_sag = Y_sag + dydz * (Zf - Z);
2060 void CDCGeometryPar::setDesignWirParam(
const unsigned layerID,
const unsigned cellID)
2062 const unsigned L = layerID;
2063 const unsigned C = cellID;
2065 const double offset = m_offSet[L];
2067 const double phiSize = 2 * M_PI / double(m_nWires[L]);
2069 const double phiF = phiSize * (double(C) + offset)
2070 + phiSize * 0.5 *
double(m_nShifts[L]) + m_globalPhiRotation;
2072 m_FWirPos[L][C][0] = (L < m_firstLayerOffset) ? 0. : m_rSLayer[L] * cos(phiF);
2073 m_FWirPos[L][C][1] = (L < m_firstLayerOffset) ? 0. : m_rSLayer[L] * sin(phiF);
2074 m_FWirPos[L][C][2] = (L < m_firstLayerOffset) ? 0. : m_zSForwardLayer[L];
2076 const double phiB = phiSize * (double(C) + offset) + m_globalPhiRotation;
2078 m_BWirPos[L][C][0] = (L < m_firstLayerOffset) ? 0. : m_rSLayer[L] * cos(phiB);
2079 m_BWirPos[L][C][1] = (L < m_firstLayerOffset) ? 0. : m_rSLayer[L] * sin(phiB);
2080 m_BWirPos[L][C][2] = (L < m_firstLayerOffset) ? 0. : m_zSBackwardLayer[L];
2082 for (
int i = 0; i < 3; ++i) {
2083 m_FWirPosMisalign[L][C][i] = (L < m_firstLayerOffset) ? 0. : m_FWirPos[L][C][i];
2084 m_BWirPosMisalign[L][C][i] = (L < m_firstLayerOffset) ? 0. : m_BWirPos[L][C][i];
2085 m_FWirPosAlign [L][C][i] = (L < m_firstLayerOffset) ? 0. : m_FWirPos[L][C][i];
2086 m_BWirPosAlign [L][C][i] = (L < m_firstLayerOffset) ? 0. : m_BWirPos[L][C][i];
2089 m_WireSagCoef[L][C] = (L < m_firstLayerOffset) ? 0. : M_PI * m_senseWireDensity * m_senseWireDiameter * m_senseWireDiameter /
2090 (8. * m_senseWireTension);
2092 m_WireSagCoefMisalign[L][C] = (L < m_firstLayerOffset) ? 0. : m_WireSagCoef[L][C];
2093 m_WireSagCoefAlign [L][C] = (L < m_firstLayerOffset) ? 0. : m_WireSagCoef[L][C];
2097 void CDCGeometryPar::outputDesignWirParam(
const unsigned layerID,
const unsigned cellID)
const
2100 const unsigned L = layerID;
2101 const unsigned C = cellID;
2103 static bool first =
true;
2104 static ofstream ofs;
2107 ofs.open(
"alignment.dat");
2110 ofs << L <<
" " << C;
2112 ofs << setiosflags(ios::showpoint | ios::uppercase);
2114 for (
int i = 0; i < 3; ++i) ofs <<
" " << setw(15) << setprecision(8) << m_BWirPos[L][C][i];
2116 for (
int i = 0; i < 3; ++i) ofs <<
" " << setw(15) << setprecision(8) << m_FWirPos[L][C][i];
2117 ofs << setiosflags(ios::fixed);
2118 ofs <<
" " << setw(4) << setprecision(1) << m_senseWireTension;
2123 double CDCGeometryPar::getDriftV(
const double time,
const unsigned short iCLayer,
const unsigned short lr,
const double alpha,
2124 const double theta)
const
2126 if (iCLayer < m_firstLayerOffset) {
2133 double minTime = getMinDriftTime(iCLayer, lr, alpha, theta);
2134 double delta = time - minTime;
2137 unsigned short lro = getOutgoingLR(lr, alpha);
2139 if (!m_linearInterpolationOfXT) {
2140 B2FATAL(
"linearInterpolationOfXT = false is not allowed now !");
2143 unsigned short ial[2] = {0};
2144 unsigned short ilr[2] = {lro, lro};
2145 getClosestAlphaPoints(alpha, wal, ial, ilr);
2147 unsigned short ith[2] = {0};
2148 getClosestThetaPoints(alpha, theta, wth, ith);
2150 unsigned short jal(0), jlr(0), jth(0);
2154 double timep = delta < 0. ? minTime - delta : time;
2157 for (
unsigned k = 0; k < 4; ++k) {
2162 w = (1. - wal) * (1. - wth);
2163 }
else if (k == 1) {
2167 w = (1. - wal) * wth;
2168 }
else if (k == 2) {
2172 w = wal * (1. - wth);
2173 }
else if (k == 3) {
2180 double boundary = m_XT[iCLayer][jlr][jal][jth][6];
2182 if (timep < boundary) {
2183 if (m_xtParamMode == 1) {
2184 const double& c1 = m_XT[iCLayer][jlr][jal][jth][1];
2185 const double& c2 = m_XT[iCLayer][jlr][jal][jth][2];
2186 const double& c3 = m_XT[iCLayer][jlr][jal][jth][3];
2187 const double& c4 = m_XT[iCLayer][jlr][jal][jth][4];
2188 const double& c5 = m_XT[iCLayer][jlr][jal][jth][5];
2189 dDdt += w * ROOT::Math::Chebyshev4(timep, c1 + 3.*c3 + 5.*c5, 4.*c2 + 8.*c4, 6.*c3 + 10.*c5, 8.*c4, 10.*c5);
2191 dDdt += w * (m_XT[iCLayer][jlr][jal][jth][1] + timep
2192 * (2.*m_XT[iCLayer][jlr][jal][jth][2] + timep
2193 * (3.*m_XT[iCLayer][jlr][jal][jth][3] + timep
2194 * (4.*m_XT[iCLayer][jlr][jal][jth][4] + timep
2195 * (5.*m_XT[iCLayer][jlr][jal][jth][5])))));
2198 dDdt += w * m_XT[iCLayer][jlr][jal][jth][7];
2211 double CDCGeometryPar::getDriftLength0(
const double time,
const unsigned short iCLayer,
const unsigned short lr,
const double alpha,
2212 const double theta)
const
2214 if (iCLayer < m_firstLayerOffset) {
2221 unsigned short lro = getOutgoingLR(lr, alpha);
2225 if (!m_linearInterpolationOfXT) {
2226 B2FATAL(
"linearInterpolationOfXT = false is not allowed now !");
2229 unsigned short ial[2] = {0};
2230 unsigned short ilr[2] = {lro, lro};
2231 getClosestAlphaPoints(alpha, wal, ial, ilr);
2233 unsigned short ith[2] = {0};
2234 getClosestThetaPoints(alpha, theta, wth, ith);
2236 unsigned short jal(0), jlr(0), jth(0);
2240 double timep = time;
2244 for (
unsigned k = 0; k < 4; ++k) {
2249 w = (1. - wal) * (1. - wth);
2250 }
else if (k == 1) {
2254 w = (1. - wal) * wth;
2255 }
else if (k == 2) {
2259 w = wal * (1. - wth);
2260 }
else if (k == 3) {
2267 double boundary = m_XT[iCLayer][jlr][jal][jth][6];
2269 if (timep < boundary) {
2270 if (m_xtParamMode == 1) {
2271 dist += w * ROOT::Math::Chebyshev5(timep, m_XT[iCLayer][jlr][jal][jth][0], m_XT[iCLayer][jlr][jal][jth][1],
2272 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]);
2274 dist += w * (m_XT[iCLayer][jlr][jal][jth][0] + timep
2275 * (m_XT[iCLayer][jlr][jal][jth][1] + timep
2276 * (m_XT[iCLayer][jlr][jal][jth][2] + timep
2277 * (m_XT[iCLayer][jlr][jal][jth][3] + timep
2278 * (m_XT[iCLayer][jlr][jal][jth][4] + timep
2279 * (m_XT[iCLayer][jlr][jal][jth][5]))))));
2282 dist += w * (m_XT[iCLayer][jlr][jal][jth][7] * (timep - boundary) + m_XT[iCLayer][jlr][jal][jth][8]);
2293 double CDCGeometryPar::getDriftLength(
const double time,
const unsigned short iCLayer,
const unsigned short lr,
const double alpha,
2295 const bool calculateMinTime,
2296 const double inputMinTime)
const
2298 if (iCLayer < m_firstLayerOffset) {
2305 double minTime = calculateMinTime ? getMinDriftTime(iCLayer, lr, alpha, theta) : inputMinTime;
2306 double delta = time - minTime;
2309 unsigned short lro = getOutgoingLR(lr, alpha);
2313 if (!m_linearInterpolationOfXT) {
2314 B2FATAL(
"linearInterpolationOfXT = false is not allowed now !");
2317 unsigned short ial[2] = {0};
2318 unsigned short ilr[2] = {lro, lro};
2319 getClosestAlphaPoints(alpha, wal, ial, ilr);
2321 unsigned short ith[2] = {0};
2322 getClosestThetaPoints(alpha, theta, wth, ith);
2324 unsigned short jal(0), jlr(0), jth(0);
2328 double timep = delta < 0. ? minTime - delta : time;
2333 for (
unsigned k = 0; k < 4; ++k) {
2338 w = (1. - wal) * (1. - wth);
2339 }
else if (k == 1) {
2343 w = (1. - wal) * wth;
2344 }
else if (k == 2) {
2348 w = wal * (1. - wth);
2349 }
else if (k == 3) {
2369 double boundary = m_XT[iCLayer][jlr][jal][jth][6];
2371 if (timep < boundary) {
2372 if (m_xtParamMode == 1) {
2373 dist += w * ROOT::Math::Chebyshev5(timep, m_XT[iCLayer][jlr][jal][jth][0], m_XT[iCLayer][jlr][jal][jth][1],
2374 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]);
2376 dist += w * (m_XT[iCLayer][jlr][jal][jth][0] + timep
2377 * (m_XT[iCLayer][jlr][jal][jth][1] + timep
2378 * (m_XT[iCLayer][jlr][jal][jth][2] + timep
2379 * (m_XT[iCLayer][jlr][jal][jth][3] + timep
2380 * (m_XT[iCLayer][jlr][jal][jth][4] + timep
2381 * (m_XT[iCLayer][jlr][jal][jth][5]))))));
2384 dist += w * (m_XT[iCLayer][jlr][jal][jth][7] * (timep - boundary) + m_XT[iCLayer][jlr][jal][jth][8]);
2391 if (delta < 0.) dist *= -1.;
2396 double CDCGeometryPar::getMinDriftTime(
const unsigned short iCLayer,
const unsigned short lr,
const double alpha,
2397 const double theta)
const
2399 if (iCLayer < m_firstLayerOffset) {
2403 double minTime = 0.;
2406 unsigned short lro = getOutgoingLR(lr, alpha);
2408 if (!m_linearInterpolationOfXT) {
2409 B2FATAL(
"linearInterpolationOfXT = false is not allowed now !");
2412 unsigned short ial[2] = {0};
2413 unsigned short ilr[2] = {lro, lro};
2414 getClosestAlphaPoints(alpha, wal, ial, ilr);
2416 unsigned short ith[2] = {0};
2417 getClosestThetaPoints(alpha, theta, wth, ith);
2419 unsigned short jal(0), jlr(0), jth(0);
2422 double c[6] = {0.}, a[6] = {0.};
2423 for (
unsigned k = 0; k < 4; ++k) {
2428 w = (1. - wal) * (1. - wth);
2429 }
else if (k == 1) {
2433 w = (1. - wal) * wth;
2434 }
else if (k == 2) {
2438 w = wal * (1. - wth);
2439 }
else if (k == 3) {
2446 for (
int i = 0; i < 5; ++i) {
2447 c[i] += w * m_XT[iCLayer][jlr][jal][jth][i];
2451 if (m_xtParamMode == 1) {
2452 a[0] = c[0] - c[2] + c[4];
2453 a[1] = c[1] - 3.*c[3] + 5.*c[5];
2454 a[2] = 2.*c[2] - 8.*c[4];
2455 a[3] = 4.*c[3] - 20.*c[5];
2459 for (
int i = 0; i < 5; ++i) a[i] = c[i];
2466 const double det = a[1] * a[1] - 4.*a[2] * a[0];
2469 minTime = (-a[1] +
sqrt(det)) / (2.*a[2]);
2473 minTime = -a[1] / (2.*a[2]);
2476 }
else if (a[1] != 0.) {
2477 minTime = -a[0] / a[1];
2479 B2WARNING(
"CDCGeometryPar::getMinDriftTime: minDriftTime not determined; assume zero.\n" <<
"layer(#0-55),lr,alpha(rad),theta= " <<
2480 iCLayer <<
" " << lr <<
" " << alpha <<
" " << theta);
2489 const double epsi4x = 5.e-6;
2491 const unsigned short maxIter = 8;
2492 const double maxDt = 20.;
2493 unsigned short nIter = 0;
2494 double minXsq = 1.e10;
2495 double minMinTime = minTime;
2498 for (nIter = 0; nIter <= maxIter; ++nIter) {
2501 double x = a[0] + t * (a[1] + t * (a[2] + t * (a[3] + t * (a[4] + t * a[5]))));
2507 double xp = a[1] + t * (2 * a[2] + t * (3 * a[3] + t * (4 * a[4] + t * 5 * a[5])));
2508 double xpp = 2 * a[2] + t * (6 * a[3] + t * (12 * a[4] + t * 20 * a[5]));
2509 double den = xp * xp + x * xpp;
2516 edm = fabs(x * xp) /
sqrt(den);
2517 if (edm < epsi4x)
break;
2524 dt = std::min(dt, maxDt);
2526 dt = std::max(dt, -maxDt);
2529 B2WARNING(
"CDCGeometryPar::getMinDriftTime: den = 0\n" <<
"layer(#0-55),lr,alpha(rad),theta= " <<
2532 " " << alpha <<
" " << theta);
2538 if (nIter == (maxIter + 1)) minTime = minMinTime;
2590 double CDCGeometryPar::getDriftTime(
const double dist,
const unsigned short iCLayer,
const unsigned short lr,
const double alpha,
2591 const double theta)
const
2593 if (iCLayer < m_firstLayerOffset) {
2599 const double eps = 2.5e-1;
2600 const double maxTrials = 100;
2608 double maxTime = 2000.;
2613 double minTime = getMinDriftTime(iCLayer, lr, alpha, theta);
2614 double t0 = minTime;
2616 const bool calMinTime =
false;
2621 double t1 = maxTime;
2622 double time = dist * m_nominalDriftVInv;
2623 while (((t1 - t0) > eps) && (i < maxTrials)) {
2624 time = 0.5 * (t0 + t1);
2625 double d1 = getDriftLength(time, iCLayer, lr, alpha, theta, calMinTime, minTime) - dist;
2635 if (i >= maxTrials - 1 || time > maxTime) {
2636 B2WARNING(
"CDCGeometryPar::getDriftTime " << dist <<
" " << iCLayer <<
" " << alpha <<
" " << lr <<
" " << t0 <<
" " << t1 <<
" " <<
2646 double CDCGeometryPar::getSigma(
const double DriftL0,
const unsigned short iCLayer,
const unsigned short lr,
const double alpha,
2647 const double theta)
const
2649 if (iCLayer < m_firstLayerOffset) {
2656 const double driftL = fabs(DriftL0);
2659 unsigned short lro = getOutgoingLR(lr, alpha);
2661 if (!m_linearInterpolationOfSgm) {
2662 B2FATAL(
"linearInterpolationOfSgm = false is not allowed now !");
2664 if (m_linearInterpolationOfSgm) {
2666 unsigned short ial[2] = {0};
2667 unsigned short ilr[2] = {lro, lro};
2668 getClosestAlphaPoints4Sgm(alpha, wal, ial, ilr);
2670 unsigned short ith[2] = {0};
2671 getClosestThetaPoints4Sgm(alpha, theta, wth, ith);
2674 unsigned short jal(0), jlr(0), jth(0);
2676 for (
unsigned k = 0; k < 4; ++k) {
2681 w = (1. - wal) * (1. - wth);
2682 }
else if (k == 1) {
2686 w = (1. - wal) * wth;
2687 }
else if (k == 2) {
2691 w = wal * (1. - wth);
2692 }
else if (k == 3) {
2710 const double& P0 = m_Sigma[iCLayer][jlr][jal][jth][0];
2711 const double& P1 = m_Sigma[iCLayer][jlr][jal][jth][1];
2712 const double& P2 = m_Sigma[iCLayer][jlr][jal][jth][2];
2713 const double& P3 = m_Sigma[iCLayer][jlr][jal][jth][3];
2714 const double& P4 = m_Sigma[iCLayer][jlr][jal][jth][4];
2715 const double& P5 = m_Sigma[iCLayer][jlr][jal][jth][5];
2716 const double& P6 = m_Sigma[iCLayer][jlr][jal][jth][6];
2718 #if defined(CDC_DEBUG)
2719 cout <<
"driftL= " << driftL << endl;
2720 cout <<
"iCLayer= " << iCLayer <<
" " << jlr <<
" " << jal <<
" " << jth << endl;
2721 cout <<
"P0= " << P0 << endl;
2722 cout <<
"P1= " << P1 << endl;
2723 cout <<
"P2= " << P2 << endl;
2724 cout <<
"P3= " << P3 << endl;
2725 cout <<
"P4= " << P4 << endl;
2726 cout <<
"P5= " << P5 << endl;
2727 cout <<
"P6= " << P6 << endl;
2729 const double P7 = m_sigmaParamMode == 0 ? DBL_MAX : m_Sigma[iCLayer][jlr][jal][jth][7];
2732 sigma += w *
sqrt(P0 / (driftL * driftL + P1) + P2 * driftL + P3 +
2733 P4 * exp(P5 * (driftL - P6) * (driftL - P6)));
2735 double forthTermAtP7 = P4 * exp(P5 * (P7 - P6) * (P7 - P6));
2736 const double& P8 = m_Sigma[iCLayer][jlr][jal][jth][8];
2737 if (m_sigmaParamMode == 1) {
2738 double sigmaAtP7 =
sqrt(P0 / (P7 * P7 + P1) + P2 * P7 + P3 + forthTermAtP7);
2739 sigma += w * (P8 * (driftL - P7) + sigmaAtP7);
2740 }
else if (m_sigmaParamMode == 2) {
2741 double onePls4AtP7 =
sqrt(P0 / (P7 * P7 + P1) + forthTermAtP7);
2742 const double onePls4 = P8 * (driftL - P7) + onePls4AtP7;
2743 sigma += w *
sqrt(P2 * driftL + P3 + onePls4 * onePls4);
2744 }
else if (m_sigmaParamMode == 3) {
2745 forthTermAtP7 =
sqrt(forthTermAtP7);
2746 const double forthTerm = P8 * (driftL - P7) + forthTermAtP7;
2747 sigma += w *
sqrt(P0 / (driftL * driftL + P1) + P2 * driftL + P3 +
2748 forthTerm * forthTerm);
2754 sigma = std::min(sigma, m_maxSpaceResol);
2761 unsigned short lr = 0;
2762 double wCrossT = (posOnWire.
Cross(posOnTrack)).Z();
2766 }
else if (wCrossT > 0.) {
2769 if ((posOnTrack - posOnWire).Perp() != 0.) {
2770 double wCrossP = (posOnWire.
Cross(momentum)).Z();
2772 if (posOnTrack.
Perp() > posOnWire.
Perp()) {
2777 }
else if (wCrossP < 0.) {
2778 if (posOnTrack.
Perp() < posOnWire.
Perp()) {
2796 const double distanceCrossP = ((posOnWire - posOnTrack).Cross(momentum)).Z();
2797 unsigned short int lr = (distanceCrossP > 0.) ? 1 : 0;
2804 const double wx = posOnWire.
X();
2805 const double wy = posOnWire.
Y();
2806 const double px = momentum.X();
2807 const double py = momentum.Y();
2809 const double cross = wx * py - wy * px;
2810 const double dot = wx * px + wy * py;
2812 return atan2(cross,
dot);
2815 double CDCGeometryPar::getTheta(
const B2Vector3D& momentum)
const
2817 return atan2(momentum.Perp(), momentum.Z());
2821 unsigned short CDCGeometryPar::getOutgoingLR(
const unsigned short lr,
const double alpha)
const
2823 unsigned short lro = (fabs(alpha) <= 0.5 * M_PI) ? lr : abs(lr - 1);
2828 double CDCGeometryPar::getOutgoingAlpha(
const double alpha)
const
2831 double alphao = alpha;
2832 if (alpha > 0.5 * M_PI) {
2834 }
else if (alpha < -0.5 * M_PI) {
2841 double CDCGeometryPar::getOutgoingTheta(
const double alpha,
const double theta)
const
2844 double thetao = fabs(alpha) > 0.5 * M_PI ? M_PI - theta : theta;
2849 void CDCGeometryPar::getClosestAlphaPoints(
const double alpha,
double& weight,
unsigned short points[2],
2850 unsigned short lrs[2])
const
2852 double alphao = getOutgoingAlpha(alpha);
2855 if (alphao < m_alphaPoints[0]) {
2856 points[0] = m_nAlphaPoints - 1;
2858 if (m_nAlphaPoints > 1) {
2859 lrs[0] = abs(lrs[0] - 1);
2860 weight = (alphao - (m_alphaPoints[points[0]] - M_PI)) / (m_alphaPoints[points[1]] - (m_alphaPoints[points[0]] - M_PI));
2862 }
else if (m_alphaPoints[m_nAlphaPoints - 1] <= alphao) {
2863 points[0] = m_nAlphaPoints - 1;
2865 if (m_nAlphaPoints > 1) {
2866 lrs[1] = abs(lrs[1] - 1);
2867 weight = (alphao - m_alphaPoints[points[0]]) / (m_alphaPoints[points[1]] + M_PI - m_alphaPoints[points[0]]);
2870 for (
unsigned short i = 0; i <= m_nAlphaPoints - 2; ++i) {
2871 if (m_alphaPoints[i] <= alphao && alphao < m_alphaPoints[i + 1]) {
2874 weight = (alphao - m_alphaPoints[points[0]]) / (m_alphaPoints[points[1]] - m_alphaPoints[points[0]]);
2883 void CDCGeometryPar::getClosestAlphaPoints4Sgm(
const double alpha,
double& weight,
unsigned short points[2],
2884 unsigned short lrs[2])
const
2886 double alphao = getOutgoingAlpha(alpha);
2889 if (alphao < m_alphaPoints4Sgm[0]) {
2890 points[0] = m_nAlphaPoints4Sgm - 1;
2892 if (m_nAlphaPoints4Sgm > 1) {
2893 lrs[0] = abs(lrs[0] - 1);
2894 weight = (alphao - (m_alphaPoints4Sgm[points[0]] - M_PI)) / (m_alphaPoints4Sgm[points[1]] - (m_alphaPoints4Sgm[points[0]] - M_PI));
2896 }
else if (m_alphaPoints4Sgm[m_nAlphaPoints4Sgm - 1] <= alphao) {
2897 points[0] = m_nAlphaPoints4Sgm - 1;
2899 if (m_nAlphaPoints4Sgm > 1) {
2900 lrs[1] = abs(lrs[1] - 1);
2901 weight = (alphao - m_alphaPoints4Sgm[points[0]]) / (m_alphaPoints4Sgm[points[1]] + M_PI - m_alphaPoints4Sgm[points[0]]);
2904 for (
unsigned short i = 0; i <= m_nAlphaPoints4Sgm - 2; ++i) {
2905 if (m_alphaPoints4Sgm[i] <= alphao && alphao < m_alphaPoints4Sgm[i + 1]) {
2908 weight = (alphao - m_alphaPoints4Sgm[points[0]]) / (m_alphaPoints4Sgm[points[1]] - m_alphaPoints4Sgm[points[0]]);
2916 void CDCGeometryPar::getClosestThetaPoints(
const double alpha,
const double theta,
double& weight,
unsigned short points[2])
const
2918 const double thetao = getOutgoingTheta(alpha, theta);
2920 if (thetao < m_thetaPoints[0]) {
2926 }
else if (m_thetaPoints[m_nThetaPoints - 1] <= thetao) {
2929 points[0] = m_nThetaPoints - 1;
2930 points[1] = m_nThetaPoints - 1;
2933 for (
unsigned short i = 0; i <= m_nThetaPoints - 2; ++i) {
2934 if (m_thetaPoints[i] <= thetao && thetao < m_thetaPoints[i + 1]) {
2937 weight = (thetao - m_thetaPoints[points[0]]) / (m_thetaPoints[points[1]] - m_thetaPoints[points[0]]);
2946 void CDCGeometryPar::getClosestThetaPoints4Sgm(
const double alpha,
const double theta,
double& weight,
2947 unsigned short points[2])
const
2949 const double thetao = getOutgoingTheta(alpha, theta);
2951 if (thetao < m_thetaPoints4Sgm[0]) {
2955 }
else if (m_thetaPoints4Sgm[m_nThetaPoints4Sgm - 1] <= thetao) {
2956 points[0] = m_nThetaPoints4Sgm - 1;
2957 points[1] = m_nThetaPoints4Sgm - 1;
2960 for (
unsigned short i = 0; i <= m_nThetaPoints4Sgm - 2; ++i) {
2961 if (m_thetaPoints4Sgm[i] <= thetao && thetao < m_thetaPoints4Sgm[i + 1]) {
2964 weight = (thetao - m_thetaPoints4Sgm[points[0]]) / (m_thetaPoints4Sgm[points[1]] - m_thetaPoints4Sgm[points[0]]);
2972 void CDCGeometryPar::setDisplacement()
2975 for (
const auto& disp : (*m_displacementFromDB)) {
2982 m_FWirPos[iLayer][iWire][0] += (iLayer < m_firstLayerOffset) ? 0. : disp.getXFwd();
2983 m_FWirPos[iLayer][iWire][1] += (iLayer < m_firstLayerOffset) ? 0. : disp.getYFwd();
2984 m_FWirPos[iLayer][iWire][2] += (iLayer < m_firstLayerOffset) ? 0. : disp.getZFwd();
2985 m_BWirPos[iLayer][iWire][0] += (iLayer < m_firstLayerOffset) ? 0. : disp.getXBwd();
2986 m_BWirPos[iLayer][iWire][1] += (iLayer < m_firstLayerOffset) ? 0. : disp.getYBwd();
2987 m_BWirPos[iLayer][iWire][2] += (iLayer < m_firstLayerOffset) ? 0. : disp.getZBwd();
2988 m_WireSagCoef[iLayer][iWire] = (iLayer < m_firstLayerOffset) ? 0. : M_PI * m_senseWireDensity * m_senseWireDiameter *
2989 m_senseWireDiameter / (8.*
2990 (m_senseWireTension + disp.getTension()));
2996 void CDCGeometryPar::setShiftInSuperLayer()
2998 const unsigned short nLayers[c_nSuperLayers] = {8, 6, 6, 6, 6, 6, 6, 6, 6};
3000 for (
unsigned short SLayer = 0; SLayer < c_nSuperLayers; ++SLayer) {
3001 unsigned short firstCLayer = 0;
3002 for (
unsigned short i = 0; i < SLayer; ++i) {
3003 firstCLayer += nLayers[i];
3007 B2Vector3D firstBPos = wireBackwardPosition(firstCLayer, 0);
3008 for (
unsigned short Layer = 0; Layer < nLayers[SLayer]; ++Layer) {
3009 unsigned short CLayer = firstCLayer + Layer;
3011 if (CLayer == firstCLayer) {
3012 m_shiftInSuperLayer[SLayer][Layer] = 0;
3014 }
else if (CLayer == firstCLayer + 1) {
3015 B2Vector3D BPos = wireBackwardPosition(CLayer, 0);
3016 m_shiftInSuperLayer[SLayer][Layer] = (BPos.
Cross(firstBPos)).Z() > 0. ? -1 : 1;
3020 if (Layer % 2 == 0) {
3021 m_shiftInSuperLayer[SLayer][Layer] = 0;
3023 m_shiftInSuperLayer[SLayer][Layer] = m_shiftInSuperLayer[SLayer][1];
3031 signed short CDCGeometryPar::getShiftInSuperLayer(
unsigned short iSuperLayer,
unsigned short iLayer)
const
3033 return m_shiftInSuperLayer[iSuperLayer][iLayer];
B2Vector3< DataType > Cross(const B2Vector3< DataType > &p) const
Cross product.
DataType Z() const
access variable Z (= .at(2) without boundary check)
void SetX(DataType x)
set X/1st-coordinate
DataType X() const
access variable X (= .at(0) without boundary check)
DataType Y() const
access variable Y (= .at(1) without boundary check)
B2Vector3< DataType > Unit() const
Unit vector parallel to this.
void SetZ(DataType z)
set Z/3rd-coordinate
void SetY(DataType y)
set Y/2nd-coordinate
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
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.
B2Vector3< double > B2Vector3D
typedef for common usage with double
double sqrt(double a)
sqrt for double
T dot(GeneralVector< T > a, GeneralVector< T > b)
dot product of two general vectors
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.