rivet is hosted by Hepforge, IPPP Durham
Event.cc
Go to the documentation of this file.
00001 #include "Rivet/Event.hh"
00002 #include "Rivet/Tools/Logging.hh"
00003 #include "Rivet/Projections/Beam.hh"
00004 #include "Rivet/BeamConstraint.hh"
00005 #include "HepMC/GenEvent.h"
00006 
00007 namespace Rivet {
00008 
00009 
00010   void Event::_init(const GenEvent& ge) {
00011     // Use Rivet's preferred units if possible
00012     #ifdef HEPMC_HAS_UNITS
00013     _genEvent.use_units(HepMC::Units::GEV, HepMC::Units::MM);
00014     #endif
00015 
00016     // Use the conventional alignment
00017     _geNormAlignment();
00018 
00019     // @todo Filter the event to remove generator-specific particles: optional
00020     // behaviour? Maybe disableable in an inconvenient way, e.g. with an env
00021     // var, to communicate the appropriate distaste for this sort of truth
00022     // analysis ;-)
00023 
00024     // Debug printout to check that copying/mangling has worked
00025     /// @todo Enable this when HepMC has been fixed to allow printing to a stream like the Rivet logger.
00026     //_genEvent.print();
00027   }
00028 
00029 
00030   namespace { // unnamed namespace for hiding
00031 
00032     void _geRot180x(GenEvent& ge) {
00033       /// @todo Use nicer iterators over HepMC particles
00034       for (HepMC::GenEvent::particle_iterator ip = ge.particles_begin(); ip != ge.particles_end(); ++ip) {
00035         const HepMC::FourVector& mom = (*ip)->momentum();
00036         (*ip)->set_momentum(HepMC::FourVector(mom.px(), -mom.py(), -mom.pz(), mom.e()));
00037       }
00038       /// @todo Use nicer iterators over HepMC vertices
00039       for (HepMC::GenEvent::vertex_iterator iv = ge.vertices_begin(); iv != ge.vertices_end(); ++iv) {
00040         const HepMC::FourVector& pos = (*iv)->position();
00041         (*iv)->set_position(HepMC::FourVector(pos.x(), -pos.y(), -pos.z(), pos.t()));
00042       }
00043     }
00044 
00045   }
00046 
00047 
00048   void Event::_geNormAlignment() {
00049     if (!_genEvent.valid_beam_particles()) return;
00050     typedef pair<HepMC::GenParticle*, HepMC::GenParticle*> GPPair;
00051     GPPair bps = _genEvent.beam_particles();
00052 
00053     // Rotate e+- p and ppbar to put p along +z
00054     /// @todo Is there an e+ e- convention for longitudinal boosting, e.g. at B-factories? Different from LEP?
00055     // if (compatible(beamids, make_pdgid_pair(ELECTRON, PROTON)) ||
00056     //     compatible(beamids, make_pdgid_pair(POSITRON, PROTON)) ||
00057     //     compatible(beamids, make_pdgid_pair(ANTIPROTON, PROTON)) ) {
00058     //   Log::getLog("Rivet.Event") << Log::TRACE << "May need to rotate event..." << endl;
00059     bool rot = false;
00060     const HepMC::GenParticle* plusgp = 0;
00061     if (bps.first->pdg_id() != PID::PROTON || bps.second->pdg_id() != PID::PROTON) {
00062       if (bps.first->pdg_id() == PID::PROTON) {
00063         plusgp = bps.first;
00064       } else if (bps.second->pdg_id() == PID::PROTON) {
00065         plusgp = bps.second;
00066       }
00067       if (plusgp && plusgp->momentum().pz() < 0) {
00068         rot = true;
00069       }
00070     }
00071 
00072     // Do the rotation
00073     if (rot) {
00074       if (Log::getLog("Rivet.Event").isActive(Log::TRACE)) {
00075         Log::getLog("Rivet.Event") << Log::TRACE << "Rotating event\n"
00076                                    << "Before rotation: "
00077                                    << bps.first->pdg_id() << "@pz=" << bps.first->momentum().pz()/GeV << ", "
00078                                    << bps.second->pdg_id() << "@pz=" << bps.second->momentum().pz()/GeV << endl;
00079       }
00080       _geRot180x(_genEvent);
00081     }
00082   }
00083 
00084 
00085 }