// Tb/TbEvent #include "Event/TbTrigger.h" #include "Event/TbHit.h" #include "Event/TbCluster.h" #include "Event/TbTrack.h" // Local #include "TbTupleWriter.h" DECLARE_ALGORITHM_FACTORY(TbTupleWriter) //============================================================================= // Standard constructor //============================================================================= TbTupleWriter::TbTupleWriter(const std::string& name, ISvcLocator* pSvcLocator) : TbAlgorithm(name, pSvcLocator) { declareProperty("WriteTriggers", m_writeTriggers = false); declareProperty("WriteHits", m_writeHits = false); declareProperty("WriteClusters", m_writeClusters = true); declareProperty("WriteTracks", m_writeTracks = false); declareProperty("MaxClusterSize", m_maxclustersize = 200); declareProperty("WriteClusterHits", m_writeClusterHits = true); declareProperty("TriggerLocation", m_triggerLocation = LHCb::TbTriggerLocation::Default); declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default); declareProperty("ClusterLocation", m_clusterLocation = LHCb::TbClusterLocation::Default); declareProperty("TrackLocation", m_trackLocation = LHCb::TbTrackLocation::Default); /// Stripped nTuples for low rate external users, /// only output tracks that have associated triggers declareProperty("StrippedNTuple", m_strippedNTuple = false); declareProperty("MaxTriggers", m_maxTriggers = 20 ); // Switch off output during finalize. setProperty("NTuplePrint", false); } //============================================================================= // Destructor //============================================================================= TbTupleWriter::~TbTupleWriter() {} //============================================================================= // Initialisation //============================================================================= StatusCode TbTupleWriter::initialize() { // Initialise the base class. StatusCode sc = TbAlgorithm::initialize(); if (sc.isFailure()) return sc; if (m_writeTriggers) bookTriggers(); if (m_writeHits) bookHits(); if (m_writeTracks) bookTracks(); if (m_writeClusters) bookClusters(); m_evtNo = 0; return StatusCode::SUCCESS; } //============================================================================= // Main execution //============================================================================= StatusCode TbTupleWriter::execute() { if (m_writeTriggers) fillTriggers(); if (m_writeHits) fillHits(); if (m_writeTracks) fillTracks(); if (m_writeClusters) fillClusters(); ++m_evtNo; return StatusCode::SUCCESS; } //============================================================================= // Book trigger tuple //============================================================================= void TbTupleWriter::bookTriggers() { NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1"); NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Trigger"); // Check if already booked. if (nt) return; nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Trigger", CLID_ColumnWiseTuple, "nTuple of Triggers"); nt->addItem("TgID", m_TgID); nt->addItem("TgTime", m_TgTime); nt->addItem("TgHTime", m_TgHTime); nt->addItem("TgEvt", m_TgEvt); nt->addItem("TgPlane", m_TgPlane); nt->addItem("TgCounter",m_TgCounter); } //============================================================================= // Book hit tuple //============================================================================= void TbTupleWriter::bookHits() { NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1"); NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Hits"); // Check if already booked. if (nt) return; nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Hits", CLID_ColumnWiseTuple, "nTuple of Hits"); nt->addItem("hID", m_hID); nt->addItem("hCol", m_hCol); nt->addItem("hRow", m_hRow); nt->addItem("hTime", m_hTime); nt->addItem("hHTime", m_hHTime); nt->addItem("hToT", m_hToT); nt->addItem("hPlane", m_hPlane); } //============================================================================= // Book cluster tuple //============================================================================= void TbTupleWriter::bookClusters() { NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1"); NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Clusters"); // Check if already booked. if (nt) return; nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Clusters", CLID_ColumnWiseTuple, "nTuple of Clusters"); nt->addItem("clID", m_clID); nt->addItem("clGx", m_clGx); nt->addItem("clGy", m_clGy); nt->addItem("clGz", m_clGz); nt->addItem("clLx", m_clLx); nt->addItem("clLy", m_clLy); nt->addItem("clTime", m_clTime); nt->addItem("clHTime", m_clHTime); nt->addItem("clSize", m_clSize); nt->addItem("clCharge", m_clCharge); nt->addItem("clIsTracked", m_clTracked); nt->addItem("clPlane", m_clPlane); nt->addItem("clEvtNo", m_clEvtNo); nt->addItem("clNHits", m_clN, 0, (int)m_maxclustersize); nt->addIndexedItem("hRow", m_clN, m_clhRow); nt->addIndexedItem("hCol", m_clN, m_clhCol); nt->addIndexedItem("sCol", m_clN, m_clsCol); nt->addIndexedItem("hHTime", m_clN, m_clhHTime); nt->addIndexedItem("hToT", m_clN, m_clhToT); } //============================================================================= // Book track tuple //============================================================================= void TbTupleWriter::bookTracks() { NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1"); NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Tracks"); // Check if already booked. if (nt) return; nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Tracks", CLID_ColumnWiseTuple, "nTuple of Tracks"); nt->addItem("TkID", m_TkID); nt->addItem("TkTime", m_TkTime); nt->addItem("TkHTime", m_TkHTime); nt->addItem("TkNCl", m_TkNCl, 0, 10); nt->addItem("TkX", m_TkX0); nt->addItem("TkY", m_TkY0); nt->addItem("TkTx", m_TkTx); nt->addItem("TkTy", m_TkTy); nt->addItem("TkChi2PerNdof", m_TkChi2ndof); nt->addIndexedItem("TkClId", m_TkNCl, m_TkClId); nt->addItem("TkEvt",m_TkEvt); nt->addItem("TkNTg",m_TkNTg,0,(int)m_maxTriggers); nt->addIndexedItem("TkTgId",m_TkNTg,m_TkTgId); nt->addIndexedItem("TkTgPlane",m_TkNTg,m_TkTgPlane); nt->addIndexedItem("TkXResidual",m_TkNCl, m_TkXResidual); nt->addIndexedItem("TkYResidual",m_TkNCl, m_TkYResidual); } //============================================================================= // Fill trigger tuple //============================================================================= void TbTupleWriter::fillTriggers() { const uint64_t evtOffset = (uint64_t)m_evtNo << 36; for (unsigned int i = 0 ; i < m_nPlanes; ++i) { const std::string location = m_triggerLocation + std::to_string(i); const LHCb::TbTriggers* triggers = getIfExists<LHCb::TbTriggers>(location); if (!triggers) continue; for (const LHCb::TbTrigger* trigger : *triggers) { // if (m_triggerChannel != 999 && m_triggerChannel != trigger->plane()) continue; const uint64_t offset = ((uint64_t)trigger->plane() << 32) + evtOffset; m_TgID = trigger->index() + offset; m_TgTime = trigger->time(); m_TgHTime = trigger->htime(); m_TgPlane = i; m_TgCounter = trigger->counter(); ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Trigger"); m_TgEvt = m_evtNo; } } } //============================================================================= // Fill hit tuple //============================================================================= void TbTupleWriter::fillHits() { const uint64_t evtOffset = (uint64_t)m_evtNo << 36; for (unsigned int i = 0; i < m_nPlanes; ++i) { const std::string location = m_hitLocation + std::to_string(i); const LHCb::TbHits* hits = getIfExists<LHCb::TbHits>(location); if (!hits) continue; const uint64_t offset = ((uint64_t)i << 32) + evtOffset; for (const LHCb::TbHit* hit : *hits) { m_hID = hit->index() + offset; m_hCol = hit->col(); m_hRow = hit->row(); m_hTime = hit->time(); m_hHTime = hit->htime(); m_hToT = hit->ToT(); m_hPlane = i; ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Hits"); } } } //============================================================================= // Fill cluster tuple //============================================================================= void TbTupleWriter::fillClusters() { const uint64_t evtOffset = (uint64_t)m_evtNo << 36; for (unsigned int i = 0; i < m_nPlanes; ++i) { const std::string location = m_clusterLocation + std::to_string(i); const LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(location); if (!clusters) continue; const uint64_t offset = ((uint64_t)i << 32) + evtOffset; for (const LHCb::TbCluster* cluster : *clusters) { const unsigned long long clid = cluster->index() + offset; m_clID = clid; m_clGx = cluster->x(); m_clGy = cluster->y(); m_clGz = cluster->z(); m_clLx = cluster->xloc(); m_clLy = cluster->yloc(); m_clTime = cluster->time(); m_clHTime = cluster->htime(); m_clSize = cluster->hits().size(); m_clCharge = cluster->charge(); m_clTracked = cluster->associated(); m_clPlane = cluster->plane(); m_clEvtNo = m_evtNo; m_clN = m_clSize > m_maxclustersize ? m_maxclustersize : m_clSize; for (unsigned int j = 0; j < m_clN; ++j) { const auto& h = cluster->hits()[j]; m_clhRow[j] = h->row(); m_clhCol[j] = h->col(); m_clsCol[j] = h->scol(); m_clhToT[j] = h->ToT(); m_clhHTime[j] = h->htime(); } ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Clusters"); } } } //============================================================================= // Fill track tuple //============================================================================= void TbTupleWriter::fillTracks() { const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation); if (!tracks) return; const uint64_t evtOffset = (uint64_t)m_evtNo << 36; for (const LHCb::TbTrack* track : *tracks) { if (m_strippedNTuple && track->triggers().empty()) continue; m_TkX0 = track->firstState().x(); m_TkY0 = track->firstState().y(); m_TkTx = track->firstState().tx(); m_TkTy = track->firstState().ty(); m_TkHTime = track->htime(); m_TkTime = track->time(); m_TkID = track->index() + evtOffset; m_TkNCl = track->clusters().size(); m_TkChi2ndof = track->chi2PerNdof(); m_TkEvt = m_evtNo; unsigned int i = 0; const SmartRefVector<LHCb::TbCluster>& clusters = track->clusters(); for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it) { const uint64_t offset = ((uint64_t)(*it)->plane() << 32) + evtOffset; const unsigned long long clid = (*it)->index() + offset; m_TkClId[i] = clid; auto intercept = geomSvc()->intercept( track, (*it)->plane() ); m_TkXResidual[(*it)->plane()] = (*it)->x() - intercept.x() ; m_TkYResidual[(*it)->plane()] = (*it)->y() - intercept.y() ; ++i; } const SmartRefVector<LHCb::TbCluster>& associatedClusters = track->associatedClusters(); for( auto it = associatedClusters.cbegin(), end = associatedClusters.cend(); it != end; ++it ){ const uint64_t offset = ((uint64_t)(*it)->plane() << 32) + evtOffset; const unsigned long long clid = (*it)->index() + offset; m_TkClId[i] = clid; auto intercept = geomSvc()->intercept( track, (*it)->plane() ); m_TkXResidual[(*it)->plane()] = (*it)->x() - intercept.x() ; m_TkYResidual[(*it)->plane()] = (*it)->y() - intercept.y() ; ++i; } m_TkNTg = track->triggers().size(); i = 0; const SmartRefVector<LHCb::TbTrigger>& triggers = track->triggers(); for (auto it = triggers.cbegin(), end = triggers.cend(); it != end; ++it) { const uint64_t offset = ((uint64_t)(*it)->plane() << 32) + evtOffset; const unsigned long long clid = (*it)->index() + offset; if (i == 20) { warning() << "More than 20 triggers associated to track: skipping" << endmsg; break; } m_TkTgId[i] = clid; m_TkTgPlane[i] = (*it)->plane(); ++i; } ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Tracks"); } }