// AIDA #include "AIDA/IAxis.h" // Gaudi #include "GaudiKernel/PhysicalConstants.h" #include "GaudiUtils/HistoLabels.h" // Tb/TbEvent #include "Event/TbTrack.h" #include "Event/TbCluster.h" // Tb/TbKernel #include "TbKernel/TbConstants.h" #include "TbKernel/TbModule.h" // Local #include "TbDUTMonitor.h" using namespace Gaudi::Utils::Histos; DECLARE_ALGORITHM_FACTORY(TbDUTMonitor) //============================================================================= // Standard constructor //============================================================================= TbDUTMonitor::TbDUTMonitor(const std::string& name, ISvcLocator* pSvcLocator) : TbAlgorithm(name, pSvcLocator), m_parResXY("", -0.2, 0.2, 200), m_parXY("", -20, 20, 500), m_parScanX("", 0, 0, 1), m_parScanY("", 0, 0, 1), m_parResTime("", -100., 100., 2000) { declareProperty("TrackLocation", m_trackLocation = LHCb::TbTrackLocation::Default); declareProperty("DUTs", m_duts); declareProperty("ScanX", m_parScanX); declareProperty("ScanY", m_parScanY); } //============================================================================= // Initialization //============================================================================= StatusCode TbDUTMonitor::initialize() { // Initialise the base class. StatusCode sc = TbAlgorithm::initialize(); if (sc.isFailure()) return sc; // Setup the histograms. const unsigned int nDuts = m_duts.size(); for (unsigned int i = 0; i < nDuts; ++i) { m_index[m_duts[i]] = i; const std::string plane = std::to_string(m_duts[i]); const std::string title = geomSvc()->modules().at(m_duts[i])->id(); unsigned int bins = m_parResXY.bins(); double low = m_parResXY.lowEdge(); double high = m_parResXY.highEdge(); std::string name = "ResidualsLocalX/Plane" + plane; m_hResLocalX.push_back(book1D(name, title, low, high, bins)); name = "ResidualsLocalY/Plane" + plane; m_hResLocalY.push_back(book1D(name, title, low, high, bins)); name = "ResidualsGlobalX/Plane" + plane; m_hResGlobalX.push_back(book1D(name, title, low, high, bins)); name = "ResidualsGlobalY/Plane" + plane; m_hResGlobalY.push_back(book1D(name, title, low, high, bins)); setAxisLabels(m_hResLocalX[i], "#it{x} - #it{x}_{track} [mm]", "entries"); setAxisLabels(m_hResLocalY[i], "#it{y} - #it{y}_{track} [mm]", "entries"); unsigned int binsXY = m_parXY.bins(); double lowXY = m_parXY.lowEdge(); double highXY = m_parXY.highEdge(); m_hUnbiasedResGlobalXvsGlobalX.push_back( book2D("GlobalResXvsGlobalX/Plane" + plane, title, lowXY, highXY, binsXY, low, high, bins)); m_hUnbiasedResGlobalYvsGlobalY.push_back( book2D("GlobalResYvsGlobalY/Plane" + plane, title, lowXY, highXY, binsXY, low, high, bins)); m_hUnbiasedResGlobalXvsTrackChi2.push_back( book2D("GlobalResXvsTrackChi2/Plane" + plane, title, 0, 100, 1000, low, high, bins)); m_hUnbiasedResGlobalYvsTrackChi2.push_back( book2D("GlobalResYvsTrackChi2/Plane" + plane, title, 0, 100, 1000, low, high, bins)); m_hUnbiasedResGlobalXvsTrackTx.push_back( book2D("GlobalResXvsTrackTx/Plane" + plane, title, -0.002, 0.002, 100, low, high, bins)); m_hUnbiasedResGlobalXvsTrackTy.push_back( book2D("GlobalResXvsTrackTy/Plane" + plane, title, -0.002, 0.002, 100, low, high, bins)); m_hUnbiasedResGlobalYvsTrackTx.push_back( book2D("GlobalResYvsTrackTx/Plane" + plane, title, -0.002, 0.002, 100, low, high, bins)); m_hUnbiasedResGlobalYvsTrackTy.push_back( book2D("GlobalResYvsTrackTy/Plane" + plane, title, -0.002, 0.002, 100, low, high, bins)); m_hUnbiasedResGlobalXvsPixelX.push_back( book2D("UnbiasedResGlobalXvsPixelX/Plane" + plane, title, -1.0, 1.0, 200, low, high, bins)); m_hUnbiasedResGlobalXvsPixelY.push_back( book2D("UnbiasedResGlobalXvsPixelY/Plane" + plane, title, -1.0, 1.0, 200, low, high, bins)); m_hUnbiasedResGlobalYvsPixelX.push_back( book2D("UnbiasedResGlobalYvsPixelX/Plane" + plane, title, -1.0, 1.0, 200, low, high, bins)); m_hUnbiasedResGlobalYvsPixelY.push_back( book2D("UnbiasedResGlobalYvsPixelY/Plane" + plane, title, -1.0, 1.0, 200, low, high, bins)); m_hUnbiasedResGlobalXvsClusterSize.push_back( book2D("GlobalResXvsClusterSize/Plane" + plane, title, 0.5, 10.5, 10, low, high, bins)); m_hUnbiasedResGlobalYvsClusterSize.push_back( book2D("GlobalResYvsClusterSize/Plane" + plane, title, 0.5, 10.5, 10, low, high, bins)); // m_UnbiasedResGlobalXvshUnbiasedResGlobalY m_UnbiasedResGlobalXvshUnbiasedResGlobalY.push_back( book2D("UnbiasedResGlobalXvshUnbiasedResGlobalY/Plane" + plane, title, low, high, bins, low, high, bins)); bins = m_parResTime.bins(); low = m_parResTime.lowEdge(); high = m_parResTime.highEdge(); name = "ResidualsTime/Plane" + plane; m_hResTime.push_back(book1D(name, title, low, high, bins)); setAxisLabels(m_hResTime[i], "#it{t} - #it{t}_{track} [ns]", "entries"); } std::vector<std::string> labels = {"X", "Y", "Z", "rotX", "rotY", "rotZ"}; unsigned int binsXY = m_parXY.bins(); double lowXY = m_parXY.lowEdge(); double highXY = m_parXY.highEdge(); unsigned int bins = m_parResXY.bins(); double low = m_parResXY.lowEdge(); double high = m_parResXY.highEdge(); if (nDuts == 0) return sc; TbModule* mod = geomSvc()->module(m_duts[0]); std::vector<bool> xaxis(6, 0); std::vector<bool> yaxis(6, 0); std::vector<std::string>::iterator xL = std::find(labels.begin(), labels.end(), m_parScanX.title()); std::vector<std::string>::iterator yL = std::find(labels.begin(), labels.end(), m_parScanY.title()); if (xL != labels.end()) xaxis[xL - labels.begin()] = 1; if (yL != labels.end()) yaxis[yL - labels.begin()] = 1; if (xL != labels.end()) { for (int i = 0; i < m_parScanX.bins(); ++i) { const double px = m_parScanX.lowEdge() + i * (m_parScanX.highEdge() - m_parScanX.lowEdge()) / m_parScanX.bins(); std::string label = "Scan #Delta" + m_parScanX.title() + " = " + std::to_string(px); if (yL == labels.end()) { info() << "Booking scan " << *xL << " = " << px << endmsg; m_hScanXvsX.push_back(book2D("XvsX/Scan" + std::to_string(i), label, lowXY, highXY, binsXY, low, high, bins)); m_hScanYvsY.push_back(book2D("YvsY/Scan" + std::to_string(i), label, lowXY, highXY, binsXY, low, high, bins)); m_testModules.push_back(new TbModule()); (*m_testModules.rbegin())->setAlignment( mod->x() + px * xaxis[0], mod->y() + px * xaxis[1], mod->z() + px * xaxis[2], mod->rotX() + px * xaxis[3], mod->rotY() + px * xaxis[4], mod->rotZ() + px * xaxis[5], 0, 0, 0, 0, 0, 0); } else { for (int j = 0; j < m_parScanY.bins(); ++j) { const double py = m_parScanY.lowEdge() + j * (m_parScanY.highEdge() - m_parScanY.lowEdge()) / m_parScanY.bins(); info() << "Booking scan " << *xL << " = " << px << ", " << *yL << " = " << py << endmsg; std::string l = label + ", " + m_parScanY.title() + " = " + std::to_string(py); m_hScanXvsX.push_back( book2D("XvsX/Scan" + std::to_string(i * m_parScanY.bins() + j), l, lowXY, highXY, binsXY, low, high, bins)); m_hScanYvsY.push_back( book2D("YvsY/Scan" + std::to_string(i * m_parScanY.bins() + j), l, lowXY, highXY, binsXY, low, high, bins)); m_testModules.push_back(new TbModule()); (*m_testModules.rbegin())->setAlignment( mod->x() + px * xaxis[0] + py * yaxis[0], mod->y() + px * xaxis[1] + py * yaxis[1], mod->z() + px * xaxis[2] + py * yaxis[2], mod->rotX() + px * xaxis[3] + py * yaxis[3], mod->rotY() + px * xaxis[4] + py * yaxis[4], mod->rotZ() + px * xaxis[5] + py * yaxis[5], 0, 0, 0, 0, 0, 0); } } } } return StatusCode::SUCCESS; } //============================================================================= // Main execution //============================================================================= StatusCode TbDUTMonitor::execute() { // Grab the tracks. const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation); if (!tracks) { return Error("No tracks in " + m_trackLocation); } // Loop over the tracks. for (const LHCb::TbTrack* track : *tracks) { auto clusters = track->associatedClusters(); for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it) { const unsigned int plane = (*it)->plane(); if (m_index.count(plane) < 1) continue; const Gaudi::XYZPoint pGlobal = geomSvc()->intercept(track, plane); const auto pLocal = geomSvc()->globalToLocal(pGlobal, plane); const unsigned int i = m_index[plane]; const double dt = (*it)->htime() - track->htime(); const double dx = (*it)->xloc() - pLocal.x(); const double dy = (*it)->yloc() - pLocal.y(); m_hResLocalX[i]->fill(dx); m_hResLocalY[i]->fill(dy); const double dxug = (*it)->x() - pGlobal.x(); const double dyug = (*it)->y() - pGlobal.y(); m_hResGlobalX[i]->fill(dxug); m_hResGlobalY[i]->fill(dyug); m_hUnbiasedResGlobalXvsGlobalX[i]->fill((*it)->x(), dxug); m_hUnbiasedResGlobalYvsGlobalY[i]->fill((*it)->y(), dyug); m_hResTime[i]->fill(dt); m_hUnbiasedResGlobalXvsTrackChi2[i]->fill(track->chi2PerNdof(), dxug); m_hUnbiasedResGlobalYvsTrackChi2[i]->fill(track->chi2PerNdof(), dyug); m_UnbiasedResGlobalXvshUnbiasedResGlobalY[i]->fill(dxug, dyug); m_hUnbiasedResGlobalXvsTrackTx[i]->fill(track->firstState().tx(), dxug); m_hUnbiasedResGlobalXvsTrackTy[i]->fill(track->firstState().ty(), dxug); m_hUnbiasedResGlobalYvsTrackTx[i]->fill(track->firstState().tx(), dyug); m_hUnbiasedResGlobalYvsTrackTy[i]->fill(track->firstState().ty(), dyug); m_hUnbiasedResGlobalXvsClusterSize[i]->fill((*it)->hits().size(), dxug); m_hUnbiasedResGlobalYvsClusterSize[i]->fill((*it)->hits().size(), dyug); unsigned int row, col; geomSvc()->pointToPixel(pLocal.x(), pLocal.y(), 4, col, row); double x0, y0; geomSvc()->pixelToPoint(col, row, 4, x0, y0); const double pixelX = (pLocal.x() - x0) / 0.055; const double pixelY = (pLocal.y() - y0) / 0.055; m_hUnbiasedResGlobalXvsPixelX[i]->fill(pixelX, dxug); m_hUnbiasedResGlobalXvsPixelY[i]->fill(pixelY, dxug); m_hUnbiasedResGlobalYvsPixelX[i]->fill(pixelX, dyug); m_hUnbiasedResGlobalYvsPixelY[i]->fill(pixelY, dyug); for (int j = 0; j < m_testModules.size(); ++j) { const auto& p = track->firstState().position(); const auto& t = track->firstState().slopes(); const Gaudi::XYZVector n = m_testModules[j]->normal(); const double s = n.Dot(m_testModules[j]->centre() - p) / n.Dot(t); const auto intercept = p + s * t; const auto cl = m_testModules[j]->transform() * Gaudi::XYZPoint((*it)->xloc(), (*it)->yloc(), 0); const double dxug = cl.x() - intercept.x(); const double dyug = cl.y() - intercept.y(); m_hScanXvsX[j]->fill(cl.x(), dxug); m_hScanYvsY[j]->fill(cl.y(), dyug); } } } return StatusCode::SUCCESS; }