Index: trunk/src/EicSmearFormatWriter.h =================================================================== --- trunk/src/EicSmearFormatWriter.h (revision 0) +++ trunk/src/EicSmearFormatWriter.h (revision 443) @@ -0,0 +1,60 @@ +//============================================================================== +// EicSmearFormatWriter.h +// +// Copyright (C) 2021 Tobias Toll and Thomas Ullrich +// +// This file is part of Sartre. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation. +// This program is distributed in the hope that it will be useful, +// but without any warranty; without even the implied warranty of +// merchantability or fitness for a particular purpose. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Author: Thomas Ullrich +// $Date$ +// $Author$ +//============================================================================== +#ifndef EicSmearFormatWriter_h +#define EicSmearFormatWriter_h +#include +#include +#include +#include "TLorentzVector.h" + +using namespace std; + +class Event; + +class EicSmearFormatWriter { +public: + EicSmearFormatWriter(); + ~EicSmearFormatWriter(); + + bool open(string, bool breakupOn = false); + bool writeEvent(Event*); + void close(); + + bool hasOpenFile() const; + string filename() const; + +private: + bool writeHeader(); + void writeKine(TLorentzVector&); + +private: + bool mBreakupIsOn; + bool mFileOpen; + string mFilename; + + ofstream mStream; +}; + +inline bool EicSmearFormatWriter::hasOpenFile() const {return mFileOpen;} +inline string EicSmearFormatWriter::filename() const {return mFilename;} + +#endif Index: trunk/src/EicSmearFormatWriter.cpp =================================================================== --- trunk/src/EicSmearFormatWriter.cpp (revision 0) +++ trunk/src/EicSmearFormatWriter.cpp (revision 443) @@ -0,0 +1,286 @@ +//============================================================================== +// EicSmearFormatWriter.cpp +// +// Copyright (C) 2021 Tobias Toll and Thomas Ullrich +// +// This file is part of Sartre. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation. +// This program is distributed in the hope that it will be useful, +// but without any warranty; without even the implied warranty of +// merchantability or fitness for a particular purpose. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Author: Thomas Ullrich based on code by Barak Schmookler (SBU) +// $Date$ +// $Author$ +//============================================================================== +#include "Event.h" +#include "Constants.h" +#include "Enumerations.h" +#include "EicSmearFormatWriter.h" + +#define PR(x) cout << #x << " = " << (x) << endl; + +EicSmearFormatWriter::EicSmearFormatWriter() +{ + mFileOpen = false; + mBreakupIsOn = false; +} + +EicSmearFormatWriter::~EicSmearFormatWriter() +{ + close(); +} + +bool EicSmearFormatWriter::open(string name, bool bupOn) +{ + mBreakupIsOn = bupOn; + + if (mFileOpen) { // stream already used + cout << "EicSmearFormatWriter::open(): Warning, trying to open file stream that is already open." << endl; + return false; + } + + mFilename = name; + mStream.open(mFilename, ios_base::out); + + if (mStream.is_open() && mStream.good()) { + mFileOpen = true; + writeHeader(); + } + else { + cout << "EicSmearFormatWriter::open(): Error, failed to open file '" + << mFilename << "'." << endl; + mStream.close(); + mFileOpen = false; + } + + return mFileOpen; +} + +void EicSmearFormatWriter::close() +{ + mStream.close(); + mFileOpen = false; + mBreakupIsOn = false; + mFilename = ""; +} + +bool EicSmearFormatWriter::writeHeader() +{ + // + // Six-line header according to + // https://eic.github.io/software/mcgen.html + // + if (!mStream.good()) return false; + mStream << "Sartre EVENT FILE" << endl; + mStream << "============================================" << endl; + mStream << "I, ievent, genevent, t, Q2, x, y, W2, nu, xpom, s, pol, dmod, bup" << endl; + mStream << "============================================" << endl; + mStream << "I, K(I,1) K(I,2) K(I,3) K(I,4) K(I,5) P(I,1) P(I,2) P(I,3) P(I,4) P(I,5) V(I,1) V(I,2) V(I,3)" << endl; + mStream << "============================================" << endl; + return true; +} + +void EicSmearFormatWriter::writeKine(TLorentzVector& vec) +{ + mStream << vec.Px(); // Px + mStream << "\t"; + mStream << vec.Py(); // Py + mStream << "\t"; + mStream << vec.Pz(); // Pz + mStream << "\t"; + mStream << vec.E(); // Energy + mStream << "\t"; + mStream << vec.M(); // Mass +} + +bool EicSmearFormatWriter::writeEvent(Event* event) +{ + // + // The first four tracks should be, in order, + // 1 - beam lepton + // 2 - beam hadron + // 3 - exchange boson (gamma*) + // 4 - scattered lepton + // That way, they are picked up correctly by the + // default methods + // Then we do + // 5 - pomeron + // 6 - scattered hadron + // 7 - vector meson + // If present + // 8 - decay daughter 1 + // 9 - decay daughter 2 + // followed by all fragments if breakup is on + // + + if (!mFileOpen) { + cout << "EicSmearFormatWriter::writeEvent(): Error, no file assigned. Do not know where to write to." << endl; + return false; + } + else { + if (!mStream.good()) { + cout << "EicSmearFormatWriter::writeEvent(): Error, cannot write into file '" + << mFilename << "'." << endl; + return false; + } + } + + if (!event) { + cout << "EicSmearFormatWriter::writeEvent(): Error, event pointer is not valid (null)." << endl; + return false; + } + + // + // The rest of the code is adapted from code by Barak Schmookler (SBU) + // Status codes used: + // stable - 1 + // decayed - 11 + // beam - 21 + + // + // General event info + // + mStream << "0"; // I + mStream << "\t"; + mStream << event->eventNumber; // ievent + mStream << "\t"; + mStream << "1"; //genevent + mStream << "\t"; + mStream << event->t; + mStream << "\t"; + mStream << event->Q2; + mStream << "\t"; + mStream << event->x; + mStream << "\t"; + mStream << event->y; + mStream << "\t"; + mStream << event->W*event->W; // W2 + mStream << "\t"; + mStream << (event->Q2)/(2.*protonMass*event->x); // nu + mStream << "\t"; + mStream << event->xpom; + mStream << "\t"; + mStream << event->s; + mStream << "\t"; + mStream << (event->polarization == transverse ? 0 : 1); // pol + mStream << "\t"; + mStream << (event->diffractiveMode == coherent ? 0 : 1); // dmod + mStream << "\t"; + mStream << (mBreakupIsOn ? 1 : 0); //bup + mStream << endl; + mStream << "============================================" << endl; + + // + // Push back initial particle vectors + // + string vertex = "\t0\t0\t0"; + + // eIn + mStream << "1\t"; // I + mStream << "21\t"; // Status + mStream << event->particles[0].pdgId << '\t'; + mStream << "0\t 0\t 0\t"; + writeKine(event->particles[0].p); + mStream << vertex << endl; // Vertex + + // pIn + mStream << "2\t"; + mStream << "21\t"; // (21 for beam) + mStream << event->particles[1].pdgId << '\t'; + //eic_out << "2212"; // "event->particles[1].pdgId" gives error on conversion + mStream << "0\t 0\t 0\t"; + writeKine(event->particles[1].p); + mStream << vertex << endl; // Vertex + + // gamma* + mStream << "3\t"; + mStream << "21\t"; + mStream << event->particles[3].pdgId; + mStream << "\t"; + mStream << "0\t 0\t 0\t"; + writeKine(event->particles[3].p); + mStream << vertex << endl; + + // eOut + mStream << "4\t"; + mStream << "1\t"; + mStream << event->particles[2].pdgId; + mStream << "\t"; + mStream << "1\t 0\t 0\t"; // 3 for scattered lepton + writeKine(event->particles[2].p); + mStream << vertex << endl; + + // Pomeron + mStream << "5\t"; + mStream << "21\t"; + mStream << event->particles[5].pdgId; + mStream << "\t 0\t 0\t 0\t"; + writeKine(event->particles[5].p); + mStream << vertex << endl; + + // pOut + mStream << "6\t"; + if(mBreakupIsOn && event->diffractiveMode == incoherent) + mStream << "11\t"; + else + mStream << "1\t"; + mStream << event->particles[6].pdgId; + mStream << "\t 2\t 0\t 0\t"; + writeKine(event->particles[6].p); + mStream << vertex << endl; + + // vector meson + int numberOfDaughters = event->particles[4].daughters.size(); + mStream << "7\t"; + mStream << (numberOfDaughters ? 11 : 1) << '\t'; + mStream << event->particles[4].pdgId; + if (numberOfDaughters) { + mStream << "\t 0\t 8\t 9\t"; + } + else { + mStream << "\t 0\t 0\t 0\t"; + } + writeKine(event->particles[4].p); + mStream << vertex << endl; + + // + // Check if daughters are present. If so + // stream them out as well. + // + int index = 7; + for (int i=0; i < numberOfDaughters; i++) { + mStream << ++index; + mStream << "\t"; + mStream << "1\t"; + int k = event->particles[4].daughters[i]; // vm = 4 + mStream << event->particles[k].pdgId; + mStream << "\t 7\t 0\t 0\t"; + writeKine(event->particles[k].p); + mStream << vertex << endl; + } + + // + // If breakup is on write out the fragments + // + if (mBreakupIsOn) { + for (unsigned int i=index; iparticles.size(); i++) { + mStream << i+1; + mStream << "\t"; + mStream << "1\t"; + mStream << event->particles[i].pdgId; + mStream << "\t"; + mStream << "6\t 0\t 0\t"; + writeKine(event->particles[i].p); + mStream << vertex << endl; + } + } + mStream << "=============== Event finished ===============" << endl; + return mStream.good(); +}