File indexing completed on 2025-12-17 09:20:01
0001 #include "CaloVtxReco.h"
0002
0003 #include <jetbase/Jet.h>
0004 #include <jetbase/JetContainer.h>
0005
0006 #include <calobase/RawTowerGeom.h>
0007 #include <calobase/RawTowerGeomContainer.h>
0008 #include <calobase/TowerInfo.h>
0009 #include <calobase/TowerInfoContainer.h>
0010 #include <calobase/TowerInfoDefs.h>
0011
0012 #include <globalvertex/CaloVertexMapv1.h>
0013 #include <globalvertex/CaloVertexv1.h>
0014
0015 #include <fun4all/Fun4AllReturnCodes.h>
0016
0017 #include <phool/PHCompositeNode.h>
0018 #include <phool/getClass.h>
0019
0020 #include <cmath>
0021
0022
0023
0024
0025
0026 CaloVtxReco::CaloVtxReco(const std::string &name, const std::string &jetnodename, const bool use_z_energy_dep)
0027 : SubsysReco(name)
0028 , m_use_z_energy_dep(use_z_energy_dep)
0029 , m_jetnodename(jetnodename)
0030 {
0031 }
0032
0033 int CaloVtxReco::createNodes(PHCompositeNode *topNode)
0034 {
0035 PHNodeIterator iter(topNode);
0036 PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0037 if (!dstNode)
0038 {
0039 std::cout << PHWHERE << "DST Node missing doing nothing" << std::endl;
0040 return Fun4AllReturnCodes::ABORTRUN;
0041 }
0042
0043 PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "RUN"));
0044 if (!runNode)
0045 {
0046 std::cout << PHWHERE << "RUN Node missing doing nothing" << std::endl;
0047 return Fun4AllReturnCodes::ABORTRUN;
0048 }
0049
0050 PHNodeIterator dstiter(dstNode);
0051
0052 PHCompositeNode *globalNode = dynamic_cast<PHCompositeNode *>(dstiter.findFirst("PHCompositeNode", "GLOBAL"));
0053 if (!globalNode)
0054 {
0055 globalNode = new PHCompositeNode("GLOBAL");
0056 dstNode->addNode(globalNode);
0057 }
0058
0059 m_calovtxmap = findNode::getClass<CaloVertexMap>(globalNode, "CaloVertexMap");
0060 if (!m_calovtxmap)
0061 {
0062 m_calovtxmap = new CaloVertexMapv1();
0063 PHIODataNode<PHObject> *VertexMapNode = new PHIODataNode<PHObject>(m_calovtxmap, "CaloVertexMap", "PHObject");
0064 globalNode->addNode(VertexMapNode);
0065 }
0066
0067 return Fun4AllReturnCodes::EVENT_OK;
0068 }
0069
0070
0071 int CaloVtxReco::InitRun(PHCompositeNode *topNode)
0072 {
0073 if (Verbosity() > 1)
0074 {
0075 std::cout << "Initializing!" << std::endl;
0076 }
0077 if (createNodes(topNode) == Fun4AllReturnCodes::ABORTRUN)
0078 {
0079 return Fun4AllReturnCodes::ABORTRUN;
0080 }
0081
0082 RawTowerGeomContainer *tower_geomEM = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_CEMC");
0083 RawTowerGeomContainer *tower_geomOH = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALOUT");
0084 if(!tower_geomEM || !tower_geomOH)
0085 {
0086 if(Verbosity() > 0)
0087 {
0088 std::cout << "CaloVtxReco::InitRun(): Missing tower geometry node for towergeomEM (address: " << tower_geomEM << ") or towergeomOH (address: " << tower_geomOH << ") - aborting run!" << std::endl;
0089 }
0090 return Fun4AllReturnCodes::ABORTRUN;
0091 }
0092
0093 m_radius_EM = tower_geomEM->get_radius();
0094 m_radius_OH = tower_geomOH->get_radius();
0095
0096 if(std::isnan(m_radius_EM) || std::isnan(m_radius_OH))
0097 {
0098 if(Verbosity() > 0)
0099 {
0100 std::cout << "CaloVtxReco::InitRun(): NaN value for one of radius EM (value: " << m_radius_EM << ") or radius OH (value: " << m_radius_OH << ") after attempting to get - aborting run!" << std::endl;
0101 }
0102 return Fun4AllReturnCodes::ABORTRUN;
0103 }
0104
0105
0106 return Fun4AllReturnCodes::EVENT_OK;
0107 }
0108
0109 float CaloVtxReco::new_eta(int channel, TowerInfoContainer *towers, RawTowerGeomContainer *geom, RawTowerDefs::CalorimeterId caloID, float testz)
0110 {
0111 int key = towers->encode_key(channel);
0112 const RawTowerDefs::keytype geomkey = RawTowerDefs::encode_towerid(caloID, towers->getTowerEtaBin(key), towers->getTowerPhiBin(key));
0113
0114 RawTowerGeom *tower_geom = geom->get_tower_geometry(geomkey);
0115 float oldeta = tower_geom->get_eta();
0116
0117 float radius = (caloID == RawTowerDefs::CalorimeterId::HCALIN ? m_radius_EM : m_radius_OH);
0118 float towerz = radius / (tanf(2 * std::atanf(std::exp(oldeta))));
0119 float newz = towerz + testz;
0120 float newTheta = std::atan2(radius, newz);
0121 float neweta = -log(tan(0.5 * newTheta));
0122
0123 return neweta;
0124 }
0125
0126 float get_dphi(float phi1, float phi2)
0127 {
0128 float dphi = std::abs(phi1 - phi2);
0129 if (dphi > M_PI)
0130 {
0131 dphi = 2 * M_PI - dphi;
0132 }
0133 return dphi;
0134 }
0135
0136 int CaloVtxReco::calo_tower_algorithm(PHCompositeNode *topNode) const
0137 {
0138 TowerInfoContainer *emcal_towers = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_CEMC");
0139 TowerInfoContainer *hcalin_towers = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_HCALIN");
0140 TowerInfoContainer *hcalout_towers = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_HCALOUT");
0141 RawTowerGeomContainer *tower_geomEM = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_CEMC");
0142 RawTowerGeomContainer *tower_geomIH = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALIN");
0143 RawTowerGeomContainer *tower_geomOH = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALOUT");
0144
0145 int size;
0146
0147 float average_z[3]{0};
0148 float total_E[3]{0};
0149
0150 if (emcal_towers)
0151 {
0152 size = emcal_towers->size();
0153 for (int channel = 0; channel < size; channel++)
0154 {
0155 TowerInfo *_tower = emcal_towers->get_tower_at_channel(channel);
0156 short good = (_tower->get_isGood() ? 1 : 0);
0157 if (!good)
0158 {
0159 continue;
0160 }
0161
0162 float energy = _tower->get_energy();
0163 if (energy < m_energy_cut)
0164 {
0165 continue;
0166 }
0167
0168
0169
0170 unsigned int towerkey = emcal_towers->encode_key(channel);
0171 int ieta = emcal_towers->getTowerEtaBin(towerkey);
0172 int iphi = emcal_towers->getTowerPhiBin(towerkey);
0173
0174 const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::CEMC, ieta, iphi);
0175
0176
0177
0178
0179
0180
0181 float tower_z = tower_geomEM->get_tower_geometry(key)->get_center_z();
0182 average_z[0] += tower_z * energy;
0183 total_E[0] += energy;
0184 }
0185 }
0186
0187 if (hcalin_towers)
0188 {
0189 size = hcalin_towers->size();
0190 for (int channel = 0; channel < size; channel++)
0191 {
0192 TowerInfo *_tower = hcalin_towers->get_tower_at_channel(channel);
0193 float energy = _tower->get_energy();
0194 if (energy < m_energy_cut)
0195 {
0196 continue;
0197 }
0198
0199 short good = (_tower->get_isGood() ? 1 : 0);
0200 if (!good)
0201 {
0202 continue;
0203 }
0204
0205 unsigned int towerkey = hcalin_towers->encode_key(channel);
0206 int ieta = hcalin_towers->getTowerEtaBin(towerkey);
0207 int iphi = hcalin_towers->getTowerPhiBin(towerkey);
0208 const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALIN, ieta, iphi);
0209 float tower_z = tower_geomIH->get_tower_geometry(key)->get_center_z();
0210
0211
0212
0213
0214
0215
0216 average_z[1] += tower_z * energy;
0217 total_E[1] += energy;
0218 }
0219 }
0220 if (hcalout_towers)
0221 {
0222 size = hcalout_towers->size();
0223 for (int channel = 0; channel < size; channel++)
0224 {
0225 TowerInfo *_tower = hcalout_towers->get_tower_at_channel(channel);
0226 float energy = _tower->get_energy();
0227 if (energy < m_energy_cut)
0228 {
0229 continue;
0230 }
0231
0232 unsigned int towerkey = hcalout_towers->encode_key(channel);
0233 int ieta = hcalout_towers->getTowerEtaBin(towerkey);
0234 int iphi = hcalout_towers->getTowerPhiBin(towerkey);
0235 short good = (_tower->get_isGood() ? 1 : 0);
0236
0237 if (!good)
0238 {
0239 continue;
0240 }
0241
0242 const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALOUT, ieta, iphi);
0243
0244
0245
0246
0247
0248
0249 float tower_z = tower_geomOH->get_tower_geometry(key)->get_center_z();
0250 average_z[2] += tower_z * energy;
0251 total_E[2] += energy;
0252 }
0253 }
0254
0255 double b_calo_vertex_z = (average_z[0] + average_z[1] + average_z[2]) / (total_E[0] + total_E[1] + total_E[2]);
0256
0257 CaloVertex *vertex = new CaloVertexv1();
0258 vertex->set_z(b_calo_vertex_z);
0259 m_calovtxmap->insert(vertex);
0260
0261 return 0;
0262 }
0263
0264 int CaloVtxReco::process_event(PHCompositeNode *topNode)
0265 {
0266 if (m_use_z_energy_dep)
0267 {
0268 calo_tower_algorithm(topNode);
0269 return Fun4AllReturnCodes::EVENT_OK;
0270 }
0271
0272 if (Verbosity() > 1)
0273 {
0274 std::cout << std::endl
0275 << std::endl
0276 << std::endl
0277 << "CaloVtxReco: Beginning event processing" << std::endl;
0278 }
0279 m_zvtx = std::numeric_limits<float>::quiet_NaN();
0280 JetContainer *jetcon = findNode::getClass<JetContainer>(topNode, m_jetnodename);
0281 TowerInfoContainer *towers[3];
0282 towers[0] = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_CEMC_RETOWER");
0283 towers[1] = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_HCALIN");
0284 towers[2] = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_HCALOUT");
0285
0286 RawTowerGeomContainer *geom[3];
0287 geom[0] = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_CEMC");
0288 geom[1] = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALIN");
0289 geom[2] = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALOUT");
0290
0291 const int nz = 601;
0292 const int njet = 2;
0293 Jet *jets[njet];
0294 float jpt[njet] = {0};
0295 float jemsum[njet] = {0};
0296 float johsum[njet] = {0};
0297 float jemeta[njet] = {0};
0298 float joheta[njet] = {0};
0299
0300 if (jetcon)
0301 {
0302 int tocheck = jetcon->size();
0303 if (Verbosity() > 2)
0304 {
0305 std::cout << "Found " << tocheck << " jets to check..." << std::endl;
0306 }
0307 for (int i = 0; i < tocheck; ++i)
0308 {
0309 Jet *jet = jetcon->get_jet(i);
0310 if (jet)
0311 {
0312 float pt = jet->get_pt();
0313 if (pt < m_jet_threshold)
0314 {
0315 continue;
0316 }
0317 if (pt > jpt[0])
0318 {
0319 jpt[1] = jpt[0];
0320 jets[1] = jets[0];
0321 jets[0] = jet;
0322 jpt[0] = pt;
0323 }
0324 else if (pt > jpt[1])
0325 {
0326 jets[1] = jet;
0327 jpt[1] = pt;
0328 }
0329 }
0330 }
0331 }
0332 else
0333 {
0334 if (Verbosity() > 0)
0335 {
0336 std::cout << "no jets" << std::endl;
0337 }
0338 return Fun4AllReturnCodes::ABORTEVENT;
0339 }
0340
0341 if (jpt[0] == 0)
0342 {
0343 if (Verbosity() > 2)
0344 {
0345 std::cout << "NO JETS > 5 GeV!" << std::endl;
0346 }
0347 }
0348
0349 float metric = std::numeric_limits<float>::max();
0350 for (int i = 0; i < nz; ++i)
0351 {
0352 float testz = -300 + i;
0353 float testmetric = 0;
0354 for (int j = 0; j < njet; ++j)
0355 {
0356 if (jpt[j] == 0)
0357 {
0358 continue;
0359 }
0360 jemsum[j] = 0;
0361 johsum[j] = 0;
0362 jemeta[j] = 0;
0363 joheta[j] = 0;
0364 for (auto comp : jets[j]->get_comp_vec())
0365 {
0366 if (comp.first == 5 || comp.first == 26)
0367 {
0368 continue;
0369 }
0370 unsigned int channel = comp.second;
0371 if (comp.first == 7 || comp.first == 27)
0372 {
0373 TowerInfo *tower = towers[2]->get_tower_at_channel(channel);
0374 if (tower->get_energy() < 0.1)
0375 {
0376 continue;
0377 }
0378 johsum[j] += tower->get_energy();
0379 float neweta = new_eta(channel, towers[2], geom[2], RawTowerDefs::CalorimeterId::HCALOUT, testz);
0380 joheta[j] += neweta * tower->get_energy();
0381 }
0382 if (comp.first == 13 || comp.first == 28 || comp.first == 25)
0383 {
0384 TowerInfo *tower = towers[0]->get_tower_at_channel(channel);
0385 if (tower->get_energy() < 0.1)
0386 {
0387 continue;
0388 }
0389 jemsum[j] += tower->get_energy();
0390 float neweta = new_eta(channel, towers[0], geom[1], RawTowerDefs::CalorimeterId::HCALIN, testz);
0391 jemeta[j] += neweta * tower->get_energy();
0392 }
0393 }
0394 jemeta[j] /= jemsum[j];
0395 joheta[j] /= johsum[j];
0396 if ((jemsum[j] == 0 || johsum[j] == 0) && Verbosity() > 1)
0397 {
0398 std::cout << "zero E sum in at least one calo for a jet" << std::endl;
0399 }
0400 if (!std::isnan(jemeta[j]) && !std::isnan(joheta[j]))
0401 {
0402 testmetric += pow(jemeta[j] - joheta[j], 2);
0403 }
0404 }
0405 if (Verbosity() > 3)
0406 {
0407 std::cout << "metric: " << testmetric << std::endl;
0408 }
0409 if (testmetric < metric && testmetric != 0)
0410 {
0411 metric = testmetric;
0412 m_zvtx = testz;
0413 }
0414 }
0415 if (std::abs(m_zvtx) < 305)
0416 {
0417 if (Verbosity() > 2)
0418 {
0419 std::cout << "optimal z: " << m_zvtx << std::endl;
0420 }
0421 CaloVertex *vertex = new CaloVertexv1();
0422 m_zvtx *= m_calib_factor;
0423 vertex->set_z(m_zvtx);
0424 m_calovtxmap->insert(vertex);
0425 if (Verbosity() > 3)
0426 {
0427 std::cout << "CaloVtxReco: end event" << std::endl;
0428 }
0429 }
0430 return Fun4AllReturnCodes::EVENT_OK;
0431 }