File indexing completed on 2024-04-06 12:11:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <memory>
0022 #include <vector>
0023 #include <iostream>
0024 #include <sstream>
0025 #include <TMath.h>
0026 #include <TRandom3.h>
0027 #include <TF1.h>
0028
0029
0030 #include "FWCore/Framework/interface/Frameworkfwd.h"
0031
0032 #include "FWCore/Framework/interface/Event.h"
0033 #include "FWCore/Framework/interface/MakerMacros.h"
0034
0035 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0036
0037 #include "DataFormats/Math/interface/Point3D.h"
0038
0039
0040 #include "DataFormats/CastorReco/interface/CastorTower.h"
0041 #include "DataFormats/HcalRecHit/interface/CastorRecHit.h"
0042 #include "DataFormats/HcalDetId/interface/HcalCastorDetId.h"
0043
0044
0045 #include "DataFormats/Candidate/interface/Candidate.h"
0046
0047 #include "FastSimulation/ForwardDetectors/plugins/CastorFastTowerProducer.h"
0048
0049
0050
0051
0052 CastorFastTowerProducer::CastorFastTowerProducer(const edm::ParameterSet& iConfig)
0053 : tokGenPart_(consumes<reco::GenParticleCollection>(edm::InputTag{"genParticles"})) {
0054
0055 produces<CastorTowerCollection>();
0056
0057
0058 }
0059
0060 CastorFastTowerProducer::~CastorFastTowerProducer() {
0061
0062
0063 }
0064
0065
0066
0067
0068
0069
0070 void CastorFastTowerProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0071 using namespace edm;
0072 using namespace reco;
0073 using namespace std;
0074 using namespace TMath;
0075
0076
0077
0078
0079
0080
0081
0082 const edm::Handle<GenParticleCollection>& genParticles = iEvent.getHandle(tokGenPart_);
0083
0084
0085 unique_ptr<CastorTowerCollection> CastorTowers(new CastorTowerCollection);
0086
0087
0088 double castorplus[4][16];
0089 double castormin[4][16];
0090
0091 for (int j = 0; j < 16; j++) {
0092 castorplus[3][j] = -2.94524 + j * 0.3927;
0093 castormin[3][j] = -2.94524 + j * 0.3927;
0094 castorplus[0][j] = 0.;
0095 castormin[0][j] = 0.;
0096 castorplus[1][j] = 0.;
0097 castormin[1][j] = 0.;
0098 castorplus[2][j] = 0.;
0099 castormin[2][j] = 0.;
0100
0101
0102 }
0103
0104
0105 vector<double> depthplus[16];
0106 vector<double> depthmin[16];
0107 vector<double> fhotplus[16];
0108 vector<double> fhotmin[16];
0109 vector<double> energyplus[16];
0110 vector<double> energymin[16];
0111
0112
0113
0114 for (int i = 0; i < 16; i++) {
0115 depthplus[i].clear();
0116 depthmin[i].clear();
0117 fhotplus[i].clear();
0118 fhotmin[i].clear();
0119 energyplus[i].clear();
0120 energymin[i].clear();
0121
0122
0123 }
0124
0125
0126
0127
0128 for (size_t i = 0; i < genParticles->size(); ++i) {
0129 const Candidate& p = (*genParticles)[i];
0130
0131
0132 if (fabs(p.eta()) > 5.2 && fabs(p.eta()) < 6.6) {
0133
0134
0135
0136
0137 double energy = -1.;
0138 double emEnergy = 0.;
0139 double hadEnergy = 0.;
0140 double fhot = 0.;
0141 double depth = 0.;
0142
0143
0144
0145 if (p.pdgId() == 11 || p.pdgId() == 22) {
0146
0147 while (energy < 0.) {
0148
0149 TRandom3 r(0);
0150
0151 double mean = 1.0024 * p.energy() - 0.3859;
0152 double sigma = 0.0228 * p.energy() + 2.1061;
0153 energy = r.Gaus(mean, sigma);
0154 }
0155
0156
0157 double tmax;
0158 double a;
0159 double cte;
0160 if (p.pdgId() == 11) {
0161 cte = -0.5;
0162 } else {
0163 cte = 0.5;
0164 }
0165 tmax = 1.0 * (log(energy / 0.0015) + cte);
0166 a = tmax * 0.5 + 1;
0167 double leakage;
0168 double x = 0.5 * 19.38;
0169 leakage = energy - energy * Gamma(a, x);
0170
0171
0172 emEnergy = energy - leakage;
0173
0174 hadEnergy = leakage;
0175
0176
0177 double d0 = 0.2338 * pow(p.energy(), -0.1634);
0178 double d1 = 5.4336 * pow(p.energy(), 0.2410) + 14408.1025;
0179 double d2 = 1.4692 * pow(p.energy(), 0.1307) - 0.5216;
0180 if (d0 < 0.)
0181 d0 = abs(d0);
0182
0183 TF1* fdepth =
0184 new TF1("fdepth", "[0] * TMath::Exp(-0.5*( (x-[1])/[2] + TMath::Exp(-(x-[1])/[2])))", 14400., 14460.);
0185 fdepth->SetParameters(d0, d1, d2);
0186 depth = fdepth->GetRandom();
0187 fdepth->Delete();
0188 if (p.eta() < 0.)
0189 depth = -1 * depth;
0190
0191 } else {
0192
0193 while (energy < 0.) {
0194
0195 TRandom3 r(0);
0196
0197 double mean = 0.8340 * p.energy() - 8.5054;
0198 double sigma = 0.1595 * p.energy() + 3.1183;
0199 energy = r.Gaus(mean, sigma);
0200 }
0201
0202
0203 hadEnergy = energy;
0204
0205
0206
0207
0208 double d0 = -0.000012 * p.energy() + 0.0661;
0209 double d1 = 785.7524 * pow(p.energy(), 0.0262) + 13663.4262;
0210 double d2 = 9.8748 * pow(p.energy(), 0.1720) + 37.0187;
0211 if (d0 < 0.)
0212 d0 = abs(d0);
0213
0214 TF1* fdepth =
0215 new TF1("fdepth", "[0] * TMath::Exp(-0.5*( (x-[1])/[2] + TMath::Exp(-(x-[1])/[2]) ))", 14400., 15500.);
0216 fdepth->SetParameters(d0, d1, d2);
0217 depth = fdepth->GetRandom();
0218 fdepth->Delete();
0219 if (p.eta() < 0.)
0220 depth = -1 * depth;
0221 }
0222
0223
0224
0225
0226 int sector = -1;
0227 for (int j = 0; j < 16; j++) {
0228 double a = -M_PI + j * 0.3927;
0229 double b = -M_PI + (j + 1) * 0.3927;
0230 if ((p.phi() > a) && (p.phi() < b)) {
0231 sector = j;
0232 }
0233 }
0234
0235
0236 if (p.eta() > 0) {
0237 castorplus[0][sector] = castorplus[0][sector] + energy;
0238 castorplus[1][sector] = castorplus[1][sector] + emEnergy;
0239 castorplus[2][sector] = castorplus[2][sector] + hadEnergy;
0240
0241 depthplus[sector].push_back(depth);
0242 fhotplus[sector].push_back(fhot);
0243 energyplus[sector].push_back(energy);
0244
0245
0246
0247
0248
0249 } else {
0250 castormin[0][sector] = castormin[0][sector] + energy;
0251 castormin[1][sector] = castormin[1][sector] + emEnergy;
0252 castormin[2][sector] = castormin[2][sector] + hadEnergy;
0253
0254 depthmin[sector].push_back(depth);
0255 fhotmin[sector].push_back(fhot);
0256 energymin[sector].push_back(energy);
0257
0258 }
0259 }
0260 }
0261
0262
0263 for (int j = 0; j < 16; j++) {
0264 double hadnoise = 0.;
0265 double emnoise = 0.;
0266 for (int i = 0; i < 12; i++) {
0267 hadnoise = hadnoise + make_noise();
0268 if (i < 2)
0269 emnoise = emnoise + make_noise();
0270 }
0271
0272 hadnoise = hadnoise - 12 * 0.053;
0273 emnoise = emnoise - 2 * 0.053;
0274 if (hadnoise < 0.)
0275 hadnoise = 0.;
0276 if (emnoise < 0.)
0277 emnoise = 0.;
0278 double totnoise = hadnoise + emnoise;
0279
0280
0281 castorplus[0][j] = castorplus[0][j] + totnoise;
0282 castormin[0][j] = castormin[0][j] + totnoise;
0283 castorplus[1][j] = castorplus[1][j] + emnoise;
0284 castormin[1][j] = castormin[1][j] + emnoise;
0285 castorplus[2][j] = castorplus[2][j] + hadnoise;
0286 castormin[2][j] = castormin[2][j] + hadnoise;
0287
0288
0289
0290
0291 }
0292
0293
0294
0295 for (int j = 0; j < 16; j++) {
0296 if (castorplus[0][j] != 0.) {
0297 double fem = 0.;
0298 fem = castorplus[1][j] / castorplus[0][j];
0299 TowerPoint pt1(88.5, 5.9, castorplus[3][j]);
0300 Point pt2(pt1);
0301
0302
0303
0304 double depth_mean = 0.;
0305 double fhot_mean = 0.;
0306 double sum_energy = 0.;
0307
0308
0309 for (size_t p = 0; p < energyplus[j].size(); p++) {
0310 depth_mean = depth_mean + depthplus[j][p] * energyplus[j][p];
0311 fhot_mean = fhot_mean + fhotplus[j][p] * energyplus[j][p];
0312 sum_energy = sum_energy + energyplus[j][p];
0313 }
0314 depth_mean = depth_mean / sum_energy;
0315 fhot_mean = fhot_mean / sum_energy;
0316
0317
0318
0319 edm::RefVector<edm::SortedCollection<CastorRecHit> > refvector;
0320 CastorTowers->push_back(reco::CastorTower(
0321 castorplus[0][j], pt2, castorplus[1][j], castorplus[2][j], fem, depth_mean, fhot_mean, refvector));
0322 }
0323 }
0324
0325 for (int j = 0; j < 16; j++) {
0326 if (castormin[0][j] != 0.) {
0327 double fem = 0.;
0328 fem = castormin[1][j] / castormin[0][j];
0329 TowerPoint pt1(88.5, -5.9, castormin[3][j]);
0330 Point pt2(pt1);
0331
0332 double depth_mean = 0.;
0333 double fhot_mean = 0.;
0334 double sum_energy = 0.;
0335
0336 for (size_t p = 0; p < energymin[j].size(); p++) {
0337 depth_mean = depth_mean + depthmin[j][p] * energymin[j][p];
0338 fhot_mean = fhot_mean + fhotmin[j][p] * energymin[j][p];
0339 sum_energy = sum_energy + energymin[j][p];
0340 }
0341 depth_mean = depth_mean / sum_energy;
0342 fhot_mean = fhot_mean / sum_energy;
0343
0344
0345 edm::RefVector<edm::SortedCollection<CastorRecHit> > refvector;
0346 CastorTowers->push_back(reco::CastorTower(
0347 castormin[0][j], pt2, castormin[1][j], castormin[2][j], fem, depth_mean, fhot_mean, refvector));
0348 }
0349 }
0350
0351 iEvent.put(std::move(CastorTowers));
0352 }
0353
0354 double CastorFastTowerProducer::make_noise() {
0355 double result = -1.;
0356 TRandom3 r2(0);
0357 double mu_noise = 0.053;
0358 double sigma_noise = 0.027;
0359
0360 while (result < 0.) {
0361 result = r2.Gaus(mu_noise, sigma_noise);
0362 }
0363
0364 return result;
0365 }
0366
0367
0368 DEFINE_FWK_MODULE(CastorFastTowerProducer);