agile is hosted by Hepforge, IPPP Durham

Run.cc

Go to the documentation of this file.
00001 #include "AGILe/Run.hh"
00002 
00003 using namespace std;
00004 
00005 namespace AGILe {
00006 
00007 
00008   Run::Run(Generator& gen)
00009     : _gen(&gen), _filter(Run::DOCFILT)//, _ostr(0), _io(0)
00010   {
00011     //
00012   }
00013 
00014 
00015   // Make a generator run with a particular gen and I/O target
00016   Run::Run(Generator& gen, const string& evtfile, int precision)
00017     : _gen(&gen), _filter(Run::DOCFILT)
00018   {
00019     if (evtfile.size() > 0) {
00020       if (evtfile == "-") {
00021         _io.reset(new HepMC::IO_GenEvent(std::cout));
00022       } else {
00023         // Ignore the HepMC::IO_GenEvent(filename, ios) constructor, since only available from HepMC >= 2.4
00024         _ostr.reset(new std::fstream(evtfile.c_str(), std::ios::out));
00025         _io.reset(new HepMC::IO_GenEvent(*_ostr));
00026       }
00027       // Use the cross-section #define as a proxy for precision() being available
00028       #ifdef HEPMC_HAS_CROSS_SECTION
00029       _io->precision(precision);
00030       #endif
00031     }
00032   }
00033 
00034 
00035   void filterEvent(HepMC::GenEvent* ge, Run::FilterLevel filterlevel) {
00036     // Escape fast if there's nothing to do
00037     if (filterlevel == Run::NOFILT) return;
00038 
00039     // We treat beam particles a bit specially
00040     const std::pair<HepMC::GenParticle*, HepMC::GenParticle*> beams = ge->beam_particles();
00041 
00042     // Make list of non-physical particle entries
00043     std::vector<HepMC::GenParticle*> unphys_particles;
00044     for (HepMC::GenEvent::particle_const_iterator pi = ge->particles_begin();
00045          pi != ge->particles_end(); ++pi) {
00046       // Beam particles might not have status = 4, but we want them anyway
00047       if (beams.first == *pi || beams.second == *pi) continue;
00048       // Filter by status
00049       const int status = (*pi)->status();
00050       const bool keep = (status == 1 || status == 4 || (filterlevel != Run::UNSTABLEFILT && status == 2));
00051       if (!keep) {
00052         unphys_particles.push_back(*pi);
00053       }
00054     }
00055 
00056     // Remove each unphysical particle from the list
00057     while (unphys_particles.size()) {
00058       HepMC::GenParticle* gp = unphys_particles.back();
00059 
00060       // Get start and end vertices
00061       HepMC::GenVertex* vstart = gp->production_vertex();
00062       HepMC::GenVertex* vend = gp->end_vertex();
00063 
00064       if (vend == vstart) {
00065         // Deal with loops
00066         vstart->remove_particle(gp);
00067       } else {
00068 
00069         // Connect decay particles from end vertex to start vertex
00071         if (vend && vend->particles_out_size()) {
00072           std::vector<HepMC::GenParticle*> end_particles;
00073           for (HepMC::GenVertex::particles_out_const_iterator gpe = vend->particles_out_const_begin();
00074                gpe != vend->particles_out_const_end(); ++gpe) {
00075             end_particles.push_back(*gpe);
00076           }
00077           // Reset production vertices of child particles to bypass unphysical particle
00078           for (std::vector<HepMC::GenParticle*>::const_iterator gpe = end_particles.begin();
00079                gpe != end_particles.end(); ++gpe) {
00080             //std::cout << vstart << ", " << vend << std::endl;
00081             if (vstart) vstart->add_particle_out(*gpe);
00082           }
00083         } else {
00084           // If null end_vertex... stable unphysical particle?
00085         }
00086 
00087         // Delete unphysical particle and its orphaned end vertex
00088         delete vend;
00089         if (vstart) {
00090           delete vstart->remove_particle(gp);
00091         }
00092       }
00093 
00094       // Remove deleted particle from list
00095       unphys_particles.pop_back();
00096       //std::cout << unphys_particles.size() << std::endl;
00097     }
00098 
00099     // Delete any orphaned vertices
00100     std::vector<HepMC::GenVertex*> orphaned_vtxs;
00101     for (HepMC::GenEvent::vertex_const_iterator vi = ge->vertices_begin();
00102          vi != ge->vertices_end(); ++vi) {
00103       if ((*vi)->particles_in_size() == 0 && (*vi)->particles_out_size() == 0) {
00104         orphaned_vtxs.push_back(*vi);
00105       }
00106     }
00107     while (orphaned_vtxs.size()) {
00108       delete orphaned_vtxs.back();
00109       orphaned_vtxs.pop_back();
00110     }
00111   }
00112 
00113 
00114 
00115   // Generate an event and send it to the writer if it exists
00116   bool Run::makeEvent() {
00117     // Make and fill event
00118     _gen->makeEvent(_evt);
00119 
00120     // Filter unphysical bits of event (reduces storage/transport size, and ensures physicality)
00121     filterEvent(&_evt, _filter);
00122 
00123     // Do I/O streaming if required
00124     if (_io) {
00125       _io->write_event(&_evt);
00126       if (_io->rdstate() != 0) {
00127         return false;
00128       }
00129     }
00130 
00131     return true;
00132   }
00133 
00134 
00135   // Return an event summary string
00136   string Run::eventSummary() const {
00137     std::ostringstream ss;
00138     int Nfs = 0;
00139     for (HepMC::GenEvent::particle_const_iterator pi = _evt.particles_begin();
00140          pi != _evt.particles_end(); ++pi) {
00141       if ((*pi)->status() == 1) Nfs += 1;
00142     }
00143     ss << "HepMC::GenEvent { "
00144        << _evt.particles_size() << " particles "
00145        << "(" << Nfs << " in FS), "
00146        << _evt.vertices_size() << " vertices }";
00147     return ss.str();
00148   }
00149 
00150 
00151 }
Generated on Tue Mar 6 10:39:39 2012 for AGILe - A Generator Interface Library (+ executable) by  doxygen 1.6.3