ATLAS Offline Software
MmReadoutGeomTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "MmReadoutGeomTool.h"
6 
8 #include <GaudiKernel/SystemOfUnits.h>
11 
14 #include <GeoModelKernel/GeoFullPhysVol.h>
15 #include <GeoModelKernel/GeoPhysVol.h>
16 #include <GeoModelKernel/GeoTrd.h>
17 
18 #include <GeoModelRead/ReadGeoModel.h>
21 
22 #ifndef SIMULATIONBASE
23 # include "Acts/Surfaces/TrapezoidBounds.hpp"
24 #endif
25 
26 using namespace ActsTrk;
27 using namespace CxxUtils;
28 
29 
30 
31 namespace MuonGMR4 {
32 
33 
35 
36 MmReadoutGeomTool::MmReadoutGeomTool(const std::string& type,
37  const std::string& name,
38  const IInterface* parent)
39  : base_class{type, name, parent} {}
41  FactoryCache& factoryCache) {
42 
43  ATH_MSG_VERBOSE("Load dimensions of "<<m_idHelperSvc->toString(define.detElId)
44  <<std::endl<<std::endl<<m_geoUtilTool->dumpVolume(define.physVol->getParent()));
45  const GeoShape* shape = m_geoUtilTool->extractShape(define.physVol);
46  if (!shape) {
47  ATH_MSG_FATAL("Failed to deduce a valid shape for "<<m_idHelperSvc->toString(define.detElId));
48  return StatusCode::FAILURE;
49  }
50  ATH_MSG_DEBUG("Extracted shape "<<m_geoUtilTool->dumpShape(shape));
52  if (shape->typeID() != GeoTrd::getClassTypeID()) {
53  ATH_MSG_FATAL(__FILE__<<":"<<__LINE__<<" expect shape to be a trapezoid but it's "<<m_geoUtilTool->dumpShape(shape));
54  return StatusCode::FAILURE;
55  }
56 
57  const GeoTrd* trapezoid = static_cast<const GeoTrd*>(shape);
58  define.halfThickness = trapezoid->getXHalfLength1() * Gaudi::Units::mm;
59  define.halfShortWidth = trapezoid->getYHalfLength1() * Gaudi::Units::mm;
60  define.halfLongWidth = trapezoid->getYHalfLength2() * Gaudi::Units::mm;
61  define.halfHeight = trapezoid->getZHalfLength() * Gaudi::Units::mm;
62 
63  ATH_MSG_DEBUG("Extracted parameters "
64  <<", halfThickness: "<<define.halfThickness<<"/"
65  <<", halfShortWidth : "<<define.halfShortWidth<<"/"
66  <<", halfLongWidth : "<<define.halfLongWidth<<"/"
67  <<", halfHeight : "<<define.halfHeight);
68 
69 
70  std::vector<physVolWithTrans> allGasGaps = m_geoUtilTool->findAllLeafNodesByName(define.physVol, "actMicroMegaGas");
71  if (allGasGaps.empty()) {
72  ATH_MSG_FATAL("The volume "<<m_idHelperSvc->toStringDetEl(define.detElId)<<" does not have any children actMicroMegaGas");
73  return StatusCode::FAILURE;
74  }
75 
77  define.nGasGaps = allGasGaps.size();
78  ATH_MSG_VERBOSE("The number of gasGaps are: " << define.nGasGaps);
79 
80  FactoryCache::ParamBookTable::const_iterator parBookItr = factoryCache.parameterBook.find(define.chambDesign);
81  if (parBookItr == factoryCache.parameterBook.end()) {
82  ATH_MSG_FATAL("The chamber "<<define.chambDesign<<" is not part of the WMM table");
83  return StatusCode::FAILURE;
84  }
85 
86  const wMMTable& paramBook{parBookItr->second};
87 
88  define.readoutSide = paramBook.readoutSide;
89 
90  /*Sort Gas Gaps in a module quadruplet based on their Z position
91  On side A the gas gap have local x axis translations : -24.975 , -8.175 , 8.175, 24.975
92  This order refers to the gap closest to the origin to the outermost gap of the experiement.
93  On side C the order is reversed : 24.975 , 8.175 , -8.175, -24.975.
94  I'm sorting the gas gap with the first one being closest to the experiment's origin.
95  I doing this in case the gaps aren't sorted in that way within the Full Phys Vol Quadruplet.
96  Also, now the stereoAngles and totalActiveStrips vectors will match the sequence of the allGasGaps vector.*/
97 
98  std::sort(allGasGaps.begin(), allGasGaps.end(),
99  [](const physVolWithTrans&gapI, const physVolWithTrans & gapJ) {
100  const Amg::Vector3D posGapI = gapI.transform.translation();
101  const Amg::Vector3D posGapJ = gapJ.transform.translation();
102  return posGapI.x() < posGapJ.x();
103  });
104  ATH_MSG_DEBUG("**************************************");
105  for (std::size_t gap = 0; gap < allGasGaps.size(); ++gap) {
106 
107  auto& gapVol = allGasGaps[gap];
108  const Amg::Vector3D posGapI = gapVol.transform.translation();
109 
110  //Check sorting of gasGaps. For Q1 --> Eta layers should be first. For Q2--> Stereo Layers should be first.
111  //Add ATH_MSG_INFO("**************************************"); before the gasGap loop.
112  ATH_MSG_DEBUG("quadruplet " << define.chambDesign.substr(6,7) << " stereoAngle : " << paramBook.stereoAngle.at(gap) << " totalStrips " << paramBook.totalActiveStrips.at(gap) << " GasGAP POS X : " << posGapI.x() );
113 
114  const GeoShape* gapShape = m_geoUtilTool->extractShape(gapVol.volume);
115  if (gapShape->typeID() != GeoTrd::getClassTypeID()) {
116  ATH_MSG_FATAL("Failed to extract a geo shape");
117  return StatusCode::FAILURE;
118  }
119 
120  bool isStereo = static_cast<bool>(paramBook.stereoAngle.at(gap));
121 
122  const GeoTrd* gapTrd = static_cast<const GeoTrd*>(gapShape);
123  ATH_MSG_DEBUG("MicroMegas Gas gap dimensions "<<m_geoUtilTool->dumpShape(gapTrd));
124  double gapHalfHeight = gapTrd->getZHalfLength();
125  double gapHalfShortY = std::min(gapTrd->getYHalfLength1(), gapTrd->getYHalfLength2());
126  double gapHalfLongY = std::max(gapTrd->getYHalfLength1(), gapTrd->getYHalfLength2());
127 
128  double firstStripPos{0.};
129  int firstActiveStrip{0};
130  if (isStereo) {
131  firstActiveStrip = paramBook.nMissedBottomStereo + 1;
132  firstStripPos = -gapHalfHeight + (1.*(firstActiveStrip - paramBook.nMissedTopEta) + 2.5)* paramBook.stripPitch;
133  } else {
134  firstActiveStrip = paramBook.nMissedBottomEta + 1;
135  firstStripPos = -gapHalfHeight + 1.5 *paramBook.stripPitch;
136  }
137 
138 
139 
140  /*The origin of the chamber/gasGap axes system is located at the center of the chamber.
141  We subtract the HalfLength across the Z axis to transform from the center to the origin of the trapezoid
142  The we add the strip pitch to reach the position of the first strip.*/
143  StripDesignPtr stripDesign = std::make_unique<StripDesign>();
144 
145  stripDesign->defineStripLayout(firstStripPos * Amg::Vector2D::UnitX(),
146  paramBook.stripPitch,
147  paramBook.stripWidth,
148  paramBook.totalActiveStrips.at(gap),
149  firstActiveStrip);
150 
152  stripDesign->defineTrapezoid(gapHalfShortY, gapHalfLongY, gapHalfHeight, paramBook.stereoAngle.at(gap));
153 
154  //Necessary strip layer rotation to match the alignment coordinate system
155  Amg::Transform3D stripLayerRotation{gapVol.transform
158  * Amg::getRotateZ3D(-stripDesign->stereoAngle())};
159 
160 
161  stripDesign = (*factoryCache.stripDesigns.emplace(stripDesign).first);
162  auto stripLayer = std::make_unique<StripLayer>(stripLayerRotation, stripDesign,
163  IdentifierHash{static_cast<unsigned int>(gap)});
164  define.layers.push_back(*factoryCache.stripLayers.emplace(std::move(stripLayer)).first);
165  } //end of gas gap loop
166  return StatusCode::SUCCESS;
167 }
168 
170  ATH_CHECK(m_geoDbTagSvc.retrieve());
171  ATH_CHECK(m_idHelperSvc.retrieve());
172  ATH_CHECK(m_geoUtilTool.retrieve());
173  GeoModelIO::ReadGeoModel* sqliteReader = m_geoDbTagSvc->getSqliteReader();
174  if (!sqliteReader) {
175  ATH_MSG_FATAL("Error, the tool works exclusively from sqlite geometry inputs");
176  return StatusCode::FAILURE;
177  }
178 
179  FactoryCache facCache{};
180  ATH_CHECK(readParameterBook(facCache));
181 
182 
183  const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
184  // Get the list of full phys volumes from SQLite, and create detector elements
186  physNodeMap mapFPV = sqliteReader->getPublishedNodes<std::string, GeoFullPhysVol*>("Muon");
187 #ifndef SIMULATIONBASE
188  SurfaceBoundSetPtr<Acts::TrapezoidBounds> layerBounds= std::make_shared<SurfaceBoundSet<Acts::TrapezoidBounds>>();
189 #endif
190 
191  for (auto& [key, pv] : mapFPV) {
194  // e.g. MM_SM1Q2_1_6_1 . It's the "type" Attribute in the new GeoModel XML files.
195  std::vector<std::string> key_tokens = tokenize(key, "_");
196 
197  if (key_tokens[0].find("MM") == std::string::npos){
198  continue;
199  }
200  ATH_MSG_DEBUG("Retrieving MicroMegas Quadruplet : " << key );
201 
203  bool isValid{false};
204  define.detElId = idHelper.channelID(key_tokens[1][0] == 'S' ? "MMS" : "MML", // Replace <MM> string part with <MMS> or <MML> to match the Identifier.
205  atoi(key_tokens[2].c_str()), // Eta index
206  atoi(key_tokens[3].c_str()), // Phi index (from 0 to 7 in GeoModel). needs a +1
207  atoi(key_tokens[4].c_str()), 1, 1, isValid); //Copy Number which reflects the number of the multilayer.
208  // THen the two 1s are reflecting gasGap and channel Number. They can be set to 1s as this is all we need
209  // to get the Identifier for the multilayer.
210 
211 
212  if (!isValid) {
213  ATH_MSG_FATAL("Failed to build a good identifier out of " << key);
214  return StatusCode::FAILURE;
215  }
216 
217  ATH_MSG_DEBUG("Key "<<key<<" brought us "<<m_idHelperSvc->toStringDetEl(define.detElId));
218  define.physVol = pv;
219  define.chambDesign = key_tokens[0]+"_"+key_tokens[1]; // Recover the string denoted in WMM tables. e.g. chambDesign = "MM_SM1Q2"
220  define.alignTransform = m_geoUtilTool->findAlignableTransform(define.physVol);
221  ATH_CHECK(loadDimensions(define, facCache));
222 #ifndef SIMULATIONBASE
223  define.layerBounds = layerBounds;
224 #endif
225  std::unique_ptr<MmReadoutElement> readoutEle = std::make_unique<MmReadoutElement>(std::move(define));
226  ATH_CHECK(mgr.addMmReadoutElement(std::move(readoutEle)));
227  }
228  return StatusCode::SUCCESS;
229 }
230 
231 
232 
234 
235  ServiceHandle<IRDBAccessSvc> accessSvc(m_geoDbTagSvc->getParamSvcName(), name());
236  ATH_CHECK(accessSvc.retrieve());
237  IRDBRecordset_ptr paramTable = accessSvc->getRecordsetPtr("WMM", "");
238  if (paramTable->size() == 0) {
239  ATH_MSG_FATAL("Empty parameter book table found");
240  return StatusCode::FAILURE;
241  }
242  ATH_MSG_VERBOSE("Found the " << paramTable->nodeName() << " ["
243  << paramTable->tagName() << "] table with "
244  << paramTable->size() << " records");
245 
246 
247 
248  for (const IRDBRecord_ptr& record : *paramTable) {
249  const std::string chambType = record->getString("WMM_TYPE");
250  wMMTable& parBook = cache.parameterBook[chambType];
251  parBook.stripPitch = record->getDouble("stripPitch") ;
252  parBook.stripWidth = record->getDouble("stripWidth") ;
253  parBook.stereoAngle = tokenizeDouble(record->getString("stereoAngle"), ";");
254  parBook.totalActiveStrips = tokenizeInt(record->getString("totalActiveStrips"), ";");
255  parBook.readoutSide = tokenizeInt(record->getString("readoutSide"),";");
256  parBook.nMissedBottomEta = record->getInt("nMissedBottomEta");
257  parBook.nMissedBottomStereo = record->getInt("nMissedBottomStereo");
258  parBook.nMissedTopEta = record->getInt("nMissedTopEta");
259  parBook.distBotFrameStrip = record->getDouble("dR_botFrame1stStrip");
260 
261  ATH_MSG_VERBOSE("Extracted parameters for chamber "<<chambType
262  <<", stripPitch: "<<parBook.stripPitch
263  <<", stripWidth: "<<parBook.stripWidth
264  <<", steroAngle: "<<parBook.stereoAngle
265  <<", totalActiveStrips: "<<parBook.totalActiveStrips
266  <<", readoutSites: "<<parBook.readoutSide);
267  }
268 
269  return StatusCode::SUCCESS;
270 }
271 
272 
273 
274 
275 
276 } // namespace MuonGMR4
GeoModel::TransientConstSharedPtr< StripDesign >
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
CxxUtils::tokenizeDouble
std::vector< double > tokenizeDouble(const std::string &the_str, std::string_view delimiter)
Definition: Control/CxxUtils/Root/StringUtils.cxx:34
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
MuonGMR4::MuonDetectorManager
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonDetectorManager.h:62
MuonGMR4::MmReadoutGeomTool::wMMTable::readoutSide
std::vector< int > readoutSide
Definition: MmReadoutGeomTool.h:43
CxxUtils::tokenizeInt
std::vector< int > tokenizeInt(const std::string &the_str, std::string_view delimiter)
Definition: Control/CxxUtils/Root/StringUtils.cxx:55
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
CxxUtils::tokenize
std::vector< std::string > tokenize(const std::string &the_str, std::string_view delimiters)
Splits the string into smaller substrings.
Definition: Control/CxxUtils/Root/StringUtils.cxx:15
MuonGMR4::MmReadoutGeomTool::wMMTable::stripWidth
double stripWidth
Definition: MmReadoutGeomTool.h:39
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
MuonGMR4::MmReadoutGeomTool::wMMTable::stereoAngle
std::vector< double > stereoAngle
Definition: MmReadoutGeomTool.h:41
MuonGMR4::MmReadoutGeomTool::FactoryCache::parameterBook
ParamBookTable parameterBook
Definition: MmReadoutGeomTool.h:57
deg
#define deg
Definition: SbPolyhedron.cxx:17
SurfaceBoundSet.h
MuonGMR4::MmReadoutElement::parameterBook::halfThickness
double halfThickness
Trapezoid dimensions of MicroMegas envelope half-thickness along z-axis.
Definition: MmReadoutElement.h:27
MuonGMR4::MmReadoutGeomTool::FactoryCache
Definition: MmReadoutGeomTool.h:51
MuonGMR4::MmReadoutElement::parameterBook::readoutSide
std::vector< int > readoutSide
Readout sides.
Definition: MmReadoutElement.h:37
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
isValid
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition: AtlasPID.h:620
MuonGMR4::MmReadoutElement::parameterBook::halfShortWidth
double halfShortWidth
width of the lower edge
Definition: MmReadoutElement.h:29
CaloSwCorrections.gap
def gap(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:212
Amg::getRotateZ3D
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Definition: GeoPrimitivesHelpers.h:270
BchCleanup.mgr
mgr
Definition: BchCleanup.py:294
Amg::getRotateX3D
Amg::Transform3D getRotateX3D(double angle)
get a rotation transformation around X-axis
Definition: GeoPrimitivesHelpers.h:252
MuonGMR4::MmReadoutElement::parameterBook::nGasGaps
unsigned int nGasGaps
number of gasGaps
Definition: MmReadoutElement.h:35
MuonGMR4::MmReadoutGeomTool::wMMTable::totalActiveStrips
std::vector< int > totalActiveStrips
Definition: MmReadoutGeomTool.h:42
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
MuonGMR4
The ReadoutGeomCnvAlg converts the Run4 Readout geometry build from the GeoModelXML into the legacy M...
Definition: MdtCalibInput.h:20
EventPrimitivesToStringConverter.h
MuonGMR4::MmReadoutGeomTool::wMMTable::distBotFrameStrip
double distBotFrameStrip
Definition: MmReadoutGeomTool.h:40
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
MuonGMR4::MmReadoutElement::parameterBook::halfHeight
double halfHeight
length in the radial direction
Definition: MmReadoutElement.h:33
MuonGMR4::MmReadoutGeomTool::wMMTable::stripPitch
double stripPitch
Definition: MmReadoutGeomTool.h:38
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
CxxUtils
Definition: aligned_vector.h:29
MuonDetectorManager.h
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MuonGMR4::MmReadoutElement::parameterBook::halfLongWidth
double halfLongWidth
width of the upper edge
Definition: MmReadoutElement.h:31
MuonGMR4::MmReadoutGeomTool::buildReadOutElements
StatusCode buildReadOutElements(MuonDetectorManager &mgr) override final
Definition: MmReadoutGeomTool.cxx:169
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
MuonGMR4::MmReadoutGeomTool::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MmReadoutGeomTool.h:29
MuonGMR4::MmReadoutElement::parameterBook::layers
std::vector< StripLayerPtr > layers
Pointers to the strip layers.
Definition: MmReadoutElement.h:39
MuonGMR4::MuonReadoutElement::defineArgs::chambDesign
std::string chambDesign
chamber design name as it's occuring in the parameter book tables E.g. BMS5, RPC10,...
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonReadoutElement.h:49
MuonGMR4::MmReadoutGeomTool::FactoryCache::stripLayers
std::set< StripLayerPtr, StripLayerSorter > stripLayers
Definition: MmReadoutGeomTool.h:55
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
MuonGMR4::MmReadoutGeomTool::m_geoDbTagSvc
ServiceHandle< IGeoDbTagSvc > m_geoDbTagSvc
Definition: MmReadoutGeomTool.h:32
MuonGMR4::physVolWithTrans
IMuonGeoUtilityTool::physVolWithTrans physVolWithTrans
Definition: MdtReadoutGeomTool.cxx:33
Amg::getRotateY3D
Amg::Transform3D getRotateY3D(double angle)
get a rotation transformation around Y-axis
Definition: GeoPrimitivesHelpers.h:261
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MuonGMR4::MmReadoutGeomTool::readParameterBook
StatusCode readParameterBook(FactoryCache &cache)
Retrieves the auxillary tables from the database.
Definition: MmReadoutGeomTool.cxx:233
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
MuonGMR4::MmReadoutGeomTool::wMMTable
Struct to cache the relevant parameters of from the WRPC tables.
Definition: MmReadoutGeomTool.h:37
MuonGMR4::MmReadoutGeomTool::m_geoUtilTool
PublicToolHandle< IMuonGeoUtilityTool > m_geoUtilTool
Definition: MmReadoutGeomTool.h:34
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
MmIdHelper
Definition: MmIdHelper.h:54
MuonGMR4::MmReadoutGeomTool::wMMTable::nMissedBottomEta
int nMissedBottomEta
Definition: MmReadoutGeomTool.h:44
GeoPrimitivesHelpers.h
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
IRDBRecord_ptr
std::unique_ptr< IRDBRecord > IRDBRecord_ptr
Definition: IRDBRecordset.h:23
python.changerun.pv
pv
Definition: changerun.py:81
MuonGMR4::MmReadoutGeomTool::wMMTable::nMissedTopEta
int nMissedTopEta
Definition: MmReadoutGeomTool.h:46
CxxUtils::atoi
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
Definition: Control/CxxUtils/Root/StringUtils.cxx:85
MuonGMR4::MuonReadoutElement::defineArgs::detElId
Identifier detElId
ATLAS identifier.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonReadoutElement.h:51
ActsTrk
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Definition: MuonDetectorBuilderTool.cxx:54
ActsTrk::SurfaceBoundSetPtr
std::shared_ptr< SurfaceBoundSet< BoundType > > SurfaceBoundSetPtr
Aberivation to create a new SurfaceBoundSetPtr.
Definition: Tracking/Acts/ActsGeoUtils/ActsGeoUtils/Defs.h:19
IRDBRecordset.h
Definition of the abstract IRDBRecordset interface.
MuonGMR4::MuonReadoutElement::defineArgs::physVol
GeoIntrusivePtr< GeoVFullPhysVol > physVol
Pointer to the underlying physical volume in GeoModel.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonReadoutElement.h:45
MuonGMR4::MmReadoutGeomTool::wMMTable::nMissedBottomStereo
int nMissedBottomStereo
Definition: MmReadoutGeomTool.h:45
MuonGMR4::MmReadoutGeomTool::FactoryCache::stripDesigns
std::set< StripDesignPtr, StripDesignSorter > stripDesigns
Definition: MmReadoutGeomTool.h:54
MmReadoutGeomTool.h
MuonGMR4::MmReadoutElement::defineArgs
Definition: MmReadoutElement.h:49
MuonGMR4::MmReadoutGeomTool::loadDimensions
StatusCode loadDimensions(MmReadoutElement::defineArgs &args, FactoryCache &factory)
Loads the chamber dimensions from GeoModel.
Definition: MmReadoutGeomTool.cxx:40
ServiceHandle< IRDBAccessSvc >
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37