00001
00002
00003
00004
00005
00006
00007 #include "GeneratorInterface/GenFilters/interface/CosmicGenFilterHelix.h"
00008
00009
00010 #include "FWCore/Framework/interface/ESHandle.h"
00011 #include "DataFormats/Common/interface/Handle.h"
00012
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014
00015 #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
00016
00017 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00018
00019 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixPropagator.h"
00020 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00021
00022 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00023 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00024 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
00025
00026
00027 #include "CommonTools/UtilAlgos/interface/TFileService.h"
00028 #include "CommonTools/Utils/interface/TFileDirectory.h"
00029 #include "FWCore/ServiceRegistry/interface/Service.h"
00030
00031 #include <TMath.h>
00032 #include <TH1.h>
00033 #include <TH2.h>
00034
00035 #include <utility>
00036 #include <string>
00037
00038
00039
00040
00041
00042
00044 CosmicGenFilterHelix::CosmicGenFilterHelix(const edm::ParameterSet& cfg)
00045 : theSrc(cfg.getParameter<edm::InputTag>("src")),
00046 theIds(cfg.getParameter<std::vector<int> >("pdgIds")),
00047 theCharges(cfg.getParameter<std::vector<int> >("charges")),
00048 thePropagatorName(cfg.getParameter<std::string>("propagator")),
00049 theMinP2(cfg.getParameter<double>("minP")*cfg.getParameter<double>("minP")),
00050 theMinPt2(cfg.getParameter<double>("minPt")*cfg.getParameter<double>("minPt")),
00051 theDoMonitor(cfg.getUntrackedParameter<bool>("doMonitor"))
00052 {
00053 if (theIds.size() != theCharges.size()) {
00054 throw cms::Exception("BadConfig") << "CosmicGenFilterHelix: "
00055 << "'pdgIds' and 'charges' need same length.";
00056 }
00057 Surface::Scalar radius = cfg.getParameter<double>("radius");
00058 Surface::Scalar maxZ = cfg.getParameter<double>("maxZ");
00059 Surface::Scalar minZ = cfg.getParameter<double>("minZ");
00060
00061 if (maxZ < minZ) {
00062 throw cms::Exception("BadConfig") << "CosmicGenFilterHelix: maxZ (" << maxZ
00063 << ") smaller than minZ (" << minZ << ").";
00064 }
00065
00066 const Surface::RotationType dummyRot;
00067 theTargetCylinder = Cylinder::build(Surface::PositionType(0.,0.,0.), dummyRot, radius);
00068 theTargetPlaneMin = Plane::build(Surface::PositionType(0.,0.,minZ), dummyRot);
00069 theTargetPlaneMax = Plane::build(Surface::PositionType(0.,0.,maxZ), dummyRot);
00070 }
00071
00073 CosmicGenFilterHelix::~CosmicGenFilterHelix()
00074 {
00075 }
00076
00077
00078
00079
00080
00081
00083 bool CosmicGenFilterHelix::filter(edm::Event &iEvent, const edm::EventSetup &iSetup)
00084 {
00085 edm::Handle<edm::HepMCProduct> hepMCEvt;
00086 iEvent.getByLabel(theSrc, hepMCEvt);
00087 const HepMC::GenEvent *mCEvt = hepMCEvt->GetEvent();
00088 const MagneticField *bField = this->getMagneticField(iSetup);
00089 const Propagator *propagator = this->getPropagator(iSetup);
00090
00091 ++theNumTotal;
00092 bool result = false;
00093 for (HepMC::GenEvent::particle_const_iterator iPart = mCEvt->particles_begin(),
00094 endPart = mCEvt->particles_end(); iPart != endPart; ++iPart) {
00095 int charge = 0;
00096 if ((*iPart)->status() != 1) continue;
00097 if (!this->charge((*iPart)->pdg_id(), charge)) continue;
00098
00099
00100 const HepMC::ThreeVector hepVertex((*iPart)->production_vertex()->point3d());
00101 const GlobalPoint vert(hepVertex.x()/10., hepVertex.y()/10., hepVertex.z()/10.);
00102 const HepMC::FourVector hepMomentum((*iPart)->momentum());
00103 const GlobalVector mom(hepMomentum.x(), hepMomentum.y(), hepMomentum.z());
00104
00105 if (theDoMonitor) this->monitorStart(vert, mom, charge, theHistsBefore);
00106
00107 if (this->propagateToCutCylinder(vert, mom, charge, bField, propagator)) {
00108 result = true;
00109 }
00110 }
00111
00112 if (result) ++theNumPass;
00113 return result;
00114 }
00115
00116
00117 bool CosmicGenFilterHelix::propagateToCutCylinder(const GlobalPoint &vertStart,
00118 const GlobalVector &momStart,
00119 int charge, const MagneticField *field,
00120 const Propagator *propagator)
00121 {
00122 typedef std::pair<TrajectoryStateOnSurface, double> TsosPath;
00123
00124 const FreeTrajectoryState fts(GlobalTrajectoryParameters(vertStart, momStart, charge, field));
00125
00126 bool result = true;
00127 TsosPath aTsosPath(propagator->propagateWithPath(fts, *theTargetCylinder));
00128 if (!aTsosPath.first.isValid()) {
00129 result = false;
00130 } else if (aTsosPath.first.globalPosition().z() < theTargetPlaneMin->position().z()) {
00131
00132
00133
00134 aTsosPath = propagator->propagateWithPath(fts, *theTargetPlaneMin);
00135 if (!aTsosPath.first.isValid()
00136 || aTsosPath.first.globalPosition().perp() > theTargetCylinder->radius()) {
00137 result = false;
00138 }
00139 } else if (aTsosPath.first.globalPosition().z() > theTargetPlaneMax->position().z()) {
00140
00141 aTsosPath = propagator->propagateWithPath(fts, *theTargetPlaneMax);
00142 if (!aTsosPath.first.isValid()
00143 || aTsosPath.first.globalPosition().perp() > theTargetCylinder->radius()) {
00144 result = false;
00145 }
00146 }
00147
00148 if (result) {
00149 const GlobalVector momEnd(aTsosPath.first.globalMomentum());
00150 if (momEnd.perp2() < theMinPt2 || momEnd.mag2() < theMinP2) {
00151 result = false;
00152 } else if (theDoMonitor) {
00153 const GlobalPoint vertEnd(aTsosPath.first.globalPosition());
00154 this->monitorStart(vertStart, momStart, charge, theHistsAfter);
00155 this->monitorEnd(vertEnd, momEnd, vertStart, momStart, aTsosPath.second, theHistsAfter);
00156 }
00157 }
00158
00159 return result;
00160 }
00161
00162
00163
00164 void CosmicGenFilterHelix::beginJob()
00165 {
00166 if (theDoMonitor) {
00167 this->createHistsStart("start", theHistsBefore);
00168 this->createHistsStart("startAfter", theHistsAfter);
00169
00170 this->createHistsEnd("end", theHistsAfter);
00171 }
00172
00173 theNumTotal = theNumPass = 0;
00174 }
00175
00177 void CosmicGenFilterHelix::createHistsStart(const char *dirName, TObjArray &hists)
00178 {
00179 edm::Service<TFileService> fs;
00180 TFileDirectory fd(fs->mkdir(dirName, dirName));
00181
00182 hists.Add(fd.make<TH1F>("momentumP", "|p(#mu^{+})| (start);|p| [GeV]",100, 0., 1000.));
00183 hists.Add(fd.make<TH1F>("momentumM", "|p(#mu^{-})| (start);|p| [GeV]",100, 0., 1000.));
00184 hists.Add(fd.make<TH1F>("momentum2", "|p(#mu)| (start);|p| [GeV]",100, 0., 25.));
00185 const int kNumBins = 50;
00186 double pBinsLog[kNumBins+1] = {0.};
00187 this->equidistLogBins(pBinsLog, kNumBins, 1., 4000.);
00188 hists.Add(fd.make<TH1F>("momentumLog", "|p(#mu)| (start);|p| [GeV]", kNumBins, pBinsLog));
00189 hists.Add(fd.make<TH1F>("phi", "start p_{#phi(#mu)};#phi", 100, -TMath::Pi(), TMath::Pi()));
00190 hists.Add(fd.make<TH1F>("cosPhi", "cos(p_{#phi(#mu)}) (start);cos(#phi)", 100, -1., 1.));
00191 hists.Add(fd.make<TH1F>("phiXz", "start p_{#phi_{xz}(#mu)};#phi_{xz}",
00192 100, -TMath::Pi(), TMath::Pi()));
00193 hists.Add(fd.make<TH1F>("theta", "#theta(#mu) (start);#theta", 100, 0., TMath::Pi()));
00194 hists.Add(fd.make<TH1F>("thetaY", "#theta_{y}(#mu) (start);#theta_{y}", 100,0.,TMath::Pi()/2.));
00195
00196 hists.Add(fd.make<TH2F>("momVsPhi", "|p(#mu)| vs #phi (start);#phi;|p| [GeV]",
00197 50, -TMath::Pi(), TMath::Pi(), 50, 1.5, 1000.));
00198 hists.Add(fd.make<TH2F>("momVsTheta", "|p(#mu)| vs #theta (start);#theta;|p| [GeV]",
00199 50, 0., TMath::Pi(), 50, 1.5, 1000.));
00200 hists.Add(fd.make<TH2F>("momVsThetaY", "|p(#mu)| vs #theta_{y} (start);#theta_{y};|p| [GeV]",
00201 50, 0., TMath::Pi()/2., 50, 1.5, 1000.));
00202 hists.Add(fd.make<TH2F>("momVsZ", "|p(#mu)| vs z (start);z [cm];|p| [GeV]",
00203 50, -1600., 1600., 50, 1.5, 1000.));
00204 hists.Add(fd.make<TH2F>("thetaVsZ", "#theta vs z (start);z [cm];#theta",
00205 50, -1600., 1600., 50, 0., TMath::Pi()));
00206 hists.Add(fd.make<TH2F>("thetaYvsZ", "#theta_{y} vs z (start);z [cm];#theta",
00207 50, -1600., 1600., 50, 0., TMath::PiOver2()));
00208 hists.Add(fd.make<TH2F>("yVsThetaY", "#theta_{y}(#mu) vs y (start);#theta_{y};y [cm]",
00209 50, 0., TMath::Pi()/2., 50, -1000., 1000.));
00210 hists.Add(fd.make<TH2F>("yVsThetaYnoR", "#theta_{y}(#mu) vs y (start, barrel);#theta_{y};y [cm]",
00211 50, 0., TMath::Pi()/2., 50, -1000., 1000.));
00212
00213 hists.Add(fd.make<TH1F>("radius", "start radius;r [cm]", 100, 0., 1000.));
00214 hists.Add(fd.make<TH1F>("z", "start z;z [cm]", 100, -1600., 1600.));
00215 hists.Add(fd.make<TH2F>("xyPlane", "start xy;x [cm];y [cm]", 50, -1000., 1000.,
00216 50, -1000., 1000.));
00217 hists.Add(fd.make<TH2F>("rzPlane",
00218 "start rz (y < 0 #Rightarrow r_{#pm} = -r);z [cm];r_{#pm} [cm]",
00219 50, -1600., 1600., 50, -1000., 1000.));
00220 }
00221
00223 void CosmicGenFilterHelix::createHistsEnd(const char *dirName, TObjArray &hists)
00224 {
00225 edm::Service<TFileService> fs;
00226 TFileDirectory fd(fs->mkdir(dirName, dirName));
00227
00228 const int kNumBins = 50;
00229 double pBinsLog[kNumBins+1] = {0.};
00230 this->equidistLogBins(pBinsLog, kNumBins, 1., 4000.);
00231
00232
00233 hists.Add(fd.make<TH1F>("pathEnd", "path until cylinder;s [cm]", 100, 0., 2000.));
00234 hists.Add(fd.make<TH1F>("momEnd", "|p_{end}|;p [GeV]", 100, 0., 1000.));
00235 hists.Add(fd.make<TH1F>("momEndLog", "|p_{end}|;p [GeV]", kNumBins, pBinsLog));
00236 hists.Add(fd.make<TH1F>("ptEnd", "p_{t} (end);p_{t} [GeV]", 100, 0., 750.));
00237 hists.Add(fd.make<TH1F>("ptEndLog", "p_{t} (end);p_{t} [GeV]", kNumBins, pBinsLog));
00238 hists.Add(fd.make<TH1F>("phiXzEnd", "#phi_{xz} (end);#phi_{xz}", 100,-TMath::Pi(),TMath::Pi()));
00239 hists.Add(fd.make<TH1F>("thetaYEnd","#theta_{y} (end);#theta_{y}", 100, 0., TMath::Pi()));
00240
00241 hists.Add(fd.make<TH1F>("momStartEnd", "|p_{start}|-|p_{end}|;#Deltap [GeV]",100,0.,15.));
00242 hists.Add(fd.make<TH1F>("momStartEndRel", "(p_{start}-p_{end})/p_{start};#Deltap_{rel}",
00243 100,.0,1.));
00244 hists.Add(fd.make<TH1F>("phiXzStartEnd", "#phi_{xz,start}-#phi_{xz,end};#Delta#phi_{xz}",
00245 100,-1.,1.));
00246 hists.Add(fd.make<TH1F>("thetaYStartEnd","#theta_{y,start}-#theta_{y,end};#Delta#theta_{y}",
00247 100,-1.,1.));
00248
00249 hists.Add(fd.make<TH2F>("phiXzStartVsEnd",
00250 "#phi_{xz} start vs end;#phi_{xz}^{end};#phi_{xz}^{start}",
00251 50, -TMath::Pi(), TMath::Pi(), 50, -TMath::Pi(), TMath::Pi()));
00252 hists.Add(fd.make<TH2F>("thetaYStartVsEnd",
00253 "#theta_{y} start vs end;#theta_{y}^{end};#theta_{y}^{start}",
00254 50, 0., TMath::Pi(), 50, 0., TMath::Pi()/2.));
00255
00256 hists.Add(fd.make<TH2F>("momStartEndRelVsZ",
00257 "(p_{start}-p_{end})/p_{start} vs z_{start};z [cm];#Deltap_{rel}",
00258 50, -1600., 1600., 50,.0,.8));
00259 hists.Add(fd.make<TH2F>("phiXzStartEndVsZ",
00260 "#phi_{xz,start}-#phi_{xz,end} vs z_{start};z [cm];#Delta#phi_{xz}",
00261 50, -1600., 1600., 50,-1., 1.));
00262 hists.Add(fd.make<TH2F>("thetaYStartEndVsZ",
00263 "#theta_{y,start}-#theta_{y,end} vs z_{start};z [cm];#Delta#theta_{y}",
00264 50, -1600., 1600., 50,-.5,.5));
00265 hists.Add(fd.make<TH2F>("momStartEndRelVsP",
00266 "(p_{start}-p_{end})/p_{start} vs p_{start};p [GeV];#Deltap_{rel}",
00267 kNumBins, pBinsLog, 50, .0, .8));
00268 hists.Add(fd.make<TH2F>("phiXzStartEndVsP",
00269 "#phi_{xz,start}-#phi_{xz,end} vs |p|_{start};p [GeV];#Delta#phi_{xz}",
00270 kNumBins, pBinsLog, 100,-1.5, 1.5));
00271 hists.Add(fd.make<TH2F>("thetaYStartEndVsP",
00272 "#theta_{y,start}-#theta_{y,end} vs |p|_{start};p [GeV];#Delta#theta_{y}",
00273 kNumBins, pBinsLog, 100,-1.,1.));
00274
00275 const double maxR = theTargetCylinder->radius() * 1.1;
00276 hists.Add(fd.make<TH1F>("radiusEnd", "end radius;r [cm]", 100, 0., maxR));
00277 double minZ = theTargetPlaneMin->position().z();
00278 minZ -= TMath::Abs(minZ) * 0.1;
00279 double maxZ = theTargetPlaneMax->position().z();
00280 maxZ += TMath::Abs(maxZ) * 0.1;
00281 hists.Add(fd.make<TH1F>("zEnd", "end z;z [cm]", 100, minZ, maxZ));
00282 hists.Add(fd.make<TH1F>("zDiff", "z_{start}-z_{end};#Deltaz [cm]", 100, -1000., 1000.));
00283 hists.Add(fd.make<TH2F>("xyPlaneEnd", "end xy;x [cm];y [cm]", 100, -maxR, maxR, 100,-maxR,maxR));
00284
00285 hists.Add(fd.make<TH2F>("rzPlaneEnd", "end rz (y<0 #Rightarrow r_{#pm}=-r);z [cm];r_{#pm} [cm]",
00286 50, minZ, maxZ, 50, -maxR, maxR));
00287 hists.Add(fd.make<TH2F>("thetaVsZend", "#theta vs z (end);z [cm];#theta",
00288 50, minZ, maxZ, 50, 0., TMath::Pi()));
00289 }
00290
00291
00292 void CosmicGenFilterHelix::endJob()
00293 {
00294 const char *border = "////////////////////////////////////////////////////////";
00295 const char *line = "\n// ";
00296 edm::LogInfo("Filter") << "@SUB=CosmicGenFilterHelix::endJob"
00297 << border << line
00298 << theNumPass << " events out of " << theNumTotal
00299 << ", i.e. " << theNumPass*100./theNumTotal << "%, "
00300 << "reached target cylinder,"
00301 << line << "defined by r < "
00302 << theTargetCylinder->radius() << " cm and "
00303 << theTargetPlaneMin->position().z() << " < z < "
00304 << theTargetPlaneMax->position().z() << " cm."
00305 << line << "Minimal required (transverse) momentum was "
00306 << TMath::Sqrt(theMinP2) << " (" << TMath::Sqrt(theMinPt2) << ") GeV."
00307 << "\n" << border;
00308 }
00309
00311 bool CosmicGenFilterHelix::charge(int id, int &charge) const
00312 {
00313 std::vector<int>::const_iterator iC = theCharges.begin();
00314 for (std::vector<int>::const_iterator i = theIds.begin(), end = theIds.end(); i != end;
00315 ++i,++iC) {
00316 if (*i == id) {
00317 charge = *iC;
00318 return true;
00319 }
00320 }
00321
00322 return false;
00323 }
00324
00325
00326 const MagneticField* CosmicGenFilterHelix::getMagneticField(const edm::EventSetup &setup) const
00327 {
00328 edm::ESHandle<MagneticField> fieldHandle;
00329 setup.get<IdealMagneticFieldRecord>().get(fieldHandle);
00330
00331 return fieldHandle.product();
00332 }
00333
00334
00335 const Propagator* CosmicGenFilterHelix::getPropagator(const edm::EventSetup &setup) const
00336 {
00337 edm::ESHandle<Propagator> propHandle;
00338 setup.get<TrackingComponentsRecord>().get(thePropagatorName, propHandle);
00339
00340 const Propagator *prop = propHandle.product();
00341 if (!dynamic_cast<const SteppingHelixPropagator*>(prop)) {
00342 edm::LogWarning("BadConfig") << "@SUB=CosmicGenFilterHelix::getPropagator"
00343 << "Not a SteppingHelixPropagator!";
00344
00345 }
00346 return prop;
00347 }
00348
00349
00350 void CosmicGenFilterHelix::monitorStart(const GlobalPoint &vert, const GlobalVector &mom,
00351 int charge, TObjArray &hists)
00352 {
00353 const double scalarMom = mom.mag();
00354 const double phi = mom.phi();
00355 const double phiXz = TMath::ATan2(mom.z(), mom.x());
00356 const double theta = mom.theta();
00357 const double thetaY = TMath::ATan2(TMath::Sqrt(mom.x()*mom.x()+mom.z()*mom.z()), -mom.y());
00358
00359 const double z = vert.z();
00360 const double r = vert.perp();
00361
00362 static int iMomP = hists.IndexOf(hists.FindObject("momentumP"));
00363 static int iMomM = hists.IndexOf(hists.FindObject("momentumM"));
00364 if (charge > 0) static_cast<TH1*>(hists[iMomP])->Fill(scalarMom);
00365 else static_cast<TH1*>(hists[iMomM])->Fill(scalarMom);
00366 static int iMom2 = hists.IndexOf(hists.FindObject("momentum2"));
00367 static_cast<TH1*>(hists[iMom2])->Fill(scalarMom);
00368 static int iMomLog = hists.IndexOf(hists.FindObject("momentumLog"));
00369 static_cast<TH1*>(hists[iMomLog])->Fill(scalarMom);
00370 static int iPhi = hists.IndexOf(hists.FindObject("phi"));
00371 static_cast<TH1*>(hists[iPhi])->Fill(phi);
00372 static int iCosPhi = hists.IndexOf(hists.FindObject("cosPhi"));
00373 static_cast<TH1*>(hists[iCosPhi])->Fill(TMath::Cos(phi));
00374 static int iPhiXz = hists.IndexOf(hists.FindObject("phiXz"));
00375 static_cast<TH1*>(hists[iPhiXz])->Fill(phiXz);
00376 static int iTheta = hists.IndexOf(hists.FindObject("theta"));
00377 static_cast<TH1*>(hists[iTheta])->Fill(theta);
00378 static int iThetaY = hists.IndexOf(hists.FindObject("thetaY"));
00379 static_cast<TH1*>(hists[iThetaY])->Fill(thetaY);
00380
00381 static int iMomVsTheta = hists.IndexOf(hists.FindObject("momVsTheta"));
00382 static_cast<TH2*>(hists[iMomVsTheta])->Fill(theta, scalarMom);
00383 static int iMomVsThetaY = hists.IndexOf(hists.FindObject("momVsThetaY"));
00384 static_cast<TH2*>(hists[iMomVsThetaY])->Fill(thetaY, scalarMom);
00385 static int iMomVsPhi = hists.IndexOf(hists.FindObject("momVsPhi"));
00386 static_cast<TH2*>(hists[iMomVsPhi])->Fill(phi, scalarMom);
00387 static int iMomVsZ = hists.IndexOf(hists.FindObject("momVsZ"));
00388 static_cast<TH2*>(hists[iMomVsZ])->Fill(z, scalarMom);
00389 static int iThetaVsZ = hists.IndexOf(hists.FindObject("thetaVsZ"));
00390 static_cast<TH2*>(hists[iThetaVsZ])->Fill(z, theta);
00391 static int iThetaYvsZ = hists.IndexOf(hists.FindObject("thetaYvsZ"));
00392 static_cast<TH2*>(hists[iThetaYvsZ])->Fill(z, thetaY);
00393 static int iYvsThetaY = hists.IndexOf(hists.FindObject("yVsThetaY"));
00394 static_cast<TH2*>(hists[iYvsThetaY])->Fill(thetaY, vert.y());
00395 static int iYvsThetaYnoR = hists.IndexOf(hists.FindObject("yVsThetaYnoR"));
00396 if (z > -1400. && z < 1400.) {
00397 static_cast<TH2*>(hists[iYvsThetaYnoR])->Fill(thetaY, vert.y());
00398 }
00399
00400 static int iRadius = hists.IndexOf(hists.FindObject("radius"));
00401 static_cast<TH1*>(hists[iRadius])->Fill(r);
00402 static int iZ = hists.IndexOf(hists.FindObject("z"));
00403 static_cast<TH1*>(hists[iZ])->Fill(z);
00404 static int iXy = hists.IndexOf(hists.FindObject("xyPlane"));
00405 static_cast<TH1*>(hists[iXy])->Fill(vert.x(), vert.y());
00406 static int iRz = hists.IndexOf(hists.FindObject("rzPlane"));
00407 static_cast<TH1*>(hists[iRz])->Fill(z, (vert.y() > 0 ? r : -r));
00408 }
00409
00410
00411 void CosmicGenFilterHelix::monitorEnd(const GlobalPoint &endVert, const GlobalVector &endMom,
00412 const GlobalPoint &vert, const GlobalVector &mom,
00413 double path, TObjArray &hists)
00414 {
00415 const double scalarMomStart = mom.mag();
00416 const double phiXzStart = TMath::ATan2(mom.z(), mom.x());
00417 const double thetaYStart = TMath::ATan2(TMath::Sqrt(mom.x()*mom.x()+mom.z()*mom.z()), -mom.y());
00418 const double scalarMomEnd = endMom.mag();
00419 const double ptEnd = endMom.perp();
00420 const double phiXzEnd = TMath::ATan2(endMom.z(), endMom.x());
00421 const double thetaYEnd = TMath::ATan2(TMath::Sqrt(endMom.x()*endMom.x()+endMom.z()*endMom.z()),
00422 -endMom.y());
00423 const double thetaEnd = endMom.theta();
00424
00425 const double diffMomRel = (scalarMomStart-scalarMomEnd)/scalarMomStart;
00426
00427 const double zEnd = endVert.z();
00428 const double rEnd = endVert.perp();
00429 const double diffZ = zEnd - vert.z();
00430
00431 static int iPathEnd = hists.IndexOf(hists.FindObject("pathEnd"));
00432 static_cast<TH1*>(hists[iPathEnd])->Fill(path);
00433 static int iMomEnd = hists.IndexOf(hists.FindObject("momEnd"));
00434 static_cast<TH1*>(hists[iMomEnd])->Fill(scalarMomEnd);
00435 static int iMomEndLog = hists.IndexOf(hists.FindObject("momEndLog"));
00436 static_cast<TH1*>(hists[iMomEndLog])->Fill(scalarMomEnd);
00437 static int iPtEnd = hists.IndexOf(hists.FindObject("ptEnd"));
00438 static_cast<TH1*>(hists[iPtEnd])->Fill(ptEnd);
00439 static int iPtEndLog = hists.IndexOf(hists.FindObject("ptEndLog"));
00440 static_cast<TH1*>(hists[iPtEndLog])->Fill(ptEnd);
00441 static int iPhiXzEnd = hists.IndexOf(hists.FindObject("phiXzEnd"));
00442 static_cast<TH1*>(hists[iPhiXzEnd])->Fill(phiXzEnd);
00443 static int iThetaYEnd = hists.IndexOf(hists.FindObject("thetaYEnd"));
00444 static_cast<TH1*>(hists[iThetaYEnd])->Fill(thetaYEnd);
00445
00446 static int iMomStartEnd = hists.IndexOf(hists.FindObject("momStartEnd"));
00447 static_cast<TH1*>(hists[iMomStartEnd])->Fill(scalarMomStart-scalarMomEnd);
00448 static int iMomStartEndRel = hists.IndexOf(hists.FindObject("momStartEndRel"));
00449 static_cast<TH1*>(hists[iMomStartEndRel])->Fill(diffMomRel);
00450 static int iPhiStartEnd = hists.IndexOf(hists.FindObject("phiXzStartEnd"));
00451 static_cast<TH1*>(hists[iPhiStartEnd])->Fill(phiXzStart-phiXzEnd);
00452 static int iThetaStartEnd = hists.IndexOf(hists.FindObject("thetaYStartEnd"));
00453 static_cast<TH1*>(hists[iThetaStartEnd])->Fill(thetaYStart-thetaYEnd);
00454
00455 static int iPhiStartVsEnd = hists.IndexOf(hists.FindObject("phiXzStartVsEnd"));
00456 static_cast<TH2*>(hists[iPhiStartVsEnd])->Fill(phiXzEnd, phiXzStart);
00457 static int iThetaStartVsEnd = hists.IndexOf(hists.FindObject("thetaYStartVsEnd"));
00458 static_cast<TH2*>(hists[iThetaStartVsEnd])->Fill(thetaYEnd, thetaYStart);
00459
00460 static int iMomStartEndRelVsZ = hists.IndexOf(hists.FindObject("momStartEndRelVsZ"));
00461 static_cast<TH2*>(hists[iMomStartEndRelVsZ])->Fill(vert.z(), diffMomRel);
00462 static int iPhiStartEndVsZ = hists.IndexOf(hists.FindObject("phiXzStartEndVsZ"));
00463 static_cast<TH2*>(hists[iPhiStartEndVsZ])->Fill(vert.z(), phiXzStart-phiXzEnd);
00464 static int iThetaStartEndVsZ = hists.IndexOf(hists.FindObject("thetaYStartEndVsZ"));
00465 static_cast<TH2*>(hists[iThetaStartEndVsZ])->Fill(vert.z(), thetaYStart-thetaYEnd);
00466 static int iMomStartEndRelVsP = hists.IndexOf(hists.FindObject("momStartEndRelVsP"));
00467 static_cast<TH2*>(hists[iMomStartEndRelVsP])->Fill(scalarMomStart, diffMomRel);
00468 static int iPhiStartEndVsP = hists.IndexOf(hists.FindObject("phiXzStartEndVsP"));
00469 static_cast<TH2*>(hists[iPhiStartEndVsP])->Fill(scalarMomStart, phiXzStart-phiXzEnd);
00470 static int iThetaStartEndVsP = hists.IndexOf(hists.FindObject("thetaYStartEndVsP"));
00471 static_cast<TH2*>(hists[iThetaStartEndVsP])->Fill(scalarMomStart, thetaYStart-thetaYEnd);
00472
00473 static int iRadiusEnd = hists.IndexOf(hists.FindObject("radiusEnd"));
00474 static_cast<TH1*>(hists[iRadiusEnd])->Fill(rEnd);
00475 static int iZend = hists.IndexOf(hists.FindObject("zEnd"));
00476 static_cast<TH1*>(hists[iZend])->Fill(zEnd);
00477 static int iZdiff = hists.IndexOf(hists.FindObject("zDiff"));
00478 static_cast<TH1*>(hists[iZdiff])->Fill(diffZ);
00479 static int iXyPlaneEnd = hists.IndexOf(hists.FindObject("xyPlaneEnd"));
00480 static_cast<TH1*>(hists[iXyPlaneEnd])->Fill(endVert.x(), endVert.y());
00481 static int iRzPlaneEnd = hists.IndexOf(hists.FindObject("rzPlaneEnd"));
00482 static_cast<TH1*>(hists[iRzPlaneEnd])->Fill(zEnd, (endVert.y() > 0 ? rEnd : -rEnd));
00483 static int iThetaVsZend = hists.IndexOf(hists.FindObject("thetaVsZend"));
00484 static_cast<TH2*>(hists[iThetaVsZend])->Fill(zEnd, thetaEnd);
00485 }
00486
00487
00488 bool CosmicGenFilterHelix::equidistLogBins(double* bins, int nBins,
00489 double first, double last) const
00490 {
00491
00492
00493
00494
00495
00496 if (nBins < 1 || first <= 0. || last <= 0.) return false;
00497
00498 bins[0] = first;
00499 bins[nBins] = last;
00500 const double firstLog = TMath::Log10(bins[0]);
00501 const double lastLog = TMath::Log10(bins[nBins]);
00502 for (int i = 1; i < nBins; ++i) {
00503 bins[i] = TMath::Power(10., firstLog + i*(lastLog-firstLog)/(nBins));
00504 }
00505
00506 return true;
00507 }