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();
+}