File indexing completed on 2025-08-06 08:17:34
0001 #include "RawClusterBuilderTopo.h"
0002
0003 #include <calobase/RawCluster.h>
0004 #include <calobase/RawClusterContainer.h>
0005 #include <calobase/RawClusterv1.h>
0006 #include <calobase/RawTowerDefs.h> // for encode_towerid, Calorime...
0007 #include <calobase/RawTowerGeom.h>
0008 #include <calobase/RawTowerGeomContainer.h>
0009 #include <calobase/TowerInfo.h> // for TowerInfo
0010 #include <calobase/TowerInfoContainer.h> // for TowerInfoContainer
0011
0012 #include <fun4all/Fun4AllReturnCodes.h>
0013 #include <fun4all/SubsysReco.h>
0014
0015 #include <phool/PHCompositeNode.h>
0016 #include <phool/PHIODataNode.h>
0017 #include <phool/PHNode.h>
0018 #include <phool/PHNodeIterator.h>
0019 #include <phool/PHObject.h>
0020 #include <phool/getClass.h>
0021 #include <phool/phool.h>
0022
0023 #include <algorithm>
0024 #include <cmath>
0025 #include <cstdlib> // for abs
0026 #include <exception>
0027 #include <iostream>
0028 #include <iterator> // for begin, end
0029 #include <list>
0030 #include <memory> // for allocator_traits<>::valu...
0031 #include <stdexcept>
0032 #include <utility>
0033 #include <vector>
0034
0035 namespace
0036 {
0037 bool sort_by_pair_second(const std::pair<int, float> &a, const std::pair<int, float> &b)
0038 {
0039 return (a.second > b.second);
0040 }
0041 }
0042
0043 int RawClusterBuilderTopo::RawClusterBuilderTopo_constants_EMCal_eta_start_given_IHCal[24] =
0044 {2, 6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44,
0045 48, 52, 55, 59, 63, 66, 70, 74, 78, 82, 86, 90};
0046
0047 int RawClusterBuilderTopo::RawClusterBuilderTopo_constants_EMCal_eta_end_given_IHCal[24] =
0048 {5, 9, 13, 17, 21, 25, 29, 32, 36, 40, 43, 47,
0049 51, 54, 58, 62, 65, 69, 73, 77, 81, 85, 89, 93};
0050
0051 int RawClusterBuilderTopo::RawClusterBuilderTopo_constants_IHCal_eta_given_EMCal[96] = {
0052 -1, -1, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2,
0053 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,
0054 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8,
0055 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11,
0056 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15,
0057 15, 15, 15, 16, 16, 16, 17, 17, 17, 17, 18, 18,
0058 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21,
0059 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, -1, -1};
0060
0061 float RawClusterBuilderTopo::calculate_dR(float eta1, float eta2, float phi1, float phi2)
0062 {
0063 float deta = eta1 - eta2;
0064 float dphi = phi1 - phi2;
0065 while (dphi > M_PI)
0066 {
0067 dphi -= 2 * M_PI;
0068 }
0069 while (dphi < -M_PI)
0070 {
0071 dphi += 2 * M_PI;
0072 }
0073 return sqrt(pow(deta, 2) + pow(dphi, 2));
0074 }
0075
0076 std::vector<int> RawClusterBuilderTopo::get_adjacent_towers_by_ID(int ID)
0077 {
0078 int this_layer = get_ilayer_from_ID(ID);
0079 int this_eta = get_ieta_from_ID(ID);
0080 int this_phi = get_iphi_from_ID(ID);
0081
0082 std::vector<int> adjacent_towers;
0083
0084
0085 if (this_layer == 0 || this_layer == 1)
0086 {
0087 for (int delta_layer = 0; delta_layer <= 1; delta_layer++)
0088 {
0089 for (int delta_eta = -1; delta_eta <= 1; delta_eta++)
0090 {
0091 for (int delta_phi = -1; delta_phi <= 1; delta_phi++)
0092 {
0093 if (delta_layer == 0 && delta_eta == 0 && delta_phi == 0)
0094 {
0095 continue;
0096 }
0097
0098 int test_eta = this_eta + delta_eta;
0099 if (test_eta < 0 || test_eta >= _HCAL_NETA)
0100 {
0101 continue;
0102 }
0103
0104 int test_layer = (this_layer + delta_layer) % 2;
0105 int test_phi = (this_phi + delta_phi + _HCAL_NPHI) % _HCAL_NPHI;
0106
0107
0108 if (!_allow_corner_neighbor && delta_layer == 1 && abs(delta_phi) == 1 && abs(delta_eta) == 1)
0109 {
0110 if (Verbosity() > 20)
0111 {
0112 std::cout << "RawClusterBuilderTopo::get_adjacent_towers_by_ID : corner growth not allowed " << std::endl;
0113 }
0114 continue;
0115 }
0116
0117
0118 adjacent_towers.push_back(get_ID(test_layer, test_eta, test_phi));
0119 }
0120 }
0121 }
0122 }
0123
0124
0125 if (this_layer == 0 && _enable_EMCal)
0126 {
0127 int EMCal_phi_start = get_first_matching_EMCal_phi_from_IHCal(this_phi);
0128 int EMCal_eta_start = RawClusterBuilderTopo_constants_EMCal_eta_start_given_IHCal[this_eta];
0129 int EMCal_eta_end = RawClusterBuilderTopo_constants_EMCal_eta_end_given_IHCal[this_eta];
0130
0131 for (int new_eta = EMCal_eta_start; new_eta <= EMCal_eta_end; new_eta++)
0132 {
0133 for (int delta_phi = 0; delta_phi < 4; delta_phi++)
0134 {
0135 int new_phi = (EMCal_phi_start + delta_phi + _EMCAL_NPHI) % _EMCAL_NPHI;
0136
0137 int EMCal_tower = get_ID(2, new_eta, new_phi);
0138 if (Verbosity() > 20)
0139 {
0140 std::cout << "RawClusterBuilderTopo::get_adjacent_towers_by_ID : HCal tower with eta / phi = " << this_eta << " / " << this_phi << ", adding EMCal tower with eta / phi = " << new_eta << " / " << new_phi << std::endl;
0141 }
0142 adjacent_towers.push_back(EMCal_tower);
0143 }
0144 }
0145 }
0146
0147
0148 if (this_layer == 2)
0149 {
0150
0151 for (int delta_eta = -1; delta_eta <= 1; delta_eta++)
0152 {
0153 for (int delta_phi = -1; delta_phi <= 1; delta_phi++)
0154 {
0155 if (delta_eta == 0 && delta_phi == 0)
0156 {
0157 continue;
0158 }
0159
0160 int test_eta = this_eta + delta_eta;
0161 if (test_eta < 0 || test_eta >= _EMCAL_NETA)
0162 {
0163 continue;
0164 }
0165
0166 int test_phi = (this_phi + delta_phi + _EMCAL_NPHI) % _EMCAL_NPHI;
0167
0168
0169 adjacent_towers.push_back(get_ID(this_layer, test_eta, test_phi));
0170 }
0171 }
0172
0173
0174 if (_enable_HCal)
0175 {
0176 int HCal_eta = RawClusterBuilderTopo_constants_IHCal_eta_given_EMCal[this_eta];
0177 int HCal_phi = get_matching_HCal_phi_from_EMCal(this_phi);
0178
0179 if (HCal_eta >= 0)
0180 {
0181 int IHCal_tower = get_ID(0, HCal_eta, HCal_phi);
0182 if (Verbosity() > 20)
0183 {
0184 std::cout << "RawClusterBuilderTopo::get_adjacent_towers_by_ID : EMCal tower with eta / phi = " << this_eta << " / " << this_phi << ", adding IHCal tower with eta / phi = " << HCal_eta << " / " << HCal_phi << std::endl;
0185 }
0186 adjacent_towers.push_back(IHCal_tower);
0187 }
0188 else
0189 {
0190 if (Verbosity() > 20)
0191 {
0192 std::cout << "RawClusterBuilderTopo::get_adjacent_towers_by_ID : EMCal tower with eta / phi = " << this_eta << " / " << this_phi << ", does not have matching IHCal due to large eta " << std::endl;
0193 }
0194 }
0195 }
0196 }
0197
0198 return adjacent_towers;
0199 }
0200
0201 void RawClusterBuilderTopo::export_single_cluster(const std::vector<int> &original_towers)
0202 {
0203 if (Verbosity() > 2)
0204 {
0205 std::cout << "RawClusterBuilderTopo::export_single_cluster called " << std::endl;
0206 }
0207
0208 std::map<int, std::pair<int, int> > tower_ownership;
0209 for (const int &original_tower : original_towers)
0210 {
0211 tower_ownership[original_tower] = std::pair<int, int>(0, -1);
0212 }
0213 export_clusters(original_towers, tower_ownership, 1, std::vector<float>(), std::vector<float>(), std::vector<float>());
0214
0215 return;
0216 }
0217
0218 void RawClusterBuilderTopo::export_clusters(const std::vector<int> &original_towers, std::map<int, std::pair<int, int> > tower_ownership, unsigned int n_clusters, const std::vector<float> &pseudocluster_sumE, const std::vector<float> &pseudocluster_eta, const std::vector<float> &pseudocluster_phi)
0219 {
0220 if (n_clusters != 1)
0221 {
0222 if (Verbosity() > 2)
0223 {
0224 std::cout << "RawClusterBuilderTopo::export_clusters called on an initial cluster with " << n_clusters << " final clusters " << std::endl;
0225 }
0226 }
0227
0228 std::vector<RawCluster *> clusters;
0229 std::vector<float> clusters_E;
0230 std::vector<float> clusters_absE;
0231 std::vector<float> clusters_x;
0232 std::vector<float> clusters_y;
0233 std::vector<float> clusters_z;
0234
0235 for (unsigned int pc = 0; pc < n_clusters; pc++)
0236 {
0237 clusters.push_back(new RawClusterv1());
0238 clusters_E.push_back(0);
0239 clusters_absE.push_back(0);
0240 clusters_x.push_back(0);
0241 clusters_y.push_back(0);
0242 clusters_z.push_back(0);
0243 }
0244
0245 for (int original_tower : original_towers)
0246 {
0247 int this_ID = original_tower;
0248 std::pair<int, int> the_pair = tower_ownership[this_ID];
0249
0250 if (Verbosity() > 5)
0251 {
0252 std::cout << "RawClusterBuilderTopo::export_clusters -> assigning tower " << original_tower << " with ownership ( " << the_pair.first << ", " << the_pair.second << " ) " << std::endl;
0253 }
0254 int this_ieta = get_ieta_from_ID(this_ID);
0255 int this_iphi = get_iphi_from_ID(this_ID);
0256 int this_layer = get_ilayer_from_ID(this_ID);
0257 float this_E = get_E_from_ID(this_ID);
0258
0259 int this_key = 0;
0260 if (this_layer == 2)
0261 {
0262 this_key = _EMTOWERMAP_KEY_ETA_PHI[this_ieta][this_iphi];
0263 }
0264 else
0265 {
0266 this_key = _TOWERMAP_KEY_LAYER_ETA_PHI[this_layer][this_ieta][this_iphi];
0267 }
0268
0269 RawTowerGeom *tower_geom = _geom_containers[this_layer]->get_tower_geometry(this_key);
0270
0271 if (the_pair.second == -1)
0272 {
0273
0274 clusters[the_pair.first]->addTower(this_key, this_E);
0275 clusters_E[the_pair.first] = clusters_E[the_pair.first] + this_E;
0276 clusters_absE[the_pair.first] = clusters_absE[the_pair.first] + std::fabs(this_E);
0277
0278 clusters_x[the_pair.first] = clusters_x[the_pair.first] + std::fabs(this_E) * tower_geom->get_center_x();
0279 clusters_y[the_pair.first] = clusters_y[the_pair.first] + std::fabs(this_E) * tower_geom->get_center_y();
0280 clusters_z[the_pair.first] = clusters_z[the_pair.first] + std::fabs(this_E) * tower_geom->get_center_z();
0281
0282 if (Verbosity() > 5)
0283 {
0284 std::cout << " -> tower ID " << this_ID << " fully assigned to pseudocluster " << the_pair.first << std::endl;
0285 }
0286 }
0287 else
0288 {
0289
0290 float dR1 = calculate_dR(tower_geom->get_eta(), pseudocluster_eta[the_pair.first], tower_geom->get_phi(), pseudocluster_phi[the_pair.first]) / _R_shower;
0291 float dR2 = calculate_dR(tower_geom->get_eta(), pseudocluster_eta[the_pair.second], tower_geom->get_phi(), pseudocluster_phi[the_pair.second]) / _R_shower;
0292 float r = std::exp(dR1 - dR2);
0293 float frac1 = fabs(pseudocluster_sumE[the_pair.first]) / (fabs(pseudocluster_sumE[the_pair.first]) + r * fabs(pseudocluster_sumE[the_pair.second]));
0294
0295 if (Verbosity() > 5)
0296 {
0297 std::cout << " tower ID " << this_ID << " has dR1 = " << dR1 << " to pseudocluster " << the_pair.first << " , and dR2 = " << dR2 << " to pseudocluster " << the_pair.second << ", so frac1 = " << frac1 << std::endl;
0298 }
0299 clusters[the_pair.first]->addTower(this_key, this_E * frac1);
0300 clusters_E[the_pair.first] = clusters_E[the_pair.first] + this_E * frac1;
0301 clusters_absE[the_pair.first] = clusters_absE[the_pair.first] + std::fabs(this_E) * frac1;
0302 clusters_x[the_pair.first] = clusters_x[the_pair.first] + std::fabs(this_E) * tower_geom->get_center_x() * frac1;
0303 clusters_y[the_pair.first] = clusters_y[the_pair.first] + std::fabs(this_E) * tower_geom->get_center_y() * frac1;
0304 clusters_z[the_pair.first] = clusters_z[the_pair.first] + std::fabs(this_E) * tower_geom->get_center_z() * frac1;
0305
0306 clusters[the_pair.second]->addTower(this_key, this_E * (1 - frac1));
0307 clusters_E[the_pair.second] = clusters_E[the_pair.second] + this_E * (1 - frac1);
0308 clusters_absE[the_pair.second] = clusters_absE[the_pair.second] + std::fabs(this_E) * (1 - frac1);
0309 clusters_x[the_pair.second] = clusters_x[the_pair.second] + std::fabs(this_E) * tower_geom->get_center_x() * (1 - frac1);
0310 clusters_y[the_pair.second] = clusters_y[the_pair.second] + std::fabs(this_E) * tower_geom->get_center_y() * (1 - frac1);
0311 clusters_z[the_pair.second] = clusters_z[the_pair.second] + std::fabs(this_E) * tower_geom->get_center_z() * (1 - frac1);
0312 }
0313 }
0314
0315
0316
0317 for (unsigned int cl = 0; cl < n_clusters; cl++)
0318 {
0319 if (clusters_absE[cl] < _min_cluster_E)
0320 {
0321 if (Verbosity() > 2)
0322 {
0323 std::cout << "RawClusterBuilderTopo::export_clusters: skipping cluster with E = " << clusters_E[cl] << " and absE = " << clusters_absE[cl] << " due to low energy " << std::endl;
0324 }
0325 continue;
0326 }
0327 clusters[cl]->set_energy(clusters_E[cl]);
0328
0329 float mean_x = clusters_x[cl] / clusters_absE[cl];
0330 float mean_y = clusters_y[cl] / clusters_absE[cl];
0331 float mean_z = clusters_z[cl] / clusters_absE[cl];
0332
0333 clusters[cl]->set_r(std::sqrt((mean_y * mean_y) + (mean_x * mean_x)));
0334 clusters[cl]->set_phi(std::atan2(mean_y, mean_x));
0335 clusters[cl]->set_z(mean_z);
0336
0337 _clusters->AddCluster(clusters[cl]);
0338
0339 if (Verbosity() > 1)
0340 {
0341 std::cout << "RawClusterBuilderTopo::export_clusters: added cluster with E = " << clusters_E[cl] << ", eta = " << -1 * log(tan(std::atan2(std::sqrt((mean_y * mean_y) + (mean_x * mean_x)), mean_z) / 2.0)) << ", phi = " << std::atan2(mean_y, mean_x) << std::endl;
0342 }
0343 }
0344
0345 return;
0346 }
0347
0348 RawClusterBuilderTopo::RawClusterBuilderTopo(const std::string &name)
0349 : SubsysReco(name)
0350 {
0351
0352
0353 std::fill(std::begin(_geom_containers), std::end(_geom_containers), nullptr);
0354 _noise_LAYER[0] = 0.0025;
0355 _noise_LAYER[1] = 0.006;
0356 _noise_LAYER[2] = 0.03;
0357
0358 _local_max_minE_LAYER[0] = 1;
0359 _local_max_minE_LAYER[1] = 1;
0360 _local_max_minE_LAYER[2] = 1;
0361 }
0362
0363 int RawClusterBuilderTopo::InitRun(PHCompositeNode *topNode)
0364 {
0365 try
0366 {
0367 CreateNodes(topNode);
0368 }
0369 catch (std::exception &e)
0370 {
0371 std::cout << PHWHERE << ": " << e.what() << std::endl;
0372 throw;
0373 }
0374
0375 if (Verbosity() > 0)
0376 {
0377 std::cout << "RawClusterBuilderTopo::InitRun: initialized with EMCal enable = " << _enable_EMCal << " and I+OHCal enable = " << _enable_HCal << std::endl;
0378 std::cout << "RawClusterBuilderTopo::InitRun: initialized with sigma_noise in EMCal / IHCal / OHCal = " << _noise_LAYER[2] << " / " << _noise_LAYER[0] << " / " << _noise_LAYER[1] << std::endl;
0379 std::cout << "RawClusterBuilderTopo::InitRun: initialized with noise multiples for seeding / growth / perimeter ( S / N / P ) = " << _sigma_seed << " / " << _sigma_grow << " / " << _sigma_peri << std::endl;
0380 std::cout << "RawClusterBuilderTopo::InitRun: initialized with allow_corner_neighbor = " << _allow_corner_neighbor << " (in HCal)" << std::endl;
0381 std::cout << "RawClusterBuilderTopo::InitRun: initialized with use_absE = " << _use_absE << std::endl;
0382 std::cout << "RawClusterBuilderTopo::InitRun: initialized with do_split = " << _do_split << " , R_shower = " << _R_shower << " (angular units) " << std::endl;
0383 std::cout << "RawClusterBuilderTopo::InitRun: initialized with minE for local max in EMCal / IHCal / OHCal = " << _local_max_minE_LAYER[2] << " / " << _local_max_minE_LAYER[0] << " / " << _local_max_minE_LAYER[1] << std::endl;
0384 }
0385
0386 return Fun4AllReturnCodes::EVENT_OK;
0387 }
0388
0389 int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode)
0390 {
0391 TowerInfoContainer *towerinfosEM = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_CEMC");
0392 TowerInfoContainer *towerinfosIH = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_HCALIN");
0393 TowerInfoContainer *towerinfosOH = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_HCALOUT");
0394
0395 if (!towerinfosEM)
0396 {
0397 std::cout << " RawClusterBuilderTopo::process_event : container TOWERINFO_CALIB_CEMC does not exist, aborting " << std::endl;
0398 return Fun4AllReturnCodes::ABORTEVENT;
0399 }
0400 if (!towerinfosIH)
0401 {
0402 std::cout << " RawClusterBuilderTopo::process_event : container TOWERINFO_CALIB_HCALIN does not exist, aborting " << std::endl;
0403 return Fun4AllReturnCodes::ABORTEVENT;
0404 }
0405 if (!towerinfosOH)
0406 {
0407 std::cout << " RawClusterBuilderTopo::process_event : container TOWERINFO_CALIB_HCALOUT does not exist, aborting " << std::endl;
0408 return Fun4AllReturnCodes::ABORTEVENT;
0409 }
0410
0411 _geom_containers[0] = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALIN");
0412 _geom_containers[1] = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_HCALOUT");
0413 _geom_containers[2] = findNode::getClass<RawTowerGeomContainer>(topNode, "TOWERGEOM_CEMC");
0414
0415 if (!_geom_containers[0])
0416 {
0417 std::cout << " RawClusterBuilderTopo::process_event : container TOWERGEOM_HCALIN does not exist, aborting " << std::endl;
0418 return Fun4AllReturnCodes::ABORTEVENT;
0419 }
0420 if (!_geom_containers[1])
0421 {
0422 std::cout << " RawClusterBuilderTopo::process_event : container TOWERGEOM_HCALOUT does not exist, aborting " << std::endl;
0423 return Fun4AllReturnCodes::ABORTEVENT;
0424 }
0425 if (!_geom_containers[2])
0426 {
0427 std::cout << " RawClusterBuilderTopo::process_event : container TOWERGEOM_CEMC does not exist, aborting " << std::endl;
0428 return Fun4AllReturnCodes::ABORTEVENT;
0429 }
0430
0431 if (Verbosity() > 10)
0432 {
0433 std::cout << "RawClusterBuilderTopo::process_event: " << towerinfosEM->size() << " TOWERINFO_CALIB_CEMC towers" << std::endl;
0434 std::cout << "RawClusterBuilderTopo::process_event: " << towerinfosIH->size() << " TOWERINFO_CALIB_HCALIN towers" << std::endl;
0435 std::cout << "RawClusterBuilderTopo::process_event: " << towerinfosOH->size() << " TOWERINFO_CALIB_HCALOUT towers" << std::endl;
0436
0437 std::cout << "RawClusterBuilderTopo::process_event: pointer to TOWERGEOM_CEMC: " << _geom_containers[2] << std::endl;
0438 std::cout << "RawClusterBuilderTopo::process_event: pointer to TOWERGEOM_HCALIN: " << _geom_containers[0] << std::endl;
0439 std::cout << "RawClusterBuilderTopo::process_event: pointer to TOWERGEOM_HCALOUT: " << _geom_containers[1] << std::endl;
0440 }
0441
0442 if (_EMCAL_NETA < 0)
0443 {
0444
0445 _EMCAL_NETA = _geom_containers[2]->get_etabins();
0446 _EMCAL_NPHI = _geom_containers[2]->get_phibins();
0447
0448 _EMTOWERMAP_STATUS_ETA_PHI.resize(_EMCAL_NETA, std::vector<int>(_EMCAL_NPHI, -2));
0449 _EMTOWERMAP_KEY_ETA_PHI.resize(_EMCAL_NETA, std::vector<int>(_EMCAL_NPHI, 0));
0450 _EMTOWERMAP_E_ETA_PHI.resize(_EMCAL_NETA, std::vector<float>(_EMCAL_NPHI, 0));
0451 }
0452
0453 if (_HCAL_NETA < 0)
0454 {
0455
0456 _HCAL_NETA = _geom_containers[1]->get_etabins();
0457 _HCAL_NPHI = _geom_containers[1]->get_phibins();
0458
0459 _TOWERMAP_STATUS_LAYER_ETA_PHI.resize(2, std::vector<std::vector<int> >(_HCAL_NETA, std::vector<int>(_HCAL_NPHI, -2)));
0460 _TOWERMAP_KEY_LAYER_ETA_PHI.resize(2, std::vector<std::vector<int> >(_HCAL_NETA, std::vector<int>(_HCAL_NPHI, 0)));
0461 _TOWERMAP_E_LAYER_ETA_PHI.resize(2, std::vector<std::vector<float> >(_HCAL_NETA, std::vector<float>(_HCAL_NPHI, 0)));
0462 }
0463
0464
0465
0466 for (int ieta = 0; ieta < _EMCAL_NETA; ieta++)
0467 {
0468 for (int iphi = 0; iphi < _EMCAL_NPHI; iphi++)
0469 {
0470 _EMTOWERMAP_STATUS_ETA_PHI[ieta][iphi] = -2;
0471 _EMTOWERMAP_E_ETA_PHI[ieta][iphi] = 0;
0472 }
0473 }
0474 for (int ilayer = 0; ilayer < 2; ilayer++)
0475 {
0476 for (int ieta = 0; ieta < _HCAL_NETA; ieta++)
0477 {
0478 for (int iphi = 0; iphi < _HCAL_NPHI; iphi++)
0479 {
0480 _TOWERMAP_STATUS_LAYER_ETA_PHI[ilayer][ieta][iphi] = -2;
0481 _TOWERMAP_E_LAYER_ETA_PHI[ilayer][ieta][iphi] = 0;
0482 }
0483 }
0484 }
0485
0486
0487 std::vector<std::pair<int, float> > list_of_seeds;
0488
0489
0490 if (_enable_EMCal)
0491 {
0492 TowerInfo *towerInfo = nullptr;
0493 unsigned int n_EM_towers = towerinfosEM->size();
0494 for (unsigned int iEM = 0; iEM < n_EM_towers; iEM++)
0495 {
0496 towerInfo = towerinfosEM->get_tower_at_channel(iEM);
0497 if (_only_good_towers && (!towerInfo->get_isGood()))
0498 {
0499 continue;
0500 }
0501 unsigned int towerinfo_key = towerinfosEM->encode_key(iEM);
0502 int ti_ieta = towerinfosEM->getTowerEtaBin(towerinfo_key);
0503 int ti_iphi = towerinfosEM->getTowerPhiBin(towerinfo_key);
0504 const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::CEMC, ti_ieta, ti_iphi);
0505
0506
0507
0508
0509
0510
0511 int ieta = ti_ieta;
0512 int iphi = ti_iphi;
0513
0514 float this_E = towerInfo->get_energy();
0515
0516
0517 if (!_use_absE && this_E < 1.E-10)
0518 {
0519 continue;
0520 }
0521
0522 _EMTOWERMAP_STATUS_ETA_PHI[ieta][iphi] = -1;
0523 _EMTOWERMAP_E_ETA_PHI[ieta][iphi] = this_E;
0524 _EMTOWERMAP_KEY_ETA_PHI[ieta][iphi] = key;
0525
0526
0527 if (std::fabs(this_E) >= _sigma_seed * _noise_LAYER[2])
0528 {
0529 int ID = get_ID(2, ieta, iphi);
0530 list_of_seeds.emplace_back(ID, this_E);
0531 if (Verbosity() > 10)
0532 {
0533 std::cout << "RawClusterBuilderTopo::process_event: adding EMCal tower at ieta / iphi = " << ieta << " / " << iphi << " with E = " << this_E << std::endl;
0534 std::cout << " --> ID = " << ID << " , check ilayer / ieta / iphi = " << get_ilayer_from_ID(ID) << " / " << get_ieta_from_ID(ID) << " / " << get_iphi_from_ID(ID) << std::endl;
0535 };
0536 }
0537 }
0538 }
0539
0540
0541 if (_enable_HCal)
0542 {
0543 TowerInfo *towerInfo = nullptr;
0544 unsigned int n_IH_towers = towerinfosIH->size();
0545 for (unsigned int iIH = 0; iIH < n_IH_towers; iIH++)
0546 {
0547 towerInfo = towerinfosIH->get_tower_at_channel(iIH);
0548 if (_only_good_towers && (!towerInfo->get_isGood()))
0549 {
0550 continue;
0551 }
0552 unsigned int towerinfo_key = towerinfosIH->encode_key(iIH);
0553 int ti_ieta = towerinfosIH->getTowerEtaBin(towerinfo_key);
0554 int ti_iphi = towerinfosIH->getTowerPhiBin(towerinfo_key);
0555 const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALIN, ti_ieta, ti_iphi);
0556
0557 RawTowerGeom *tower_geom = _geom_containers[0]->get_tower_geometry(key);
0558
0559 int ieta = _geom_containers[0]->get_etabin(tower_geom->get_eta());
0560 int iphi = _geom_containers[0]->get_phibin(tower_geom->get_phi());
0561 float this_E = towerInfo->get_energy();
0562
0563 if (!_use_absE && this_E < 1.E-10)
0564 {
0565 continue;
0566 }
0567
0568 _TOWERMAP_STATUS_LAYER_ETA_PHI[0][ieta][iphi] = -1;
0569 _TOWERMAP_E_LAYER_ETA_PHI[0][ieta][iphi] = this_E;
0570 _TOWERMAP_KEY_LAYER_ETA_PHI[0][ieta][iphi] = key;
0571
0572 if (std::fabs(this_E) >= _sigma_seed * _noise_LAYER[0])
0573 {
0574 int ID = get_ID(0, ieta, iphi);
0575 list_of_seeds.emplace_back(ID, this_E);
0576 if (Verbosity() > 10)
0577 {
0578 std::cout << "RawClusterBuilderTopo::process_event: adding IHCal tower at ieta / iphi = " << ieta << " / " << iphi << " with E = " << this_E << std::endl;
0579 std::cout << " --> ID = " << ID << " , check ilayer / ieta / iphi = " << get_ilayer_from_ID(ID) << " / " << get_ieta_from_ID(ID) << " / " << get_iphi_from_ID(ID) << std::endl;
0580 };
0581 }
0582 }
0583 unsigned int n_OH_towers = towerinfosOH->size();
0584 for (unsigned int iOH = 0; iOH < n_OH_towers; iOH++)
0585 {
0586 towerInfo = towerinfosOH->get_tower_at_channel(iOH);
0587 if (_only_good_towers && (!towerInfo->get_isGood()))
0588 {
0589 continue;
0590 }
0591 unsigned int towerinfo_key = towerinfosOH->encode_key(iOH);
0592 int ti_ieta = towerinfosOH->getTowerEtaBin(towerinfo_key);
0593 int ti_iphi = towerinfosOH->getTowerPhiBin(towerinfo_key);
0594 const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALOUT, ti_ieta, ti_iphi);
0595
0596 RawTowerGeom *tower_geom = _geom_containers[1]->get_tower_geometry(key);
0597
0598 int ieta = _geom_containers[1]->get_etabin(tower_geom->get_eta());
0599 int iphi = _geom_containers[1]->get_phibin(tower_geom->get_phi());
0600 float this_E = towerInfo->get_energy();
0601
0602 if (!_use_absE && this_E < 1.E-10)
0603 {
0604 continue;
0605 }
0606
0607 _TOWERMAP_STATUS_LAYER_ETA_PHI[1][ieta][iphi] = -1;
0608 _TOWERMAP_E_LAYER_ETA_PHI[1][ieta][iphi] = this_E;
0609 _TOWERMAP_KEY_LAYER_ETA_PHI[1][ieta][iphi] = key;
0610
0611 if (std::fabs(this_E) >= _sigma_seed * _noise_LAYER[1])
0612 {
0613 int ID = get_ID(1, ieta, iphi);
0614 list_of_seeds.emplace_back(ID, this_E);
0615 if (Verbosity() > 10)
0616 {
0617 std::cout << "RawClusterBuilderTopo::process_event: adding OHCal tower at ieta / iphi = " << ieta << " / " << iphi << " with E = " << this_E << std::endl;
0618 std::cout << " --> ID = " << ID << " , check ilayer / ieta / iphi = " << get_ilayer_from_ID(ID) << " / " << get_ieta_from_ID(ID) << " / " << get_iphi_from_ID(ID) << std::endl;
0619 };
0620 }
0621 }
0622 }
0623
0624 if (Verbosity() > 10)
0625 {
0626 for (unsigned int n = 0; n < list_of_seeds.size(); n++)
0627 {
0628 std::cout << "RawClusterBuilderTopo::process_event: unsorted seed element n = " << n << " , ID / E = " << list_of_seeds.at(n).first << " / " << list_of_seeds.at(n).second << std::endl;
0629 }
0630 }
0631
0632 std::sort(list_of_seeds.begin(), list_of_seeds.end(), sort_by_pair_second);
0633
0634 if (Verbosity() > 10)
0635 {
0636 for (unsigned int n = 0; n < list_of_seeds.size(); n++)
0637 {
0638 std::cout << "RawClusterBuilderTopo::process_event: sorted seed element n = " << n << " , ID / E = " << list_of_seeds.at(n).first << " / " << list_of_seeds.at(n).second << std::endl;
0639 }
0640 }
0641
0642 if (Verbosity() > 0)
0643 {
0644 std::cout << "RawClusterBuilderTopo::process_event: initialized with " << list_of_seeds.size() << " seeds with E > 4*sigma " << std::endl;
0645 }
0646
0647 int cluster_index = 0;
0648
0649 std::vector<std::vector<int> > all_cluster_towers;
0650
0651 while (!list_of_seeds.empty())
0652 {
0653 int seed_ID = list_of_seeds.at(0).first;
0654 list_of_seeds.erase(list_of_seeds.begin());
0655
0656 if (Verbosity() > 5)
0657 {
0658 std::cout << " RawClusterBuilderTopo::process_event: in seeded loop, current seed has ID = " << seed_ID << " , length of remaining seed vector = " << list_of_seeds.size() << std::endl;
0659 }
0660
0661
0662 int seed_status = get_status_from_ID(seed_ID);
0663 if (seed_status > -1)
0664 {
0665 if (Verbosity() > 10)
0666 {
0667 std::cout << " --> already owned by cluster # " << seed_status << std::endl;
0668 }
0669 continue;
0670 }
0671
0672
0673 set_status_by_ID(seed_ID, cluster_index);
0674
0675 std::vector<int> cluster_tower_ID;
0676 cluster_tower_ID.push_back(seed_ID);
0677
0678 std::vector<int> grow_tower_ID;
0679 grow_tower_ID.push_back(seed_ID);
0680
0681
0682
0683 if (Verbosity() > 5)
0684 {
0685 std::cout << " RawClusterBuilderTopo::process_event: Entering Growth stage for cluster " << cluster_index << std::endl;
0686 }
0687
0688 while (!grow_tower_ID.empty())
0689 {
0690 int grow_ID = grow_tower_ID.at(0);
0691 grow_tower_ID.erase(grow_tower_ID.begin());
0692
0693 if (Verbosity() > 5)
0694 {
0695 std::cout << " --> cluster " << cluster_index << ", growth stage, examining neighbors of ID " << grow_ID << ", " << grow_tower_ID.size() << " grow towers left" << std::endl;
0696 }
0697
0698 std::vector<int> adjacent_tower_IDs = get_adjacent_towers_by_ID(grow_ID);
0699
0700 for (int this_adjacent_tower_ID : adjacent_tower_IDs)
0701 {
0702 if (Verbosity() > 10)
0703 {
0704 std::cout << " --> --> --> checking possible adjacent tower with ID " << this_adjacent_tower_ID << " : ";
0705 }
0706 int test_layer = get_ilayer_from_ID(this_adjacent_tower_ID);
0707
0708
0709 if (get_status_from_ID(this_adjacent_tower_ID) == -2)
0710 {
0711 if (Verbosity() > 10)
0712 {
0713 std::cout << "does not exist " << std::endl;
0714 }
0715 continue;
0716 }
0717
0718
0719 if (get_status_from_ID(this_adjacent_tower_ID) == cluster_index)
0720 {
0721 if (Verbosity() > 10)
0722 {
0723 std::cout << "already owned by this cluster index " << cluster_index << std::endl;
0724 }
0725 continue;
0726 }
0727
0728
0729 if (std::fabs(get_E_from_ID(this_adjacent_tower_ID)) < _sigma_grow * _noise_LAYER[test_layer])
0730 {
0731 if (Verbosity() > 10)
0732 {
0733 std::cout << "E = " << get_E_from_ID(this_adjacent_tower_ID) << " under 2*sigma threshold " << std::endl;
0734 }
0735 continue;
0736 }
0737
0738
0739 if (get_status_from_ID(this_adjacent_tower_ID) > -1)
0740 {
0741 if (Verbosity() > 10)
0742 {
0743 std::cout << "ERROR! in growth stage, encountered >2sigma tower which is already owned?!" << std::endl;
0744 }
0745 continue;
0746 }
0747
0748
0749 grow_tower_ID.push_back(this_adjacent_tower_ID);
0750 cluster_tower_ID.push_back(this_adjacent_tower_ID);
0751 set_status_by_ID(this_adjacent_tower_ID, cluster_index);
0752 if (Verbosity() > 10)
0753 {
0754 std::cout << "add this tower ( ID " << this_adjacent_tower_ID << " ) to grow list " << std::endl;
0755 }
0756 }
0757
0758 if (Verbosity() > 5)
0759 {
0760 std::cout << " --> after examining neighbors, grow list is now " << grow_tower_ID.size() << ", # of towers in cluster = " << cluster_tower_ID.size() << std::endl;
0761 }
0762 }
0763
0764
0765 if (Verbosity() > 5)
0766 {
0767 std::cout << " RawClusterBuilderTopo::process_event: Entering Perimeter stage for cluster " << cluster_index << std::endl;
0768 }
0769
0770 int n_core_towers = cluster_tower_ID.size();
0771
0772 for (int ic = 0; ic < n_core_towers; ic++)
0773 {
0774 int core_ID = cluster_tower_ID.at(ic);
0775
0776 if (Verbosity() > 5)
0777 {
0778 std::cout << " --> cluster " << cluster_index << ", perimeter stage, examining neighbors of ID " << core_ID << ", core cluster # " << ic << " of " << n_core_towers << " total " << std::endl;
0779 }
0780 std::vector<int> adjacent_tower_IDs = get_adjacent_towers_by_ID(core_ID);
0781
0782 for (int this_adjacent_tower_ID : adjacent_tower_IDs)
0783 {
0784 if (Verbosity() > 10)
0785 {
0786 std::cout << " --> --> --> checking possible adjacent tower with ID " << this_adjacent_tower_ID << " : ";
0787 }
0788
0789 int test_layer = get_ilayer_from_ID(this_adjacent_tower_ID);
0790
0791
0792 if (get_status_from_ID(this_adjacent_tower_ID) == -2)
0793 {
0794 if (Verbosity() > 10)
0795 {
0796 std::cout << "does not exist " << std::endl;
0797 }
0798 continue;
0799 }
0800
0801
0802 if (get_status_from_ID(this_adjacent_tower_ID) > -1)
0803 {
0804 if (Verbosity() > 10)
0805 {
0806 std::cout << "already owned by other cluster index " << get_status_from_ID(this_adjacent_tower_ID) << std::endl;
0807 }
0808 continue;
0809 }
0810
0811
0812 if (std::fabs(get_E_from_ID(this_adjacent_tower_ID)) < _sigma_peri * _noise_LAYER[test_layer])
0813 {
0814 if (Verbosity() > 10)
0815 {
0816 std::cout << "E = " << get_E_from_ID(this_adjacent_tower_ID) << " under 0*sigma threshold " << std::endl;
0817 }
0818 continue;
0819 }
0820
0821
0822 cluster_tower_ID.push_back(this_adjacent_tower_ID);
0823 set_status_by_ID(this_adjacent_tower_ID, cluster_index);
0824 if (Verbosity() > 10)
0825 {
0826 std::cout << "add this tower ( ID " << this_adjacent_tower_ID << " ) to cluster " << std::endl;
0827 }
0828 }
0829
0830 if (Verbosity() > 5)
0831 {
0832 std::cout << " --> after examining perimeter neighbors, # of towers in cluster is now = " << cluster_tower_ID.size() << std::endl;
0833 }
0834 }
0835
0836
0837 all_cluster_towers.push_back(cluster_tower_ID);
0838
0839
0840 cluster_index++;
0841 }
0842
0843 if (Verbosity() > 0)
0844 {
0845 std::cout << "RawClusterBuilderTopo::process_event: " << cluster_index << " topo-clusters initially reconstructed, entering splitting step" << std::endl;
0846 }
0847
0848 int original_cluster_index = cluster_index;
0849
0850
0851
0852 for (int cl = 0; cl < original_cluster_index; cl++)
0853 {
0854 std::vector<int> original_towers = all_cluster_towers.at(cl);
0855
0856 if (!_do_split)
0857 {
0858
0859 if (Verbosity() > 2)
0860 {
0861 std::cout << "RawClusterBuilderTopo::process_event: splitting step disabled, cluster " << cluster_index << " is final" << std::endl;
0862 }
0863 export_single_cluster(original_towers);
0864 continue;
0865 }
0866
0867 std::vector<std::pair<int, float> > local_maxima_ID;
0868
0869
0870 for (int tower_ID : original_towers)
0871 {
0872 if (Verbosity() > 10)
0873 {
0874 std::cout << " -> examining tower ID " << tower_ID << " for possible local maximum " << std::endl;
0875 }
0876
0877
0878 if (get_E_from_ID(tower_ID) < _local_max_minE_LAYER[get_ilayer_from_ID(tower_ID)])
0879 {
0880 if (Verbosity() > 10)
0881 {
0882 std::cout << " -> -> energy E = " << get_E_from_ID(tower_ID) << " < " << _local_max_minE_LAYER[get_ilayer_from_ID(tower_ID)] << " too low" << std::endl;
0883 }
0884 continue;
0885 }
0886
0887
0888 std::vector<int> adjacent_tower_IDs = get_adjacent_towers_by_ID(tower_ID);
0889 int neighbors_in_cluster = 0;
0890
0891
0892 bool has_higher_neighbor = false;
0893 for (int this_adjacent_tower_ID : adjacent_tower_IDs)
0894 {
0895 if (get_status_from_ID(this_adjacent_tower_ID) != cl)
0896 {
0897 continue;
0898 }
0899
0900 neighbors_in_cluster++;
0901
0902 if (get_E_from_ID(this_adjacent_tower_ID) > get_E_from_ID(tower_ID))
0903 {
0904 if (Verbosity() > 10)
0905 {
0906 std::cout << " -> -> has higher-energy neighbor ID / E = " << this_adjacent_tower_ID << " / " << get_E_from_ID(this_adjacent_tower_ID) << std::endl;
0907 }
0908 has_higher_neighbor = true;
0909 break;
0910 }
0911 }
0912
0913 if (has_higher_neighbor)
0914 {
0915 continue;
0916 }
0917
0918
0919 if (neighbors_in_cluster < 4)
0920 {
0921 if (Verbosity() > 10)
0922 {
0923 std::cout << " -> -> too few neighbors N = " << neighbors_in_cluster << std::endl;
0924 }
0925 continue;
0926 }
0927
0928 local_maxima_ID.emplace_back(tower_ID, get_E_from_ID(tower_ID));
0929 }
0930
0931
0932 for (unsigned int n = 0; n < local_maxima_ID.size(); n++)
0933 {
0934
0935 std::pair<int, float> this_LM = local_maxima_ID.at(n);
0936 if (get_ilayer_from_ID(this_LM.first) == 2)
0937 {
0938 continue;
0939 }
0940
0941 float this_phi = _geom_containers[get_ilayer_from_ID(this_LM.first)]->get_phicenter(get_iphi_from_ID(this_LM.first));
0942 if (this_phi > M_PI)
0943 {
0944 this_phi -= 2 * M_PI;
0945 }
0946 float this_eta = _geom_containers[get_ilayer_from_ID(this_LM.first)]->get_etacenter(get_ieta_from_ID(this_LM.first));
0947
0948 bool has_EM_overlap = false;
0949
0950
0951 for (unsigned int n2 = 0; n2 < local_maxima_ID.size(); n2++)
0952 {
0953 if (n == n2)
0954 {
0955 continue;
0956 }
0957
0958
0959 std::pair<int, float> this_LM2 = local_maxima_ID.at(n2);
0960 if (get_ilayer_from_ID(this_LM2.first) != 2)
0961 {
0962 continue;
0963 }
0964
0965 float this_phi2 = _geom_containers[get_ilayer_from_ID(this_LM2.first)]->get_phicenter(get_iphi_from_ID(this_LM2.first));
0966 if (this_phi2 > M_PI)
0967 {
0968 this_phi -= 2 * M_PI;
0969 }
0970 float this_eta2 = _geom_containers[get_ilayer_from_ID(this_LM2.first)]->get_etacenter(get_ieta_from_ID(this_LM2.first));
0971
0972
0973 float dR = calculate_dR(this_eta, this_eta2, this_phi, this_phi2);
0974
0975
0976 if (dR < 0.15)
0977 {
0978 has_EM_overlap = true;
0979 if (Verbosity() > 2)
0980 {
0981 std::cout << "RawClusterBuilderTopo::process_event : removing I/OHal local maximum (ID,E,phi,eta = " << this_LM.first << ", " << this_LM.second << ", " << this_phi << ", " << this_eta << "), ";
0982 std::cout << "due to EM overlap (ID,E,phi,eta = " << this_LM2.first << ", " << this_LM2.second << ", " << this_phi2 << ", " << this_eta2 << "), dR = " << dR << std::endl;
0983 }
0984 break;
0985 }
0986 }
0987
0988 if (has_EM_overlap)
0989 {
0990
0991 local_maxima_ID.erase(local_maxima_ID.begin() + n);
0992
0993 n = n - 1;
0994 }
0995 }
0996
0997
0998 if (Verbosity() > 2)
0999 {
1000 for (auto this_LM : local_maxima_ID)
1001 {
1002 int tower_ID = this_LM.first;
1003 std::cout << "RawClusterBuilderTopo::process_event in cluster " << cl << ", tower ID " << tower_ID << " is LOCAL MAXIMUM with layer / E = " << get_ilayer_from_ID(tower_ID) << " / " << get_E_from_ID(tower_ID) << ", ";
1004 float this_phi = _geom_containers[get_ilayer_from_ID(tower_ID)]->get_phicenter(get_iphi_from_ID(tower_ID));
1005 if (this_phi > M_PI)
1006 {
1007 this_phi -= 2 * M_PI;
1008 }
1009 std::cout << " eta / phi = " << _geom_containers[get_ilayer_from_ID(tower_ID)]->get_etacenter(get_ieta_from_ID(tower_ID)) << " / " << this_phi << std::endl;
1010 }
1011 }
1012
1013
1014 if (local_maxima_ID.size() <= 1)
1015 {
1016 if (Verbosity() > 2)
1017 {
1018 std::cout << "RawClusterBuilderTopo::process_event cluster " << cl << " has only " << local_maxima_ID.size() << " local maxima, not splitting " << std::endl;
1019 }
1020 export_single_cluster(original_towers);
1021
1022 continue;
1023 }
1024
1025
1026
1027 if (Verbosity() > 2)
1028 {
1029 std::cout << "RawClusterBuilderTopo::process_event splitting cluster " << cl << " into " << local_maxima_ID.size() << " according to local maxima!" << std::endl;
1030 }
1031
1032
1033
1034
1035 std::map<int, std::pair<int, int> > tower_ownership;
1036 for (int &original_tower : original_towers)
1037 {
1038 tower_ownership[original_tower] = std::pair<int, int>(-1, -1);
1039 }
1040 std::vector<int> seed_list;
1041 std::vector<int> neighbor_list;
1042 std::vector<int> shared_list;
1043
1044
1045 std::sort(local_maxima_ID.begin(), local_maxima_ID.end(), sort_by_pair_second);
1046
1047
1048 for (unsigned int s = 0; s < local_maxima_ID.size(); s++)
1049 {
1050 tower_ownership[local_maxima_ID.at(s).first] = std::pair<int, int>(s, -1);
1051 neighbor_list.push_back(local_maxima_ID.at(s).first);
1052 }
1053
1054 if (Verbosity() > 100)
1055 {
1056 for (int &original_tower : original_towers)
1057 {
1058 std::pair<int, int> the_pair = tower_ownership[original_tower];
1059 std::cout << " Debug Pre-Split: tower_ownership[ " << original_tower << " ] = ( " << the_pair.first << ", " << the_pair.second << " ) ";
1060 std::cout << " , layer / ieta / iphi = " << get_ilayer_from_ID(original_tower) << " / " << get_ieta_from_ID(original_tower) << " / " << get_iphi_from_ID(original_tower);
1061 std::cout << std::endl;
1062 }
1063 }
1064
1065 bool first_pass = true;
1066
1067 do
1068 {
1069 if (Verbosity() > 5)
1070 {
1071 std::cout << " -> starting split loop with " << seed_list.size() << " seed, " << neighbor_list.size() << " neighbor, and " << shared_list.size() << " shared towers " << std::endl;
1072 }
1073
1074 std::vector<int> new_ownerships;
1075
1076 for (unsigned int n = 0; n < neighbor_list.size(); n++)
1077 {
1078 int neighbor_ID = neighbor_list.at(n);
1079
1080 if (Verbosity() > 10)
1081 {
1082 std::cout << " -> -> looking at neighbor " << n << " (tower ID " << neighbor_ID << " ) of " << neighbor_list.size() << " total" << std::endl;
1083 }
1084 if (first_pass)
1085 {
1086 if (Verbosity() > 10)
1087 {
1088 std::cout << " -> -> -> special first pass rules, this tower already owned by pseudocluster " << tower_ownership[neighbor_ID].first << std::endl;
1089 }
1090 new_ownerships.push_back(tower_ownership[neighbor_ID].first);
1091 }
1092 else
1093 {
1094 std::map<int, bool> pseudocluster_adjacency;
1095 for (unsigned int s = 0; s < local_maxima_ID.size(); s++)
1096 {
1097 pseudocluster_adjacency[s] = false;
1098 }
1099
1100 std::vector<int> adjacent_tower_IDs = get_adjacent_towers_by_ID(neighbor_ID);
1101
1102 for (int this_adjacent_tower_ID : adjacent_tower_IDs)
1103 {
1104 if (get_status_from_ID(this_adjacent_tower_ID) != cl)
1105 {
1106 continue;
1107 }
1108
1109 if (tower_ownership[this_adjacent_tower_ID].first > -1)
1110 {
1111 if (Verbosity() > 20)
1112 {
1113 std::cout << " -> -> -> adjacent tower to this one, with ID " << this_adjacent_tower_ID << " , is owned by pseudocluster " << tower_ownership[this_adjacent_tower_ID].first << std::endl;
1114 }
1115 pseudocluster_adjacency[tower_ownership[this_adjacent_tower_ID].first] = true;
1116 }
1117 }
1118 int n_pseudocluster_adjacent = 0;
1119 int last_adjacent_pseudocluster = -1;
1120 for (unsigned int s = 0; s < local_maxima_ID.size(); s++)
1121 {
1122 if (pseudocluster_adjacency[s])
1123 {
1124 last_adjacent_pseudocluster = s;
1125 n_pseudocluster_adjacent++;
1126 if (Verbosity() > 20)
1127 {
1128 std::cout << " -> -> adjacent to pseudocluster " << s << std::endl;
1129 }
1130 }
1131 }
1132
1133 if (n_pseudocluster_adjacent == 0)
1134 {
1135 std::cout << " -> -> ERROR! How can a neighbor tower at this stage be adjacent to no pseudoclusters?? " << std::endl;
1136 new_ownerships.push_back(9999);
1137 }
1138 else if (n_pseudocluster_adjacent == 1)
1139 {
1140 if (Verbosity() > 10)
1141 {
1142 std::cout << " -> -> neighbor tower " << neighbor_ID << " is ONLY adjacent to one pseudocluster # " << last_adjacent_pseudocluster << std::endl;
1143 }
1144 new_ownerships.push_back(last_adjacent_pseudocluster);
1145 }
1146 else
1147 {
1148 if (Verbosity() > 10)
1149 {
1150 std::cout << " -> -> neighbor tower " << neighbor_ID << " is adjacent to " << n_pseudocluster_adjacent << " pseudoclusters, move to shared list " << std::endl;
1151 }
1152 new_ownerships.push_back(-3);
1153 }
1154 }
1155 }
1156
1157 if (Verbosity() > 5)
1158 {
1159 std::cout << " -> now updating status of all " << neighbor_list.size() << " original neighbors " << std::endl;
1160 }
1161
1162 for (unsigned int n = 0; n < neighbor_list.size(); n++)
1163 {
1164 int neighbor_ID = neighbor_list.at(n);
1165 if (new_ownerships.at(n) > -1)
1166 {
1167 tower_ownership[neighbor_ID] = std::pair<int, int>(new_ownerships.at(n), -1);
1168 seed_list.push_back(neighbor_ID);
1169 if (Verbosity() > 20)
1170 {
1171 std::cout << " -> -> neighbor ID " << neighbor_ID << " has new status " << new_ownerships.at(n) << std::endl;
1172 }
1173 }
1174 if (new_ownerships.at(n) == -3)
1175 {
1176 tower_ownership[neighbor_ID] = std::pair<int, int>(-3, -1);
1177 shared_list.push_back(neighbor_ID);
1178 if (Verbosity() > 20)
1179 {
1180 std::cout << " -> -> neighbor ID " << neighbor_ID << " has new status " << -3 << std::endl;
1181 }
1182 }
1183 }
1184
1185 if (Verbosity() > 5)
1186 {
1187 std::cout << " producing a new neighbor list ... " << std::endl;
1188 }
1189
1190 std::list<int> new_neighbor_list;
1191 for (unsigned int n = 0; n < neighbor_list.size(); n++)
1192 {
1193 int neighbor_ID = neighbor_list.at(n);
1194 if (new_ownerships.at(n) > -1)
1195 {
1196 std::vector<int> adjacent_tower_IDs = get_adjacent_towers_by_ID(neighbor_ID);
1197
1198 for (int this_adjacent_tower_ID : adjacent_tower_IDs)
1199 {
1200 if (get_status_from_ID(this_adjacent_tower_ID) != cl)
1201 {
1202 continue;
1203 }
1204 if (tower_ownership[this_adjacent_tower_ID].first == -1)
1205 {
1206 new_neighbor_list.push_back(this_adjacent_tower_ID);
1207 if (Verbosity() > 5)
1208 {
1209 std::cout << " -> queueing up to add tower " << this_adjacent_tower_ID << " , neighbor of tower " << neighbor_ID << " to new neighbor list" << std::endl;
1210 }
1211 }
1212 }
1213 }
1214 }
1215
1216 if (Verbosity() > 5)
1217 {
1218 std::cout << " new neighbor list has size " << new_neighbor_list.size() << ", but after removing duplicate elements: ";
1219 }
1220
1221 new_neighbor_list.sort();
1222 new_neighbor_list.unique();
1223
1224 if (Verbosity() > 5)
1225 {
1226 std::cout << new_neighbor_list.size() << std::endl;
1227 }
1228
1229
1230 neighbor_list.clear();
1231
1232
1233 for (; !new_neighbor_list.empty();)
1234 {
1235 neighbor_list.push_back(new_neighbor_list.front());
1236 new_neighbor_list.pop_front();
1237 }
1238
1239 first_pass = false;
1240
1241 } while (!neighbor_list.empty());
1242
1243 if (Verbosity() > 100)
1244 {
1245 for (int &original_tower : original_towers)
1246 {
1247 std::pair<int, int> the_pair = tower_ownership[original_tower];
1248 std::cout << " Debug Mid-Split: tower_ownership[ " << original_tower << " ] = ( " << the_pair.first << ", " << the_pair.second << " ) ";
1249 std::cout << " , layer / ieta / iphi = " << get_ilayer_from_ID(original_tower) << " / " << get_ieta_from_ID(original_tower) << " / " << get_iphi_from_ID(original_tower);
1250 std::cout << std::endl;
1251 if (the_pair.first == -1)
1252 {
1253 std::vector<int> adjacent_tower_IDs = get_adjacent_towers_by_ID(original_tower);
1254
1255 for (int this_adjacent_tower_ID : adjacent_tower_IDs)
1256 {
1257 if (get_status_from_ID(this_adjacent_tower_ID) != cl)
1258 {
1259 continue;
1260 }
1261 std::cout << " -> adjacent to add tower " << this_adjacent_tower_ID << " , which has status " << tower_ownership[this_adjacent_tower_ID].first << std::endl;
1262 }
1263 }
1264 }
1265 }
1266
1267
1268 std::vector<float> pseudocluster_sumeta;
1269 std::vector<float> pseudocluster_sumphi;
1270 std::vector<float> pseudocluster_sumE;
1271 std::vector<int> pseudocluster_ntower;
1272 std::vector<float> pseudocluster_eta;
1273 std::vector<float> pseudocluster_phi;
1274
1275 pseudocluster_sumeta.resize(local_maxima_ID.size(), 0);
1276 pseudocluster_sumphi.resize(local_maxima_ID.size(), 0);
1277 pseudocluster_sumE.resize(local_maxima_ID.size(), 0);
1278 pseudocluster_ntower.resize(local_maxima_ID.size(), 0);
1279
1280 for (int &original_tower : original_towers)
1281 {
1282 std::pair<int, int> the_pair = tower_ownership[original_tower];
1283 if (the_pair.first > -1)
1284 {
1285 float this_ID = original_tower;
1286 pseudocluster_sumE[the_pair.first] += get_E_from_ID(this_ID);
1287 float this_eta = _geom_containers[get_ilayer_from_ID(this_ID)]->get_etacenter(get_ieta_from_ID(this_ID));
1288 float this_phi = _geom_containers[get_ilayer_from_ID(this_ID)]->get_phicenter(get_iphi_from_ID(this_ID));
1289
1290 pseudocluster_sumeta[the_pair.first] += this_eta;
1291 pseudocluster_sumphi[the_pair.first] += this_phi;
1292 pseudocluster_ntower[the_pair.first] += 1;
1293 }
1294 }
1295
1296 for (unsigned int pc = 0; pc < local_maxima_ID.size(); pc++)
1297 {
1298 pseudocluster_eta.push_back(pseudocluster_sumeta.at(pc) / pseudocluster_ntower.at(pc));
1299 pseudocluster_phi.push_back(pseudocluster_sumphi.at(pc) / pseudocluster_ntower.at(pc));
1300
1301 if (Verbosity() > 2)
1302 {
1303 std::cout << "RawClusterBuilderTopo::process_event pseudocluster #" << pc << ", E / eta / phi / Ntower = " << pseudocluster_sumE.at(pc) << " / " << pseudocluster_eta.at(pc) << " / " << pseudocluster_phi.at(pc) << " / " << pseudocluster_ntower.at(pc) << std::endl;
1304 }
1305 }
1306
1307 if (Verbosity() > 2)
1308 {
1309 std::cout << "RawClusterBuilderTopo::process_event now splitting up shared clusters (including unassigned clusters), initial shared list has size " << shared_list.size() << std::endl;
1310 }
1311
1312 while (!shared_list.empty())
1313 {
1314
1315 int shared_ID = shared_list.at(0);
1316 shared_list.erase(shared_list.begin());
1317
1318 if (Verbosity() > 5)
1319 {
1320 std::cout << " -> looking at shared tower " << shared_ID << ", after this one there are " << shared_list.size() << " shared towers left " << std::endl;
1321 }
1322
1323 std::vector<bool> pseudocluster_adjacency;
1324 pseudocluster_adjacency.resize(local_maxima_ID.size(), false);
1325
1326 std::vector<int> adjacent_tower_IDs = get_adjacent_towers_by_ID(shared_ID);
1327
1328 for (int this_adjacent_tower_ID : adjacent_tower_IDs)
1329 {
1330 if (get_status_from_ID(this_adjacent_tower_ID) != cl)
1331 {
1332 continue;
1333 }
1334 if (tower_ownership[this_adjacent_tower_ID].first > -1)
1335 {
1336 pseudocluster_adjacency[tower_ownership[this_adjacent_tower_ID].first] = true;
1337 }
1338 if (tower_ownership[this_adjacent_tower_ID].second > -1)
1339 {
1340 pseudocluster_adjacency[tower_ownership[this_adjacent_tower_ID].second] = true;
1341 }
1342
1343 if (tower_ownership[this_adjacent_tower_ID].first == -1)
1344 {
1345 shared_list.push_back(this_adjacent_tower_ID);
1346 tower_ownership[this_adjacent_tower_ID] = std::pair<int, int>(-3, -1);
1347 if (Verbosity() > 10)
1348 {
1349 std::cout << " -> while looking at neighbors, have added un-examined tower " << this_adjacent_tower_ID << " to shared list " << std::endl;
1350 }
1351 }
1352 }
1353
1354
1355 int highest_pseudocluster_index = -1;
1356 int second_highest_pseudocluster_index = -1;
1357
1358 float highest_pseudocluster_E = -999;
1359 float second_highest_pseudocluster_E = -999;
1360
1361 for (unsigned int n = 0; n < pseudocluster_adjacency.size(); n++)
1362 {
1363 if (!pseudocluster_adjacency[n])
1364 {
1365 continue;
1366 }
1367
1368 if (pseudocluster_sumE[n] > highest_pseudocluster_E)
1369 {
1370 second_highest_pseudocluster_E = highest_pseudocluster_E;
1371 second_highest_pseudocluster_index = highest_pseudocluster_index;
1372
1373 highest_pseudocluster_E = pseudocluster_sumE[n];
1374 highest_pseudocluster_index = n;
1375 }
1376 else if (pseudocluster_sumE[n] > second_highest_pseudocluster_E)
1377 {
1378 second_highest_pseudocluster_E = pseudocluster_sumE[n];
1379 second_highest_pseudocluster_index = n;
1380 }
1381 }
1382
1383 if (Verbosity() > 5)
1384 {
1385 std::cout << " -> highest pseudoclusters its adjacent to are " << highest_pseudocluster_index << " ( E = " << highest_pseudocluster_E << " ) and " << second_highest_pseudocluster_index << " ( E = " << second_highest_pseudocluster_E << " ) " << std::endl;
1386 }
1387
1388 tower_ownership[shared_ID] = std::pair<int, int>(highest_pseudocluster_index, second_highest_pseudocluster_index);
1389 }
1390
1391 if (Verbosity() > 100)
1392 {
1393 for (int &original_tower : original_towers)
1394 {
1395 std::pair<int, int> the_pair = tower_ownership[original_tower];
1396 std::cout << " Debug Post-Split: tower_ownership[ " << original_tower << " ] = ( " << the_pair.first << ", " << the_pair.second << " ) ";
1397 std::cout << " , layer / ieta / iphi = " << get_ilayer_from_ID(original_tower) << " / " << get_ieta_from_ID(original_tower) << " / " << get_iphi_from_ID(original_tower);
1398 std::cout << std::endl;
1399 if (the_pair.first == -1)
1400 {
1401 std::vector<int> adjacent_tower_IDs = get_adjacent_towers_by_ID(original_tower);
1402
1403 for (int this_adjacent_tower_ID : adjacent_tower_IDs)
1404 {
1405 if (get_status_from_ID(this_adjacent_tower_ID) != cl)
1406 {
1407 continue;
1408 }
1409 std::cout << " -> adjacent to add tower " << this_adjacent_tower_ID << " , which has status " << tower_ownership[this_adjacent_tower_ID].first << std::endl;
1410 }
1411 }
1412 }
1413 }
1414
1415
1416 export_clusters(original_towers, tower_ownership, local_maxima_ID.size(), pseudocluster_sumE, pseudocluster_eta, pseudocluster_phi);
1417 }
1418
1419 if (Verbosity() > 1)
1420 {
1421 std::cout << "RawClusterBuilderTopo::process_event after splitting (if any) final clusters output to node are: " << std::endl;
1422 RawClusterContainer::ConstRange begin_end = _clusters->getClusters();
1423 int ncl = 0;
1424 for (RawClusterContainer::ConstIterator hiter = begin_end.first; hiter != begin_end.second; ++hiter)
1425 {
1426 std::cout << "-> #" << ncl++ << " ";
1427 hiter->second->identify();
1428 std::cout << std::endl;
1429 }
1430 }
1431
1432 return Fun4AllReturnCodes::EVENT_OK;
1433 }
1434
1435 int RawClusterBuilderTopo::End(PHCompositeNode * )
1436 {
1437 return Fun4AllReturnCodes::EVENT_OK;
1438 }
1439
1440 void RawClusterBuilderTopo::CreateNodes(PHCompositeNode *topNode)
1441 {
1442 PHNodeIterator iter(topNode);
1443
1444 PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
1445 if (!dstNode)
1446 {
1447 std::cerr << PHWHERE << "DST Node missing, doing nothing." << std::endl;
1448 throw std::runtime_error("Failed to find DST node in RawClusterBuilderTopo::CreateNodes");
1449 }
1450
1451 PHNodeIterator dstiter(dstNode);
1452 PHCompositeNode *DetNode = dynamic_cast<PHCompositeNode *>(dstiter.findFirst("PHCompositeNode", "TOPOCLUSTER"));
1453 if (!DetNode)
1454 {
1455 DetNode = new PHCompositeNode("TOPOCLUSTER");
1456 dstNode->addNode(DetNode);
1457 }
1458
1459 _clusters = new RawClusterContainer();
1460
1461 PHIODataNode<PHObject> *clusterNode = new PHIODataNode<PHObject>(_clusters, ClusterNodeName, "PHObject");
1462 DetNode->addNode(clusterNode);
1463 }