00001 #include "HepEvt2HepMC.h"
00002 #include "GaudiKernel/IssueSeverity.h"
00003 #include "HepMC/GenEvent.h"
00004 #include "HepMC/GenParticle.h"
00005 #include "HepMC/GenVertex.h"
00006 #include "CLHEP/Units/SystemOfUnits.h"
00007 #include <string>
00008 #include <sstream>
00009
00010 HepEvt2HepMC::HepEvt2HepMC()
00011 : m_eventCount(0)
00012 {
00013 }
00014
00015 HepEvt2HepMC::~HepEvt2HepMC()
00016 {
00017
00018 HepMC::GenEvent* event=0;
00019 while (this->cacheSize()) {
00020 this->generate(event).ignore();
00021 delete event;
00022 event = 0;
00023 }
00024 }
00025
00026
00027 StatusCode HepEvt2HepMC::generate(HepMC::GenEvent*& event)
00028 {
00029 if (!this->cacheSize()) {
00030 event=0;
00031 STATUSCODE(StatusCode::FAILURE, IssueSeverity::FATAL,
00032 "No cached events to return, call fill()");
00033 }
00034
00035 event = m_events.front();
00036 m_events.pop_front();
00037 return StatusCode::SUCCESS;
00038 }
00039
00040
00041 #include <cstdio>
00042 static FILE* open_file(std::string filename)
00043 {
00044 size_t siz = filename.size();
00045 if (filename[siz-1] == '|') {
00046 return popen(filename.substr(0,siz-1).c_str(), "r");
00047 }
00048 else {
00049 return fopen(filename.c_str(), "r");
00050 }
00051 return 0;
00052 }
00053
00054
00055 static void close_file(FILE* fp, std::string filename)
00056 {
00057 size_t siz = filename.size();
00058 if (filename[siz-1] == '|') {
00059 pclose(fp);
00060 }
00061 else {
00062 fclose(fp);
00063 }
00064 }
00065
00066 static bool is_data(const char* line)
00067 {
00068 int numchkindx = 0;
00069 if (line[0] == ' ') numchkindx = 1;
00070 return line[numchkindx] >= '0' && line[numchkindx] <= '9';
00071 }
00072
00073 static bool get_line(FILE* fp, std::string& line)
00074 {
00075 char buf[1024] = {'\0'};
00076 if (!fgets(buf,1024,fp)) {
00077 return false;
00078 }
00079 if (buf[1022]) {
00080 return false;
00081 }
00082
00083 if (!is_data(buf)) return get_line(fp,line);
00084
00085 line = buf;
00086 return true;
00087 }
00088
00089 static bool unpack(const std::string& line, HepMC::GenEvent& event)
00090 {
00091 int status=0;
00092 int pdgid=0;
00093 int oldest_daughter=0;
00094 int baby_daughter=0;
00095 double px=0.0;
00096 double py=0.0;
00097 double pz=0.0;
00098 double req_novalue=1e30;
00099 double mass=req_novalue;
00100 double vertexX=req_novalue;
00101 double vertexY=req_novalue;
00102 double vertexZ=req_novalue;
00103 double vertex_dT=req_novalue;
00104 double polx=0.0;
00105 double poly=0.0;
00106 double polz=0.0;
00107 double energy_unit= CLHEP::GeV;
00108 double position_unit= CLHEP::millimeter;
00109 double time_unit= CLHEP::nanosecond;
00110
00111 std::istringstream is;
00112 is.str(line);
00113 is >> status >> pdgid >> oldest_daughter >> baby_daughter
00114 >> px >> py >> pz >> mass
00115 >> vertex_dT >> vertexX >> vertexY >> vertexZ
00116 >> polx >> poly >> polz;
00117
00118
00119 HepMC::GenParticle* particle = new HepMC::GenParticle
00120 (HepMC::FourVector(px*energy_unit,
00121 py*energy_unit,
00122 pz*energy_unit,
00123 sqrt(px*px+py*py+pz*pz+mass*mass)*energy_unit),
00124 pdgid,status);
00125 HepMC::GenVertex* vertex = new HepMC::GenVertex
00126 (HepMC::FourVector(vertexX*position_unit,
00127 vertexY*position_unit,
00128 vertexZ*position_unit,
00129 vertex_dT*time_unit));
00130 event.add_vertex(vertex);
00131 if (status == 1) {
00132 vertex->add_particle_out(particle);
00133 event.set_signal_process_vertex(vertex);
00134 }
00135 else {
00136 vertex->add_particle_in(particle);
00137 }
00138 return true;
00139 }
00140
00141
00142 StatusCode HepEvt2HepMC::fill(const char* source_desc)
00143 {
00144 FILE* fp = open_file(source_desc);
00145 if (!fp) {
00146 std::string msg = "Failed to open HEPEvt data source: \"";
00147 msg += source_desc;
00148 msg += "\"";
00149 return STATUSCODE(StatusCode::FAILURE,IssueSeverity::FATAL,msg);
00150 }
00151
00152 std::string line;
00153 int nlines = 0;
00154 while (get_line(fp,line)) {
00155 std::istringstream is;
00156 is.str(line);
00157 is >> nlines;
00158 HepMC::GenEvent* event = new HepMC::GenEvent(0,m_eventCount);
00159 for(; nlines; --nlines) {
00160 get_line(fp,line);
00161 if (!unpack(line,*event)) return StatusCode::FAILURE;
00162 }
00163 m_events.push_back(event);
00164 ++m_eventCount;
00165 }
00166
00167 close_file(fp,source_desc);
00168 return STATUSCODE(StatusCode::SUCCESS,IssueSeverity::INFO,
00169 "Filled HepMC event cache");
00170 }
00171
00172