File indexing completed on 2026-04-05 08:09:24
0001 #ifndef __BUILDMETATOWERS_H__
0002 #define __BUILDMETATOWERS_H__
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <math.h>
0026 #include <vector>
0027 #include <array>
0028 #include <string>
0029
0030
0031 #include <vandyclasses/Tower.h>
0032 #include <vadyclasses/EventInfo.h>
0033
0034
0035 #include <calobase/TowerInfoContainer.h>
0036 #include <calobase/TowerInfoContainerv1.h>
0037 #include <calobase/TowerInfoContainerv2.h>
0038 #include <calobase/TowerInfov2.h>
0039 #include <calobase/TowerInfov1.h>
0040 #include <calobase/TowerInfo.h>
0041 #include <calobase/RawTowerDefs.h>
0042 #include <calobase/RawTowerContainer.h>
0043 #include <calobase/RawTowerGeomContainer.h>
0044 #include <calobase/RawTowerGeomContainer_Cylinderv1.h>
0045
0046
0047 #include <g4main/PHG4Particle.h>
0048 #include <g4main/PHG4Hit.h>
0049 #include <g4main/PHG4TruthInfoContainer.h>
0050
0051
0052 #include <phool/PHCompositeNode.h>
0053 #include <phool/getClass.h>
0054 #include <phool/PHNodeOperation.h>
0055
0056 class BuildMetaTowers
0057 {
0058 public:
0059 BuildMetaTowers(
0060 float radius = 1.245 ,
0061 std::string input="VandyClass"
0062 )
0063 {
0064
0065 if(radius > 50 ) this->R = radius;
0066 if(radius < 50 ) this->R = radius * 100;
0067 this->T = input;
0068 }
0069 ~BuildMetaTowers(){};
0070
0071
0072 struct TowerArrayEntry
0073 {
0074 double Energy;
0075 double phi;
0076 double eta;
0077 };
0078 enum CALO
0079 {
0080 META = 0,
0081 EMCAL = 1,
0082 IHCAL = 2,
0083 OHCAL = 3
0084 };
0085
0086 void RunMetaTowerBuilder(float zVTX)
0087 {
0088 for( int i = 0; i < 24; i++ ) shiftedetaEdges.at(i)=calculateEtaShift(etaEdges.at(i), zVTX);
0089 for( int i = 0; i < 24; i++ )
0090 {
0091 double eta =10.;
0092 if(i < (int) shiftedetaEdges.size() - 1 )
0093 eta = 0.5*(shiftedEtaEdges.at(i), shiftedEtaEdges.at(i+1));
0094 else
0095 eta = 0.5*(shiftedEtaEdges.at(i), 1.1);
0096 for( int j = 0; j < 64; j++)
0097 {
0098 double pt =100.;
0099 TowerArrayEntry* tower =
0100 new TowerArrayEntry* {0., shiftedEtaEdges.at(i), phiEdges.at(i)};
0101 if(i < (int) phiEdges.size() - 1 )
0102 phi = 0.5*(phiEdges.at(i), phiEdges.at(i+1));
0103 else
0104 phi = 0.5*(phiEdges.at(i), phiEdges.at(0));
0105 if(phi > M_PI) phi += -2*M_PI;
0106 if(phi < -M_PI) phi += 2*M_PI;
0107 tower->eta = eta;
0108 tower->phi = phi;
0109 int index = CalculateIndex(tower);
0110 MetaTower->at(index)=tower;
0111 }
0112
0113 }
0114 for(int i=0; i<(int)EMReTowers->size(); i++) AddMetaTower(EMReTowers->at(i));
0115 for(int i=0; i<(int)IHCaTowers->size(); i++) AddMetaTower(IHCaTowers->at(i));
0116 for(int i=0; i<(int)OHCaTowers->size(); i++) AddMetaTower(OHCaTowers->at(i));
0117 return;
0118
0119 }
0120
0121 void GetFun4AllTowers(
0122 TowerInfoContainerv2 CAL,
0123 RawTowerGeomContainer_Cylinderv1 geom,
0124 std::array<TowerArrayEntry*, 1536>* Towers
0125 double zVTX,
0126 CALO calo
0127 )
0128 {
0129 for(int t = 0; t < (int)CAL.size(); t++)
0130 {
0131 auto key = CAL.encode_key(n) ;
0132 auto f4tower = CAL.get_tower_at_channel(t);
0133 int phibin = CAL.getTowerPhiBin(key);
0134 int etabin = CAL.getTowerEtabin(key);
0135 double phi = geom.get_phicenter(phibin);
0136 double eta = geom.get_etaecenter(etabin);
0137 double E = f4tower->get_energy();
0138 eta = CalculateEtaShift(eta, zVTX, calo);
0139 TowerArrayEntry* tower =
0140 new TowerArrayEntry {E, phi, eta};
0141 int index = CalculateIndex(tower, true);
0142 Towers->at(index) = tower;
0143 }
0144 return;
0145 }
0146 void GetEMCALTowers(
0147 TowerInfoContainerv2 EMCAL,
0148 RawTowerGeomContainer_Cylinderv1 EMCAL_geom,
0149 bool isRetower=false,
0150 double zVTX = 0.
0151 )
0152 {
0153 if(!isRetower){
0154 std::cout<<"Please use the retowered EMCAL" <<std::endl;
0155 return;
0156 }
0157 CALO cal = CALO::EMCAL;
0158 GetFun4AllTowers(EMCAL, EMCAL_geom, EMReTowers, zVTX, cal);
0159 return;
0160 }
0161 void GetHCALTowers(
0162 TowerInfoContainerv2 HCAL,
0163 RawTowerGeomContainer_Cylinderv1 HCAL_geom,
0164 bool outer=false,
0165 double zVTX = 0.
0166 )
0167 {
0168 std::array<TowerEntryArray*, 1536>* HCaTowers = NULL;
0169 CALO cal = CALO::OHCAL;
0170 if(outer){
0171 HCaTowers = OHCaTowers;
0172 cal = CALO::OHCAL;
0173 }
0174 else{
0175 HCaTowers = IHCaTowers;
0176 cal = CALO::IHCAL;
0177 }
0178 GetFun4AllTowers(HCAL, HCAL_geom, HCaTowers, zVTX, cal);
0179 return;
0180 }
0181
0182
0183
0184 void GetEMCALTowers(
0185 std::vector<Tower*> EMCAL,
0186 bool isRetower=false,
0187 double zVTX = 0.
0188 )
0189 {
0190 if(!isRetower){
0191 std::cout<<"Please use retowered"<<std::endl;
0192 return;
0193 }
0194 CALO calo = CALO::EMCAL;
0195 GetVandyTowers(EMCAL, EMReTowers, zVTX, calo);
0196 return;
0197 }
0198 void GetHCALTowers(
0199 std::vector<Tower*> HCAL,
0200 bool outer=false,
0201 double zVTX = 0.
0202 );
0203 {
0204 if(outer)
0205 {
0206 CALO calo = CALO::OHCAL;
0207 GetVandyTowers(HCAL, OHCaTowers, zVTX, calo);
0208 }
0209 else if(!outer)
0210 {
0211 CALO calo = CALO::IHCAL;
0212 GetVandyTowers(HCAL, IHCaTowers, zVTX, calo);
0213 }
0214 return;
0215 }
0216 void GetVandyTowers(
0217 std::vector<Tower*> CAL,
0218 std::array<TowerArrayEntry*, 1536>* output_array
0219 double zVTX,
0220 CALO calo
0221 )
0222 {
0223 for(int i = 0; i<(int)CAL.size(); i++)
0224 {
0225 Tower* tw = CAL.at(i);
0226 double E = tw->e();
0227 double px = tw->px();
0228 double py = tw->py();
0229 double pz = tw->pz();
0230 double p = std::sqrt(std::pow(px, 2) + std::pow(py, 2) + std::pow(pz, 2));
0231 double phi = std::atan2(px, py);
0232 double eta = std::atanh(pz/p);
0233 eta = CalculateEtaShift(eta, zVTX, calo);
0234 TowerArrayEntry* tower = new TowerArrayEntry {E, phi, eta};
0235 int index = CalculateIndex(tower, true);
0236 output_array->at(i) = tower;
0237 }
0238 return;
0239 }
0240
0241
0242 void GetEMCALTowers(
0243 std::vector<TowerArrayEntry*> EMCAL,
0244 bool isRetower = false,
0245 double zVTX = 0.
0246 )
0247 {
0248 CALO calo = CALO::EMCAL;
0249 for(int i = 0; i <(int)EMCAL->size(); i++)
0250 {
0251 EMReTowers->at(i) = EMCAL->at(i);
0252 EMReTowers->at(i)->eta = calculateEtaShift(EMReTower->at(i)->eta, zVTX, calo);
0253 }
0254 return;
0255 }
0256
0257 void GetHCALTowers(
0258 std::vector<TowerArrayEntry*> HCAL,
0259 bool outer=false,
0260 double zVTX = 0.
0261 )
0262 {
0263 CALO calo = CALO::OHCAL;
0264 std::array<TowerArrayEntry*>* HC = OHCaTowers;
0265 if(!outer){
0266 calo = CALO::IHCAL;
0267 HC = IHCaTowers;
0268 for(int i = 0; i <(int)HCAL->size(); i++)
0269 {
0270 HC->at(i)->eta = calculateEtaShift(HCAL->at(i)->eta, zVTX, calo);
0271 }
0272 return;
0273 }
0274
0275 void setRadius ( float r = 1.245 ) { this->R = r ; } ;
0276 float getRadius ( ) { return this->R; };
0277
0278 void setInput
0279 ( std::string input = "VandyClass" ) { this->T = input; };
0280 std::string getInput() { return this->T; };
0281
0282
0283 std::array<TowerArrayEntry*, 1536>* getMetaTowers() { return this->MetaTowers; };
0284
0285 private:
0286
0287 float R { 1245 };
0288 std::string T { "VandyClass" };
0289 const float R_OHCAL_Outer {269};
0290 const float R_OHCAL_Inner {182};
0291 const float R_IHCAL_Outer {137};
0292 const float R_IHCAL_Inner {116};
0293 const float R_EMCAL_Outer {116};
0294 const float R_EMCAL_Inner { 90};
0295 const float R_OHCAL_MID { 1/2.*(R_OHCAL_Outer + R_OHCAL_Inner) };
0296 const float R_IHCAL_MID { 1/2.*(R_IHCAL_Outer + R_IHCAL_Inner) };
0297 const float R_EMCAL_MID { 1/2.*(R_EMCAL_Outer + R_EMCAL_Inner) };
0298 std::array <TowerArrayEntry*, 1536>* MetaTowers = new std::array <TowerArrayEntry*, 1536> {};
0299 std::array <TowerArrayEntry*, 1536>* EMReTowers = new std::array <TowerArrayEntry*, 1536> {};
0300 std::array <TowerArrayEntry*, 1536>* IHCaTowers = new std::array <TowerArrayEntry*, 1536> {};
0301 std::array <TowerArrayEntry*, 1536>* OHCaTowers = new std::array <TowerArrayEntry*, 1536> {};
0302
0303
0304 const std::array <double, 24> etaEdges
0305 { -1.1000000, -1.0083333, -0.91666667, -0.82500000, -0.73333333, -0.64166667,
0306 -0.55000000, -0.45833333, -0.36666667, -0.27500000, -0.18333333, -0.091666667,
0307 1.1102230e-16, 0.091666667, 0.18333333, 0.27500000, 0.36666667, 0.45833333,
0308 0.55000000, 0.64166667, 0.73333333, 0.82500000, 0.91666667, 1.0083333, 1.1000000 };
0309
0310 const std::array <double, 64> phiEdges
0311 { -0.053619781, 0.044554989, 0.14272976, 0.24090453, 0.33907930, 0.43725407,
0312 0.53542884, 0.63360361, 0.73177838, 0.82995315, 0.92812792, 1.0263027,
0313 1.1244775, 1.2226522, 1.3208270, 1.4190018, 1.5171765, 1.6153513, 1.7135261,
0314 1.8117009, 1.9098756, 2.0080504, 2.1062252, 2.2043999, 2.3025747, 2.4007495,
0315 2.4989242, 2.5970990, 2.6952738, 2.7934486, 2.8916233, 2.9897981, 3.0879729,
0316 3.1861476, 3.2843224, 3.3824972, 3.4806720, 3.5788467, 3.6770215, 3.7751963,
0317 3.8733710, 3.9715458, 4.0697206, 4.1678953, 4.2660701, 4.3642449, 4.4624197,
0318 4.5605944, 4.6587692, 4.7569440, 4.8551187, 4.9532935, 5.0514683, 5.1496431,
0319 5.2478178, 5.3459926, 5.4441674, 5.5423421, 5.6405169, 5.7386917, 5.8368664,
0320 5.9350412, 6.0332160, 6.1313908, 6.2295655 };
0321
0322 std::array<double ,24> shiftedetaEdges {};
0323
0324
0325 double calculateEtaShift(double eta, double zVtx)
0326 {
0327 double z = R*std::sinh(eta);
0328 double zshift = z-zVtx;
0329 zshift = zshift / R;
0330 double etashift = std::asinh(zshift);
0331 return etashift;
0332 }
0333 double calculateEtaShift(double eta, double zVtx, CAlO calo)
0334 {
0335 double r = this->R;
0336 if( calo == CALO::EMCAL ) r = R_EMCAL_MID;
0337 else if( calo == CALO::IHCAL ) r = R_IHCAL_MID;
0338 else if( calo == CALO::OHCAL ) r = R_OHCAL_MID;
0339 else r = this->R;
0340 double z = R*std::sinh(eta);
0341 double zshift = z-zVtx;
0342 zshift = zshift / R;
0343 double etashift = std::asinh(zshift);
0344 return etashift;
0345 }
0346
0347
0348 int calculateIndex(TowerArrayEntry tower, bool useSlant)
0349 {
0350 int etabin = 0;
0351 int phibin = 0;
0352 etabin = LookupBin(tower.eta, useSlant, true);
0353 phibin = LookupBin(tower.phi, useSlant, false);
0354 int index = etabin * 64 + phibin ;
0355 return index;
0356 }
0357 int LookupBin(double towervalue, bool useSlant, bool isEta)
0358 {
0359 std::vector<double> tempBottom;
0360 int binN=0;
0361 if(isEta && useSlant)
0362 {
0363 for(int i = 0; i<(int) shiftedEtaEdges.size(); i++){
0364 tempBottom.push_back(shiftedEtaEdges.at(i));
0365 }
0366 }
0367 else if (isEta)
0368 {
0369 for(int i = 0; i<(int) EtaEdges.size(); i++){
0370 tempBottom.push_back(EtaEdges.at(i));
0371 }
0372 }
0373 else
0374 {
0375 for(int i = 0; i<(int) PhiEdges.size(); i++){
0376 tempBottom.push_back(PhiEdges.at(i));
0377 }
0378 }
0379 for(int i = 0; i<(int)tempBottom.size(); i++)
0380 {
0381 if(towervalue >= tempBottom.at(i)){
0382 binN = i;
0383 continue;
0384 }
0385 if(towervalue < tempBottom.at(i)){
0386 break;
0387 }
0388 }
0389 return binN;
0390 }
0391 void decodeIndex(int index, int* ebr, int* pbr)
0392 {
0393
0394 int etabin = index / 64;
0395 int phibin = index % 64;
0396 ebr = &etabin;
0397 pbr = &phibin;
0398 return;
0399 }
0400
0401 void shiftBinMins(double zVtx)
0402 {
0403 for(int i= 0; i<(int) etaEdges.size(); i++)
0404 {
0405 shiftedetaEdges[i]=calculateEtaShift(etaEdges[i], zVtx);
0406 }
0407 return;
0408 }
0409 void shiftEMCAL(std::vector<TowerArrayEntry*> emcal, bool isRetower, float zVTX)
0410 {
0411 if(!isRetower || (int) emcal.size() > 1536)
0412 {
0413 std::vector<TowerArrayEntry*> rtEM = RetowerEMCAL(emcal);
0414 emcal.clear();
0415 emcal = rtEM;
0416 }
0417 for(int i = 0; i<(int) emcal.size(); i++)
0418 {
0419 TowerArrayEntry* nTower = shiftTower(emcal.at(i), CALO::EMC, zVTX);
0420 int N = calculateIndex( *nTower );
0421 EMReTowers->at(N) = nTower;
0422 }
0423 return;
0424 }
0425
0426 void shiftIHCAL(std::vector<TowerArrayEntry*> ihcal, float zVTX);
0427 {
0428 for(int i = 0; i<(int) ihcal.size(); i++)
0429 {
0430 TowerArrayEntry* nTower = shiftTower(ihcal.at(i), CALO::IHC, zVTX);
0431 int N = calculateIndex( *nTower );
0432 IHCaTowers->at(N) = nTower;
0433 }
0434 return;
0435 }
0436 void shiftOHCAL(std::vector<TowerArrayEntry*> ohcal, float zVTX);
0437 {
0438 for(int i = 0; i<(int) ohcal.size(); i++)
0439 {
0440 TowerArrayEntry* nTower = shiftTower(ohcal.at(i), CALO::OHC, zVTX);
0441 int N = calculateIndex( *nTower );
0442 OHCaTowers->at(N) = nTower;
0443 }
0444 return;
0445 }
0446 void addMetaTower(TowerArrayEntry tower)
0447 {
0448 double eta_val = tower.eta;
0449 double phi_val = tower.phi;
0450 int etaBin = findEtaBin(eta_val);
0451 int phiBin = findPhiBin(phi_val);
0452 int N = calculateIndex(tower);
0453 if (!MetaTowers->at(N)) MetaTowers->at(N) =
0454 new TowerArrayEntry* { 0, getPhiCenter(phiBin), getEtaCenter(etaBin) };
0455 MetaTowers->at(N)->E += tower.E;
0456 return;
0457 }
0458 TowerArrayEntry* shiftTower(TowerArrayEntry* tower, CALO calo, float zVTX)
0459 {
0460
0461 tower->eta = CalculateEtaShift(tower->eta, zVTX, calo);
0462 return tower;
0463 }
0464
0465 };
0466
0467 #endif