File indexing completed on 2024-04-06 12:13:39
0001
0002
0003
0004
0005
0006 #include "GeneratorInterface/GenFilters/plugins/CosmicGenFilterHelix.h"
0007
0008
0009 #include "FWCore/Framework/interface/ESHandle.h"
0010 #include "DataFormats/Common/interface/Handle.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 #include "FWCore/Utilities/interface/InputTag.h"
0013 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixPropagator.h"
0014 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
0015 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
0016 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
0017 #include "CommonTools/UtilAlgos/interface/TFileService.h"
0018 #include "CommonTools/Utils/interface/TFileDirectory.h"
0019 #include "FWCore/ServiceRegistry/interface/Service.h"
0020
0021 #include <TMath.h>
0022 #include <TH1.h> // include checker: don't touch!
0023 #include <TH2.h> // include checker: don't touch!
0024
0025 #include <utility> // for std::pair
0026 #include <string>
0027
0028
0029
0030
0031
0032
0033 CosmicGenFilterHelix::CosmicGenFilterHelix(const edm::ParameterSet &cfg)
0034 : theMFToken(esConsumes()),
0035 thePropToken(esConsumes(edm::ESInputTag("", cfg.getParameter<std::string>("propagator")))),
0036 theIds(cfg.getParameter<std::vector<int> >("pdgIds")),
0037 theCharges(cfg.getParameter<std::vector<int> >("charges")),
0038 theMinP2(cfg.getParameter<double>("minP") * cfg.getParameter<double>("minP")),
0039 theMinPt2(cfg.getParameter<double>("minPt") * cfg.getParameter<double>("minPt")),
0040 theDoMonitor(cfg.getUntrackedParameter<bool>("doMonitor")) {
0041 theSrcToken = consumes<edm::HepMCProduct>(cfg.getParameter<edm::InputTag>("src"));
0042
0043 usesResource(TFileService::kSharedResource);
0044
0045 if (theIds.size() != theCharges.size()) {
0046 throw cms::Exception("BadConfig") << "CosmicGenFilterHelix: "
0047 << "'pdgIds' and 'charges' need same length.";
0048 }
0049 Surface::Scalar radius = cfg.getParameter<double>("radius");
0050 Surface::Scalar maxZ = cfg.getParameter<double>("maxZ");
0051 Surface::Scalar minZ = cfg.getParameter<double>("minZ");
0052
0053 if (maxZ < minZ) {
0054 throw cms::Exception("BadConfig") << "CosmicGenFilterHelix: maxZ (" << maxZ << ") smaller than minZ (" << minZ
0055 << ").";
0056 }
0057
0058 const Surface::RotationType dummyRot;
0059 theTargetCylinder = Cylinder::build(Surface::PositionType(0., 0., 0.), dummyRot, radius);
0060 theTargetPlaneMin = Plane::build(Surface::PositionType(0., 0., minZ), dummyRot);
0061 theTargetPlaneMax = Plane::build(Surface::PositionType(0., 0., maxZ), dummyRot);
0062 }
0063
0064
0065 CosmicGenFilterHelix::~CosmicGenFilterHelix() {}
0066
0067
0068
0069
0070
0071
0072 bool CosmicGenFilterHelix::filter(edm::Event &iEvent, const edm::EventSetup &iSetup) {
0073 edm::Handle<edm::HepMCProduct> hepMCEvt;
0074 iEvent.getByToken(theSrcToken, hepMCEvt);
0075 const HepMC::GenEvent *mCEvt = hepMCEvt->GetEvent();
0076 const MagneticField *bField = this->getMagneticField(iSetup);
0077 const Propagator *propagator = this->getPropagator(iSetup);
0078
0079 ++theNumTotal;
0080 bool result = false;
0081 for (HepMC::GenEvent::particle_const_iterator iPart = mCEvt->particles_begin(), endPart = mCEvt->particles_end();
0082 iPart != endPart;
0083 ++iPart) {
0084 int charge = 0;
0085 if ((*iPart)->status() != 1)
0086 continue;
0087 if (!this->charge((*iPart)->pdg_id(), charge))
0088 continue;
0089
0090
0091 const HepMC::ThreeVector hepVertex((*iPart)->production_vertex()->point3d());
0092 const GlobalPoint vert(hepVertex.x() / 10., hepVertex.y() / 10., hepVertex.z() / 10.);
0093 const HepMC::FourVector hepMomentum((*iPart)->momentum());
0094 const GlobalVector mom(hepMomentum.x(), hepMomentum.y(), hepMomentum.z());
0095
0096 if (theDoMonitor)
0097 this->monitorStart(vert, mom, charge, theHistsBefore);
0098
0099 if (this->propagateToCutCylinder(vert, mom, charge, bField, propagator)) {
0100 result = true;
0101 }
0102 }
0103
0104 if (result)
0105 ++theNumPass;
0106 return result;
0107 }
0108
0109
0110 bool CosmicGenFilterHelix::propagateToCutCylinder(const GlobalPoint &vertStart,
0111 const GlobalVector &momStart,
0112 int charge,
0113 const MagneticField *field,
0114 const Propagator *propagator) {
0115 typedef std::pair<TrajectoryStateOnSurface, double> TsosPath;
0116
0117 const FreeTrajectoryState fts(GlobalTrajectoryParameters(vertStart, momStart, charge, field));
0118
0119 bool result = true;
0120 TsosPath aTsosPath(propagator->propagateWithPath(fts, *theTargetCylinder));
0121 if (!aTsosPath.first.isValid()) {
0122 result = false;
0123 } else if (aTsosPath.first.globalPosition().z() < theTargetPlaneMin->position().z()) {
0124
0125
0126
0127 aTsosPath = propagator->propagateWithPath(fts, *theTargetPlaneMin);
0128 if (!aTsosPath.first.isValid() || aTsosPath.first.globalPosition().perp() > theTargetCylinder->radius()) {
0129 result = false;
0130 }
0131 } else if (aTsosPath.first.globalPosition().z() > theTargetPlaneMax->position().z()) {
0132
0133 aTsosPath = propagator->propagateWithPath(fts, *theTargetPlaneMax);
0134 if (!aTsosPath.first.isValid() || aTsosPath.first.globalPosition().perp() > theTargetCylinder->radius()) {
0135 result = false;
0136 }
0137 }
0138
0139 if (result) {
0140 const GlobalVector momEnd(aTsosPath.first.globalMomentum());
0141 if (momEnd.perp2() < theMinPt2 || momEnd.mag2() < theMinP2) {
0142 result = false;
0143 } else if (theDoMonitor) {
0144 const GlobalPoint vertEnd(aTsosPath.first.globalPosition());
0145 this->monitorStart(vertStart, momStart, charge, theHistsAfter);
0146 this->monitorEnd(vertEnd, momEnd, vertStart, momStart, aTsosPath.second, theHistsAfter);
0147 }
0148 }
0149
0150 return result;
0151 }
0152
0153
0154 void CosmicGenFilterHelix::beginJob() {
0155 if (theDoMonitor) {
0156 this->createHistsStart("start", theHistsBefore);
0157 this->createHistsStart("startAfter", theHistsAfter);
0158
0159 this->createHistsEnd("end", theHistsAfter);
0160 }
0161
0162 theNumTotal = theNumPass = 0;
0163 }
0164
0165
0166 void CosmicGenFilterHelix::createHistsStart(const char *dirName, TObjArray &hists) {
0167 edm::Service<TFileService> fs;
0168 TFileDirectory fd(fs->mkdir(dirName, dirName));
0169
0170 hists.Add(fd.make<TH1F>("momentumP", "|p(#mu^{+})| (start);|p| [GeV]", 100, 0., 1000.));
0171 hists.Add(fd.make<TH1F>("momentumM", "|p(#mu^{-})| (start);|p| [GeV]", 100, 0., 1000.));
0172 hists.Add(fd.make<TH1F>("momentum2", "|p(#mu)| (start);|p| [GeV]", 100, 0., 25.));
0173 const int kNumBins = 50;
0174 double pBinsLog[kNumBins + 1] = {0.};
0175 this->equidistLogBins(pBinsLog, kNumBins, 1., 4000.);
0176 hists.Add(fd.make<TH1F>("momentumLog", "|p(#mu)| (start);|p| [GeV]", kNumBins, pBinsLog));
0177 hists.Add(fd.make<TH1F>("phi", "start p_{#phi(#mu)};#phi", 100, -TMath::Pi(), TMath::Pi()));
0178 hists.Add(fd.make<TH1F>("cosPhi", "cos(p_{#phi(#mu)}) (start);cos(#phi)", 100, -1., 1.));
0179 hists.Add(fd.make<TH1F>("phiXz", "start p_{#phi_{xz}(#mu)};#phi_{xz}", 100, -TMath::Pi(), TMath::Pi()));
0180 hists.Add(fd.make<TH1F>("theta", "#theta(#mu) (start);#theta", 100, 0., TMath::Pi()));
0181 hists.Add(fd.make<TH1F>("thetaY", "#theta_{y}(#mu) (start);#theta_{y}", 100, 0., TMath::Pi() / 2.));
0182
0183 hists.Add(fd.make<TH2F>(
0184 "momVsPhi", "|p(#mu)| vs #phi (start);#phi;|p| [GeV]", 50, -TMath::Pi(), TMath::Pi(), 50, 1.5, 1000.));
0185 hists.Add(
0186 fd.make<TH2F>("momVsTheta", "|p(#mu)| vs #theta (start);#theta;|p| [GeV]", 50, 0., TMath::Pi(), 50, 1.5, 1000.));
0187 hists.Add(fd.make<TH2F>(
0188 "momVsThetaY", "|p(#mu)| vs #theta_{y} (start);#theta_{y};|p| [GeV]", 50, 0., TMath::Pi() / 2., 50, 1.5, 1000.));
0189 hists.Add(fd.make<TH2F>("momVsZ", "|p(#mu)| vs z (start);z [cm];|p| [GeV]", 50, -1600., 1600., 50, 1.5, 1000.));
0190 hists.Add(fd.make<TH2F>("thetaVsZ", "#theta vs z (start);z [cm];#theta", 50, -1600., 1600., 50, 0., TMath::Pi()));
0191 hists.Add(
0192 fd.make<TH2F>("thetaYvsZ", "#theta_{y} vs z (start);z [cm];#theta", 50, -1600., 1600., 50, 0., TMath::PiOver2()));
0193 hists.Add(fd.make<TH2F>(
0194 "yVsThetaY", "#theta_{y}(#mu) vs y (start);#theta_{y};y [cm]", 50, 0., TMath::Pi() / 2., 50, -1000., 1000.));
0195 hists.Add(fd.make<TH2F>("yVsThetaYnoR",
0196 "#theta_{y}(#mu) vs y (start, barrel);#theta_{y};y [cm]",
0197 50,
0198 0.,
0199 TMath::Pi() / 2.,
0200 50,
0201 -1000.,
0202 1000.));
0203
0204 hists.Add(fd.make<TH1F>("radius", "start radius;r [cm]", 100, 0., 1000.));
0205 hists.Add(fd.make<TH1F>("z", "start z;z [cm]", 100, -1600., 1600.));
0206 hists.Add(fd.make<TH2F>("xyPlane", "start xy;x [cm];y [cm]", 50, -1000., 1000., 50, -1000., 1000.));
0207 hists.Add(fd.make<TH2F>(
0208 "rzPlane", "start rz (y < 0 #Rightarrow r_{#pm} = -r);z [cm];r_{#pm} [cm]", 50, -1600., 1600., 50, -1000., 1000.));
0209 }
0210
0211
0212 void CosmicGenFilterHelix::createHistsEnd(const char *dirName, TObjArray &hists) {
0213 edm::Service<TFileService> fs;
0214 TFileDirectory fd(fs->mkdir(dirName, dirName));
0215
0216 const int kNumBins = 50;
0217 double pBinsLog[kNumBins + 1] = {0.};
0218 this->equidistLogBins(pBinsLog, kNumBins, 1., 4000.);
0219
0220
0221 hists.Add(fd.make<TH1F>("pathEnd", "path until cylinder;s [cm]", 100, 0., 2000.));
0222 hists.Add(fd.make<TH1F>("momEnd", "|p_{end}|;p [GeV]", 100, 0., 1000.));
0223 hists.Add(fd.make<TH1F>("momEndLog", "|p_{end}|;p [GeV]", kNumBins, pBinsLog));
0224 hists.Add(fd.make<TH1F>("ptEnd", "p_{t} (end);p_{t} [GeV]", 100, 0., 750.));
0225 hists.Add(fd.make<TH1F>("ptEndLog", "p_{t} (end);p_{t} [GeV]", kNumBins, pBinsLog));
0226 hists.Add(fd.make<TH1F>("phiXzEnd", "#phi_{xz} (end);#phi_{xz}", 100, -TMath::Pi(), TMath::Pi()));
0227 hists.Add(fd.make<TH1F>("thetaYEnd", "#theta_{y} (end);#theta_{y}", 100, 0., TMath::Pi()));
0228
0229 hists.Add(fd.make<TH1F>("momStartEnd", "|p_{start}|-|p_{end}|;#Deltap [GeV]", 100, 0., 15.));
0230 hists.Add(fd.make<TH1F>("momStartEndRel", "(p_{start}-p_{end})/p_{start};#Deltap_{rel}", 100, .0, 1.));
0231 hists.Add(fd.make<TH1F>("phiXzStartEnd", "#phi_{xz,start}-#phi_{xz,end};#Delta#phi_{xz}", 100, -1., 1.));
0232 hists.Add(fd.make<TH1F>("thetaYStartEnd", "#theta_{y,start}-#theta_{y,end};#Delta#theta_{y}", 100, -1., 1.));
0233
0234 hists.Add(fd.make<TH2F>("phiXzStartVsEnd",
0235 "#phi_{xz} start vs end;#phi_{xz}^{end};#phi_{xz}^{start}",
0236 50,
0237 -TMath::Pi(),
0238 TMath::Pi(),
0239 50,
0240 -TMath::Pi(),
0241 TMath::Pi()));
0242 hists.Add(fd.make<TH2F>("thetaYStartVsEnd",
0243 "#theta_{y} start vs end;#theta_{y}^{end};#theta_{y}^{start}",
0244 50,
0245 0.,
0246 TMath::Pi(),
0247 50,
0248 0.,
0249 TMath::Pi() / 2.));
0250
0251 hists.Add(fd.make<TH2F>("momStartEndRelVsZ",
0252 "(p_{start}-p_{end})/p_{start} vs z_{start};z [cm];#Deltap_{rel}",
0253 50,
0254 -1600.,
0255 1600.,
0256 50,
0257 .0,
0258 .8));
0259 hists.Add(fd.make<TH2F>("phiXzStartEndVsZ",
0260 "#phi_{xz,start}-#phi_{xz,end} vs z_{start};z [cm];#Delta#phi_{xz}",
0261 50,
0262 -1600.,
0263 1600.,
0264 50,
0265 -1.,
0266 1.));
0267 hists.Add(fd.make<TH2F>("thetaYStartEndVsZ",
0268 "#theta_{y,start}-#theta_{y,end} vs z_{start};z [cm];#Delta#theta_{y}",
0269 50,
0270 -1600.,
0271 1600.,
0272 50,
0273 -.5,
0274 .5));
0275 hists.Add(fd.make<TH2F>("momStartEndRelVsP",
0276 "(p_{start}-p_{end})/p_{start} vs p_{start};p [GeV];#Deltap_{rel}",
0277 kNumBins,
0278 pBinsLog,
0279 50,
0280 .0,
0281 .8));
0282 hists.Add(fd.make<TH2F>("phiXzStartEndVsP",
0283 "#phi_{xz,start}-#phi_{xz,end} vs |p|_{start};p [GeV];#Delta#phi_{xz}",
0284 kNumBins,
0285 pBinsLog,
0286 100,
0287 -1.5,
0288 1.5));
0289 hists.Add(fd.make<TH2F>("thetaYStartEndVsP",
0290 "#theta_{y,start}-#theta_{y,end} vs |p|_{start};p [GeV];#Delta#theta_{y}",
0291 kNumBins,
0292 pBinsLog,
0293 100,
0294 -1.,
0295 1.));
0296
0297 const double maxR = theTargetCylinder->radius() * 1.1;
0298 hists.Add(fd.make<TH1F>("radiusEnd", "end radius;r [cm]", 100, 0., maxR));
0299 double minZ = theTargetPlaneMin->position().z();
0300 minZ -= TMath::Abs(minZ) * 0.1;
0301 double maxZ = theTargetPlaneMax->position().z();
0302 maxZ += TMath::Abs(maxZ) * 0.1;
0303 hists.Add(fd.make<TH1F>("zEnd", "end z;z [cm]", 100, minZ, maxZ));
0304 hists.Add(fd.make<TH1F>("zDiff", "z_{start}-z_{end};#Deltaz [cm]", 100, -1000., 1000.));
0305 hists.Add(fd.make<TH2F>("xyPlaneEnd", "end xy;x [cm];y [cm]", 100, -maxR, maxR, 100, -maxR, maxR));
0306
0307 hists.Add(fd.make<TH2F>(
0308 "rzPlaneEnd", "end rz (y<0 #Rightarrow r_{#pm}=-r);z [cm];r_{#pm} [cm]", 50, minZ, maxZ, 50, -maxR, maxR));
0309 hists.Add(fd.make<TH2F>("thetaVsZend", "#theta vs z (end);z [cm];#theta", 50, minZ, maxZ, 50, 0., TMath::Pi()));
0310 }
0311
0312
0313 void CosmicGenFilterHelix::endJob() {
0314 const char *border = "////////////////////////////////////////////////////////";
0315 const char *line = "\n// ";
0316 edm::LogInfo("Filter") << "@SUB=CosmicGenFilterHelix::endJob" << border << line << theNumPass << " events out of "
0317 << theNumTotal << ", i.e. " << theNumPass * 100. / theNumTotal << "%, "
0318 << "reached target cylinder," << line << "defined by r < " << theTargetCylinder->radius()
0319 << " cm and " << theTargetPlaneMin->position().z() << " < z < "
0320 << theTargetPlaneMax->position().z() << " cm." << line
0321 << "Minimal required (transverse) momentum was " << TMath::Sqrt(theMinP2) << " ("
0322 << TMath::Sqrt(theMinPt2) << ") GeV."
0323 << "\n"
0324 << border;
0325 }
0326
0327
0328 bool CosmicGenFilterHelix::charge(int id, int &charge) const {
0329 std::vector<int>::const_iterator iC = theCharges.begin();
0330 for (std::vector<int>::const_iterator i = theIds.begin(), end = theIds.end(); i != end; ++i, ++iC) {
0331 if (*i == id) {
0332 charge = *iC;
0333 return true;
0334 }
0335 }
0336
0337 return false;
0338 }
0339
0340
0341 const MagneticField *CosmicGenFilterHelix::getMagneticField(const edm::EventSetup &setup) const {
0342 return &setup.getData(theMFToken);
0343 }
0344
0345
0346 const Propagator *CosmicGenFilterHelix::getPropagator(const edm::EventSetup &setup) const {
0347 const Propagator *prop = &setup.getData(thePropToken);
0348 if (!dynamic_cast<const SteppingHelixPropagator *>(prop)) {
0349 edm::LogWarning("BadConfig") << "@SUB=CosmicGenFilterHelix::getPropagator"
0350 << "Not a SteppingHelixPropagator!";
0351 }
0352 return prop;
0353 }
0354
0355
0356 void CosmicGenFilterHelix::monitorStart(const GlobalPoint &vert, const GlobalVector &mom, int charge, TObjArray &hists) {
0357 const double scalarMom = mom.mag();
0358 const double phi = mom.phi();
0359 const double phiXz = TMath::ATan2(mom.z(), mom.x());
0360 const double theta = mom.theta();
0361 const double thetaY = TMath::ATan2(TMath::Sqrt(mom.x() * mom.x() + mom.z() * mom.z()), -mom.y());
0362
0363 const double z = vert.z();
0364 const double r = vert.perp();
0365
0366 const static int iMomP = hists.IndexOf(hists.FindObject("momentumP"));
0367 const static int iMomM = hists.IndexOf(hists.FindObject("momentumM"));
0368 if (charge > 0)
0369 static_cast<TH1 *>(hists[iMomP])->Fill(scalarMom);
0370 else
0371 static_cast<TH1 *>(hists[iMomM])->Fill(scalarMom);
0372 const static int iMom2 = hists.IndexOf(hists.FindObject("momentum2"));
0373 static_cast<TH1 *>(hists[iMom2])->Fill(scalarMom);
0374 const static int iMomLog = hists.IndexOf(hists.FindObject("momentumLog"));
0375 static_cast<TH1 *>(hists[iMomLog])->Fill(scalarMom);
0376 const static int iPhi = hists.IndexOf(hists.FindObject("phi"));
0377 static_cast<TH1 *>(hists[iPhi])->Fill(phi);
0378 const static int iCosPhi = hists.IndexOf(hists.FindObject("cosPhi"));
0379 static_cast<TH1 *>(hists[iCosPhi])->Fill(TMath::Cos(phi));
0380 const static int iPhiXz = hists.IndexOf(hists.FindObject("phiXz"));
0381 static_cast<TH1 *>(hists[iPhiXz])->Fill(phiXz);
0382 const static int iTheta = hists.IndexOf(hists.FindObject("theta"));
0383 static_cast<TH1 *>(hists[iTheta])->Fill(theta);
0384 const static int iThetaY = hists.IndexOf(hists.FindObject("thetaY"));
0385 static_cast<TH1 *>(hists[iThetaY])->Fill(thetaY);
0386
0387 const static int iMomVsTheta = hists.IndexOf(hists.FindObject("momVsTheta"));
0388 static_cast<TH2 *>(hists[iMomVsTheta])->Fill(theta, scalarMom);
0389 const static int iMomVsThetaY = hists.IndexOf(hists.FindObject("momVsThetaY"));
0390 static_cast<TH2 *>(hists[iMomVsThetaY])->Fill(thetaY, scalarMom);
0391 const static int iMomVsPhi = hists.IndexOf(hists.FindObject("momVsPhi"));
0392 static_cast<TH2 *>(hists[iMomVsPhi])->Fill(phi, scalarMom);
0393 const static int iMomVsZ = hists.IndexOf(hists.FindObject("momVsZ"));
0394 static_cast<TH2 *>(hists[iMomVsZ])->Fill(z, scalarMom);
0395 const static int iThetaVsZ = hists.IndexOf(hists.FindObject("thetaVsZ"));
0396 static_cast<TH2 *>(hists[iThetaVsZ])->Fill(z, theta);
0397 const static int iThetaYvsZ = hists.IndexOf(hists.FindObject("thetaYvsZ"));
0398 static_cast<TH2 *>(hists[iThetaYvsZ])->Fill(z, thetaY);
0399 const static int iYvsThetaY = hists.IndexOf(hists.FindObject("yVsThetaY"));
0400 static_cast<TH2 *>(hists[iYvsThetaY])->Fill(thetaY, vert.y());
0401 const static int iYvsThetaYnoR = hists.IndexOf(hists.FindObject("yVsThetaYnoR"));
0402 if (z > -1400. && z < 1400.) {
0403 static_cast<TH2 *>(hists[iYvsThetaYnoR])->Fill(thetaY, vert.y());
0404 }
0405
0406 const static int iRadius = hists.IndexOf(hists.FindObject("radius"));
0407 static_cast<TH1 *>(hists[iRadius])->Fill(r);
0408 const static int iZ = hists.IndexOf(hists.FindObject("z"));
0409 static_cast<TH1 *>(hists[iZ])->Fill(z);
0410 const static int iXy = hists.IndexOf(hists.FindObject("xyPlane"));
0411 static_cast<TH1 *>(hists[iXy])->Fill(vert.x(), vert.y());
0412 const static int iRz = hists.IndexOf(hists.FindObject("rzPlane"));
0413 static_cast<TH1 *>(hists[iRz])->Fill(z, (vert.y() > 0 ? r : -r));
0414 }
0415
0416
0417 void CosmicGenFilterHelix::monitorEnd(const GlobalPoint &endVert,
0418 const GlobalVector &endMom,
0419 const GlobalPoint &vert,
0420 const GlobalVector &mom,
0421 double path,
0422 TObjArray &hists) {
0423 const double scalarMomStart = mom.mag();
0424 const double phiXzStart = TMath::ATan2(mom.z(), mom.x());
0425 const double thetaYStart = TMath::ATan2(TMath::Sqrt(mom.x() * mom.x() + mom.z() * mom.z()), -mom.y());
0426 const double scalarMomEnd = endMom.mag();
0427 const double ptEnd = endMom.perp();
0428 const double phiXzEnd = TMath::ATan2(endMom.z(), endMom.x());
0429 const double thetaYEnd = TMath::ATan2(TMath::Sqrt(endMom.x() * endMom.x() + endMom.z() * endMom.z()), -endMom.y());
0430 const double thetaEnd = endMom.theta();
0431
0432 const double diffMomRel = (scalarMomStart - scalarMomEnd) / scalarMomStart;
0433
0434 const double zEnd = endVert.z();
0435 const double rEnd = endVert.perp();
0436 const double diffZ = zEnd - vert.z();
0437
0438 const static int iPathEnd = hists.IndexOf(hists.FindObject("pathEnd"));
0439 static_cast<TH1 *>(hists[iPathEnd])->Fill(path);
0440 const static int iMomEnd = hists.IndexOf(hists.FindObject("momEnd"));
0441 static_cast<TH1 *>(hists[iMomEnd])->Fill(scalarMomEnd);
0442 const static int iMomEndLog = hists.IndexOf(hists.FindObject("momEndLog"));
0443 static_cast<TH1 *>(hists[iMomEndLog])->Fill(scalarMomEnd);
0444 const static int iPtEnd = hists.IndexOf(hists.FindObject("ptEnd"));
0445 static_cast<TH1 *>(hists[iPtEnd])->Fill(ptEnd);
0446 const static int iPtEndLog = hists.IndexOf(hists.FindObject("ptEndLog"));
0447 static_cast<TH1 *>(hists[iPtEndLog])->Fill(ptEnd);
0448 const static int iPhiXzEnd = hists.IndexOf(hists.FindObject("phiXzEnd"));
0449 static_cast<TH1 *>(hists[iPhiXzEnd])->Fill(phiXzEnd);
0450 const static int iThetaYEnd = hists.IndexOf(hists.FindObject("thetaYEnd"));
0451 static_cast<TH1 *>(hists[iThetaYEnd])->Fill(thetaYEnd);
0452
0453 const static int iMomStartEnd = hists.IndexOf(hists.FindObject("momStartEnd"));
0454 static_cast<TH1 *>(hists[iMomStartEnd])->Fill(scalarMomStart - scalarMomEnd);
0455 const static int iMomStartEndRel = hists.IndexOf(hists.FindObject("momStartEndRel"));
0456 static_cast<TH1 *>(hists[iMomStartEndRel])->Fill(diffMomRel);
0457 const static int iPhiStartEnd = hists.IndexOf(hists.FindObject("phiXzStartEnd"));
0458 static_cast<TH1 *>(hists[iPhiStartEnd])->Fill(phiXzStart - phiXzEnd);
0459 const static int iThetaStartEnd = hists.IndexOf(hists.FindObject("thetaYStartEnd"));
0460 static_cast<TH1 *>(hists[iThetaStartEnd])->Fill(thetaYStart - thetaYEnd);
0461
0462 const static int iPhiStartVsEnd = hists.IndexOf(hists.FindObject("phiXzStartVsEnd"));
0463 static_cast<TH2 *>(hists[iPhiStartVsEnd])->Fill(phiXzEnd, phiXzStart);
0464 const static int iThetaStartVsEnd = hists.IndexOf(hists.FindObject("thetaYStartVsEnd"));
0465 static_cast<TH2 *>(hists[iThetaStartVsEnd])->Fill(thetaYEnd, thetaYStart);
0466
0467 const static int iMomStartEndRelVsZ = hists.IndexOf(hists.FindObject("momStartEndRelVsZ"));
0468 static_cast<TH2 *>(hists[iMomStartEndRelVsZ])->Fill(vert.z(), diffMomRel);
0469 const static int iPhiStartEndVsZ = hists.IndexOf(hists.FindObject("phiXzStartEndVsZ"));
0470 static_cast<TH2 *>(hists[iPhiStartEndVsZ])->Fill(vert.z(), phiXzStart - phiXzEnd);
0471 const static int iThetaStartEndVsZ = hists.IndexOf(hists.FindObject("thetaYStartEndVsZ"));
0472 static_cast<TH2 *>(hists[iThetaStartEndVsZ])->Fill(vert.z(), thetaYStart - thetaYEnd);
0473 const static int iMomStartEndRelVsP = hists.IndexOf(hists.FindObject("momStartEndRelVsP"));
0474 static_cast<TH2 *>(hists[iMomStartEndRelVsP])->Fill(scalarMomStart, diffMomRel);
0475 const static int iPhiStartEndVsP = hists.IndexOf(hists.FindObject("phiXzStartEndVsP"));
0476 static_cast<TH2 *>(hists[iPhiStartEndVsP])->Fill(scalarMomStart, phiXzStart - phiXzEnd);
0477 const static int iThetaStartEndVsP = hists.IndexOf(hists.FindObject("thetaYStartEndVsP"));
0478 static_cast<TH2 *>(hists[iThetaStartEndVsP])->Fill(scalarMomStart, thetaYStart - thetaYEnd);
0479
0480 const static int iRadiusEnd = hists.IndexOf(hists.FindObject("radiusEnd"));
0481 static_cast<TH1 *>(hists[iRadiusEnd])->Fill(rEnd);
0482 const static int iZend = hists.IndexOf(hists.FindObject("zEnd"));
0483 static_cast<TH1 *>(hists[iZend])->Fill(zEnd);
0484 const static int iZdiff = hists.IndexOf(hists.FindObject("zDiff"));
0485 static_cast<TH1 *>(hists[iZdiff])->Fill(diffZ);
0486 const static int iXyPlaneEnd = hists.IndexOf(hists.FindObject("xyPlaneEnd"));
0487 static_cast<TH1 *>(hists[iXyPlaneEnd])->Fill(endVert.x(), endVert.y());
0488 const static int iRzPlaneEnd = hists.IndexOf(hists.FindObject("rzPlaneEnd"));
0489 static_cast<TH1 *>(hists[iRzPlaneEnd])->Fill(zEnd, (endVert.y() > 0 ? rEnd : -rEnd));
0490 const static int iThetaVsZend = hists.IndexOf(hists.FindObject("thetaVsZend"));
0491 static_cast<TH2 *>(hists[iThetaVsZend])->Fill(zEnd, thetaEnd);
0492 }
0493
0494
0495 bool CosmicGenFilterHelix::equidistLogBins(double *bins, int nBins, double first, double last) const {
0496
0497
0498
0499
0500
0501 if (nBins < 1 || first <= 0. || last <= 0.)
0502 return false;
0503
0504 bins[0] = first;
0505 bins[nBins] = last;
0506 const double firstLog = TMath::Log10(bins[0]);
0507 const double lastLog = TMath::Log10(bins[nBins]);
0508 for (int i = 1; i < nBins; ++i) {
0509 bins[i] = TMath::Power(10., firstLog + i * (lastLog - firstLog) / (nBins));
0510 }
0511
0512 return true;
0513 }