Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F10881488
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
176 KB
Subscribers
None
View Options
Index: trunk/src/ExclusiveFinalStateGenerator.h
===================================================================
--- trunk/src/ExclusiveFinalStateGenerator.h (revision 490)
+++ trunk/src/ExclusiveFinalStateGenerator.h (revision 491)
@@ -1,41 +1,43 @@
//==============================================================================
// ExclusiveFinalStateGenerator.h
//
// Copyright (C) 2010-2019 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich
// Last update:
// $Date$
// $Author$
//==============================================================================
#ifndef ExclusiveFinalStateGenerator_h
#define ExclusiveFinalStateGenerator_h
#include "FinalStateGenerator.h"
class ExclusiveFinalStateGenerator : public FinalStateGenerator {
public:
ExclusiveFinalStateGenerator();
~ExclusiveFinalStateGenerator();
-
- bool generate(int id, double t, double y, double Q2,
- bool isIncoherent, int A, Event *event);
+
+ bool generate(int id, double t, double y, double Q2, bool isIncoherent, int A, Event *event);
//UPC version:
- bool generate(int id, double t, double xpom,
- bool isIncoherent, int A, Event *event);
+ bool generate(int id, double t, double xpom, bool isIncoherent, int A, Event *event);
+
double xpomMin(double massVM, double t, TLorentzVector hBeam, TLorentzVector eBeam);
-};
+
+ double uiGamma_N(double* var, double* par) const;
+ double gamma_N(unsigned int i, double val);
+};
#endif
Index: trunk/src/Settings.cpp
===================================================================
--- trunk/src/Settings.cpp (revision 490)
+++ trunk/src/Settings.cpp (revision 491)
@@ -1,592 +1,603 @@
//==============================================================================
// Settings.cpp
//
// Copyright (C) 2010-2019 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich
// Last update:
// $Date$
// $Author$
//==============================================================================
#include "Settings.h"
#include <typeinfo>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <ctype.h>
+#include <cstdlib>
#include "TParticlePDG.h"
#include "TError.h"
-#include <cstdlib>
#define PR(x) cout << #x << " = " << (x) << endl;
TRandom3 Settings::mRandomGenerator;
Settings::Settings()
{
- mPDG = new TDatabasePDG;
- mPDG->ReadPDGTable();
+ mPDG = new TDatabasePDG;
+ mPDG->ReadPDGTable();
//
// Setup name table (map) for nuclei
//
mPeriodicTable[1] = "H";
mPeriodicTable[2] = "He";
mPeriodicTable[3] = "Li";
mPeriodicTable[4] = "Be";
mPeriodicTable[5] = "B";
mPeriodicTable[6] = "C";
mPeriodicTable[7] = "N";
mPeriodicTable[8] = "O";
mPeriodicTable[9] = "F";
mPeriodicTable[10] = "Ne";
mPeriodicTable[11] = "Na";
mPeriodicTable[12] = "Mg";
mPeriodicTable[13] = "Al";
mPeriodicTable[14] = "Si";
mPeriodicTable[15] = "P";
mPeriodicTable[16] = "S";
mPeriodicTable[17] = "Cl";
mPeriodicTable[18] = "Ar";
mPeriodicTable[19] = "K";
mPeriodicTable[20] = "Ca";
mPeriodicTable[21] = "Sc";
mPeriodicTable[22] = "Ti";
mPeriodicTable[23] = "V";
mPeriodicTable[24] = "Cr";
mPeriodicTable[25] = "Mn";
mPeriodicTable[26] = "Fe";
mPeriodicTable[27] = "Co";
mPeriodicTable[28] = "Ni";
mPeriodicTable[29] = "Cu";
mPeriodicTable[30] = "Zn";
mPeriodicTable[31] = "Ga";
mPeriodicTable[32] = "Ge";
mPeriodicTable[33] = "As";
mPeriodicTable[34] = "Se";
mPeriodicTable[35] = "Br";
mPeriodicTable[36] = "Kr";
mPeriodicTable[37] = "Rb";
mPeriodicTable[38] = "Sr";
mPeriodicTable[39] = "Y";
mPeriodicTable[40] = "Zr";
mPeriodicTable[41] = "Nb";
mPeriodicTable[42] = "Mo";
mPeriodicTable[43] = "Tc";
mPeriodicTable[44] = "Ru";
mPeriodicTable[45] = "Rh";
mPeriodicTable[46] = "Pd";
mPeriodicTable[47] = "Ag";
mPeriodicTable[48] = "Cd";
mPeriodicTable[49] = "In";
mPeriodicTable[50] = "Sn";
mPeriodicTable[51] = "Sb";
mPeriodicTable[52] = "Te";
mPeriodicTable[53] = "I";
mPeriodicTable[54] = "Xe";
mPeriodicTable[55] = "Cs";
mPeriodicTable[56] = "Ba";
mPeriodicTable[57] = "La";
mPeriodicTable[58] = "Ce";
mPeriodicTable[59] = "Pr";
mPeriodicTable[60] = "Nd";
mPeriodicTable[61] = "Pm";
mPeriodicTable[62] = "Sm";
mPeriodicTable[63] = "Eu";
mPeriodicTable[64] = "Gd";
mPeriodicTable[65] = "Tb";
mPeriodicTable[66] = "Dy";
mPeriodicTable[67] = "Ho";
mPeriodicTable[68] = "Er";
mPeriodicTable[69] = "Tm";
mPeriodicTable[70] = "Yb";
mPeriodicTable[71] = "Lu";
mPeriodicTable[72] = "Hf";
mPeriodicTable[73] = "Ta";
mPeriodicTable[74] = "W";
mPeriodicTable[75] = "Re";
mPeriodicTable[76] = "Os";
mPeriodicTable[77] = "Ir";
mPeriodicTable[78] = "Pt";
mPeriodicTable[79] = "Au";
mPeriodicTable[80] = "Hg";
mPeriodicTable[81] = "Tl";
mPeriodicTable[82] = "Pb";
mPeriodicTable[83] = "Bi";
mPeriodicTable[84] = "Po";
mPeriodicTable[85] = "At";
mPeriodicTable[86] = "Rn";
mPeriodicTable[87] = "Fr";
mPeriodicTable[88] = "Ra";
mPeriodicTable[89] = "Ac";
mPeriodicTable[90] = "Th";
mPeriodicTable[91] = "Pa";
mPeriodicTable[92] = "U";
mPeriodicTable[93] = "Np";
mPeriodicTable[94] = "Pu";
mPeriodicTable[95] = "Am";
mPeriodicTable[96] = "Cm";
mPeriodicTable[97] = "Bk";
mPeriodicTable[251] = "Cf";
mPeriodicTable[252] = "Es";
mPeriodicTable[100] = "Fm";
mPeriodicTable[258] = "Md";
mPeriodicTable[102] = "No";
mPeriodicTable[103] = "Lr";
mPeriodicTable[261] = "Rf";
mPeriodicTable[105] = "Db";
mPeriodicTable[106] = "Sg";
mPeriodicTable[107] = "Bh";
mPeriodicTable[108] = "Hs";
mPeriodicTable[109] = "Mt";
//
// Register parameters (ptr, name, default)
//
registerParameter(&mUserInt, "userInt", 0);
registerParameter(&mUserDouble, "userDouble", 0.);
registerParameter(&mUserString, "userString", string(""));
registerParameter(&mA, "A", static_cast<unsigned int>(1));
registerParameter(&mVectorMesonId, "vectorMesonId", 443); // J/psi
registerParameter(&mDipoleModelName, "dipoleModel", string("bSat"));
registerParameter(&mDipoleModelParameterSetName, "dipoleModelParameterSet", string("KMW"));
registerParameter(&mTableSetTypeName, "tableSetType", string("total_and_coherent"));
registerParameter(&mQ2min, "Q2min", 1000.); // no limits if max <= min
registerParameter(&mQ2max, "Q2max", 0.);
registerParameter(&mWmin, "Wmin", 1000.);
registerParameter(&mWmax, "Wmax", 0.);
registerParameter(&mXpomMin, "xpomMin", 1e-8);
registerParameter(&mXpomMax, "xpomMax", 1.);
+ registerParameter(&mbetamin, "betamin", 0.);
+ registerParameter(&mbetamax, "betamax", 1.);
+
registerParameter(&mVerbose, "verbose", false);
registerParameter(&mVerboseLevel, "verboseLevel", 0);
registerParameter(&mRootfile, "rootfile", string("sartre.root"));
registerParameter(&mSeed, "seed", static_cast<unsigned int>(time(0)));
registerParameter(&mUPC, "UPC", false);
registerParameter(&mUPCA, "UPCA", static_cast<unsigned int>(1));
}
Settings::~Settings()
{
for (unsigned int k=0; k<mRegisteredParameters.size(); k++) {
delete mRegisteredParameters[k];
}
- mRegisteredParameters.clear();
-}
+ mRegisteredParameters.clear();
+ delete mPDG;
+}
int Settings::userInt() const {return mUserInt;}
double Settings::userDouble() const {return mUserDouble;}
string Settings::userString() const {return mUserString;}
void Settings::setUserInt(int val) {mUserInt = val;}
void Settings::setUserDouble(double val) {mUserDouble = val;}
void Settings::setUserString(const string& val) {mUserString = val;}
unsigned int Settings::seed() const {return mSeed;}
void Settings::setSeed(unsigned int val)
{
mSeed = val;
mRandomGenerator.SetSeed(mSeed);
gRandom->SetSeed(mSeed); // needed for TH1::GetRandom()
}
bool Settings::readSettingsFromFile(const char *file)
{
if (!file) return false; // nothing to do
mRuncard = string(file);
mLines.clear();
//
// Open file
//
ifstream ifs(file);
if (!ifs) {
cout << "Settings::readSettingsFromFile(): error, cannot open file '"
<< file << "'." << endl;
return false;
}
//
// Read file into vector of strings, skip comments and empty lines
//
while (ifs.good() && !ifs.eof()) {
string line;
getline (ifs, line);
if (ifs.eof() && line.empty()) break;
// empty line
if (line.find_first_not_of(" \n\t\v\b\r\f\a") == string::npos) continue;
// if first character is not a letter/digit, then taken to be a comment.
int firstChar = line.find_first_not_of(" \n\t\v\b\r\f\a");
if (!isalnum(line[firstChar])) continue;
mLines.push_back(line);
}
ifs.close(); // done with I/O
//
// Process vector of strings one at a time and use
// it to set registered variables.
//
for (unsigned int i=0; i<mLines.size(); i++) {
// replace '=' by blank to make parsing simpler.
while (mLines[i].find("=") != string::npos) {
int firstEqual = mLines[i].find_first_of("=");
mLines[i].replace(firstEqual, 1, " ");
}
// replace ':' by blank to make parsing simpler.
while (mLines[i].find(":") != string::npos) {
int firstEqual = mLines[i].find_first_of(":");
mLines[i].replace(firstEqual, 1, " ");
}
// get identifier string
istringstream splitLine(mLines[i]);
string name;
splitLine >> name;
// find value string
string valueString;
splitLine >> valueString;
if (!splitLine) {
cout << "Settings::readSettingsFromFile(): error, value of variable '"
<< name.c_str() << "' not recognized." << endl;
}
istringstream modeData(valueString);
//
// Loop over registered variables and see which fits.
// Not particular elegant but does the job and saves
// a lot of programming in derived classes.
//
bool isRegistered = false;
for (unsigned int k=0; k<mRegisteredParameters.size(); k++) {
if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<vector<double>>)) { // test
SettingsParameter<vector<double>> *var = dynamic_cast<SettingsParameter<vector<double>>*> (mRegisteredParameters[k]);
if (var->name == name) {
var->address->push_back(atof(valueString.c_str())); // first value
while (splitLine.good() && !splitLine.eof()) { // get remaining
string nextValue;
splitLine >> nextValue;
var->address->push_back(atof(nextValue.c_str()));
if (splitLine.eof()) break;
}
isRegistered = true;
}
}
else if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<double>)) {
SettingsParameter<double> *var = dynamic_cast<SettingsParameter<double>*> (mRegisteredParameters[k]);
if (var->name == name) {
modeData >> (*(var->address));
isRegistered = true;
}
}
else if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<int>)) {
SettingsParameter<int> *var = dynamic_cast<SettingsParameter<int>*> (mRegisteredParameters[k]);
if (var->name == name) {
modeData >> (*(var->address));
isRegistered = true;
}
}
else if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<unsigned int>)) {
SettingsParameter<unsigned int> *var = dynamic_cast<SettingsParameter<unsigned int>*> (mRegisteredParameters[k]);
if (var->name == name) {
modeData >> (*(var->address));
isRegistered = true;
}
}
else if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<unsigned long>)) {
SettingsParameter<unsigned long> *var = dynamic_cast<SettingsParameter<unsigned long>*> (mRegisteredParameters[k]);
if (var->name == name) {
modeData >> (*(var->address));
isRegistered = true;
}
}
else if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<string>)) {
SettingsParameter<string> *var = dynamic_cast<SettingsParameter<string>*> (mRegisteredParameters[k]);
if (var->name == name) {
*(var->address) = valueString;
isRegistered = true;
}
}
else if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<bool>)) {
SettingsParameter<bool> *var = dynamic_cast<SettingsParameter<bool>*> (mRegisteredParameters[k]);
if (var->name == name) {
isRegistered = true;
if (valueString == string("true") ||
valueString == string("True") ||
valueString == string("TRUE") ||
valueString == string("on") ||
valueString == string("On") ||
valueString == string("ON") ||
valueString == string("Yes") ||
valueString == string("yes") ||
valueString == string("YES") ||
valueString == string("T") ||
valueString == string("t") ||
valueString == string("1") ) {
*(var->address) = true;
}
else {
*(var->address) = false;
}
}
}
}
if (!isRegistered) {
cout << "Settings::readSettingsFromFile(): error, parameter identifier '" <<
name.c_str() << "' not recognized." << endl;
}
}
//
// Consolidate input (after burner)
//
consolidateCommonSettings();
consolidateSettings(); // overloaded
return true;
}
bool Settings::list(ostream& os)
{
const int fieldWidth = 28;
os << "\nRun Settings:" << endl;
for (unsigned int k=0; k<mRegisteredParameters.size(); k++) {
if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<double>)) {
SettingsParameter<double> *var = dynamic_cast<SettingsParameter<double>*> (mRegisteredParameters[k]);
os << setw(fieldWidth) << var->name.c_str() << "\t" << *(var->address) << endl;
}
else if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<int>)) {
SettingsParameter<int> *var = dynamic_cast<SettingsParameter<int>*> (mRegisteredParameters[k]);
os << setw(fieldWidth) << var->name.c_str() << "\t" << *(var->address) << endl;
}
else if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<unsigned int>)) {
SettingsParameter<unsigned int> *var = dynamic_cast<SettingsParameter<unsigned int>*> (mRegisteredParameters[k]);
os << setw(fieldWidth) << var->name.c_str() << "\t" << *(var->address) << endl;
}
else if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<unsigned long>)) {
SettingsParameter<unsigned long> *var = dynamic_cast<SettingsParameter<unsigned long>*> (mRegisteredParameters[k]);
os << setw(fieldWidth) << var->name.c_str() << "\t" << *(var->address) << endl;
}
else if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<string>)) {
SettingsParameter<string> *var = dynamic_cast<SettingsParameter<string>*> (mRegisteredParameters[k]);
os << setw(fieldWidth) << var->name.c_str() << "\t" << var->address->c_str() << endl;
}
else if (typeid(*mRegisteredParameters[k]) == typeid(SettingsParameter<bool>)) {
SettingsParameter<bool> *var = dynamic_cast<SettingsParameter<bool>*> (mRegisteredParameters[k]);
os << setw(fieldWidth) << var->name.c_str() << "\t" << (*(var->address) ? "true" : "false") << endl;
}
}
os << endl;
return true;
}
TParticlePDG* Settings::lookupPDG(int id) const
{
if (mPDG)
return mPDG->GetParticle(id);
else
return 0;
}
string Settings::particleName(int pdgID)
{
string name("unknown");
if (abs(pdgID) < 1000000000) { // particle
if (mPDG) {
TParticlePDG *part = lookupPDG(pdgID);
if (part) name = part->GetName();
}
if (abs(pdgID) == 990) name = "pomeron";
}
else { // nucleus in 10LZZZAAAI PDG format
int id = pdgID;
// int iso = id%10;
id /= 10;
int A = id%1000;
id /= 1000;
int Z = id%1000;
stringstream namestream;
namestream << mPeriodicTable[Z] << "(" << A << ")";
name = namestream.str();
}
return name;
}
void Settings::setVerbose(bool val) {
mVerbose = val;
- if (mVerbose && mVerboseLevel == 0) setVerboseLevel(1);
+ if (mVerbose && mVerboseLevel == 0) setVerboseLevel(1);
if (!mVerbose && mVerboseLevel != 0) setVerboseLevel(0);
}
+
bool Settings::verbose() const {return mVerbose;}
void Settings::setVerboseLevel(int val) {
mVerboseLevel = val;
if (!mVerbose && mVerboseLevel != 0) mVerbose = true;
if (mVerbose && mVerboseLevel == 0) mVerbose = false;
//
// Unless verbose level is 5 or higher we suppress the many redundant
// ROOT messages from algorithms since most of their errors are handled
// internally anyway.
//
if (mVerboseLevel < 5) gErrorIgnoreLevel = 5000;
}
+
int Settings::verboseLevel() const {return mVerboseLevel;}
void Settings::setQ2min(double val) { mQ2min = val;}
double Settings::Q2min() const {return mQ2min;}
double Settings::Qmin() const {return sqrt(mQ2min);}
void Settings::setQ2max(double val) { mQ2max = val;}
double Settings::Q2max() const {return mQ2max;}
double Settings::Qmax() const {return sqrt(mQ2max);}
void Settings::setW2min(double val) { mWmin = sqrt(val);}
void Settings::setWmin(double val) { mWmin = val;}
double Settings::Wmin() const {return mWmin;}
double Settings::W2min() const {return mWmin*mWmin;}
void Settings::setW2max(double val) { mWmax = sqrt(val);}
void Settings::setWmax(double val) { mWmax = val;}
double Settings::Wmax() const {return mWmax;}
double Settings::W2max() const {return mWmax*mWmax;}
void Settings::setXpomMin(double val) {mXpomMin = val;}
void Settings::setXpomMax(double val) {mXpomMax = val;}
double Settings::xpomMin() const {return mXpomMin;}
double Settings::xpomMax() const {return mXpomMax;}
+void Settings::setbetamin(double val) {mbetamin = val;}
+void Settings::setbetamax(double val) {mbetamax = val;}
+double Settings::betamin() const {return mbetamin;}
+double Settings::betamax() const {return mbetamax;}
+
int Settings::vectorMesonId() const {return mVectorMesonId;}
void Settings::setVectorMesonId(int val) {mVectorMesonId = val;}
string Settings::dipoleModelName() const {return mDipoleModelName;}
DipoleModelType Settings::dipoleModelType() const {return mDipoleModelType;}
void Settings::setDipoleModelType(DipoleModelType val)
{
mDipoleModelType = val;
if (mDipoleModelType == bSat)
mDipoleModelName = string("bSat");
else if (mDipoleModelType == bNonSat)
mDipoleModelName = string("bNonSat");
else if (mDipoleModelType == bCGC)
mDipoleModelName = string("bCGC");
}
unsigned int Settings::A() const {return mA;}
void Settings::setA(unsigned int val) {mA = val;}
void Settings::setRootfile(const char* val){ mRootfile = val; }
string Settings::rootfile() const { return mRootfile; }
string Settings::dipoleModelParameterSetName() const {return mDipoleModelParameterSetName;}
DipoleModelParameterSet Settings::dipoleModelParameterSet() const {return mDipoleModelParameterSet;}
void Settings::setDipoleModelParameterSet(DipoleModelParameterSet val)
{
mDipoleModelParameterSet = val;
if (mDipoleModelParameterSet == KMW)
mDipoleModelParameterSetName = string("KMW");
else if (mDipoleModelParameterSet == HMPZ)
mDipoleModelParameterSetName = string("HMPZ");
else if (mDipoleModelParameterSet == STU)
mDipoleModelParameterSetName = string("STU");
else if (mDipoleModelParameterSet == CUSTOM)
mDipoleModelParameterSetName = string("CUSTOM");
}
string Settings::tableSetTypeName() const {return mTableSetTypeName;}
TableSetType Settings::tableSetType() const {return mTableSetType;}
void Settings::setTableSetType(TableSetType val)
{
mTableSetType = val;
if (mTableSetType == total_and_coherent)
mTableSetTypeName = string("total_and_coherent");
else if (mTableSetType == coherent_and_incoherent)
mTableSetTypeName = string("coherent_and_incoherent");
}
void Settings::consolidateCommonSettings()
{
//
// Check if verbose levels and flags are consistent
// The verbose flag superseeds the verboseLevel.
//
if (mVerbose && mVerboseLevel == 0) setVerboseLevel(1);
if (mVerboseLevel != 0 && !mVerbose) setVerboseLevel(0);
setVerboseLevel(verboseLevel()); // invoke method no matter what
//
// Set random generator seed
//
mRandomGenerator.SetSeed(mSeed);
gRandom->SetSeed(mSeed); // needed for TH1::GetRandom()
//
// Dipole Model
//
if (mDipoleModelName == string("bSat"))
mDipoleModelType = bSat;
else if (mDipoleModelName == string("bNonSat"))
mDipoleModelType = bNonSat;
else if (mDipoleModelName == string("bCGC"))
mDipoleModelType = bCGC;
else {
cout << "Settings::consolidateCommonSettings(): Error, dipole model '"
<< mDipoleModelName.c_str() << "' is not defined." << endl;
exit(1);
}
//
// Dipole Model Parameter Set
//
if (mDipoleModelParameterSetName == string("KMW"))
mDipoleModelParameterSet = KMW;
else if (mDipoleModelParameterSetName == string("HMPZ"))
mDipoleModelParameterSet = HMPZ;
else if (mDipoleModelParameterSetName == string("STU"))
mDipoleModelParameterSet = STU;
else if (mDipoleModelParameterSetName == string("CUSTOM"))
mDipoleModelParameterSet = CUSTOM;
else {
cout << "Settings::consolidateCommonSettings(): Error, dipole model parameter set'"
<< mDipoleModelParameterSetName.c_str() << "' is not defined." << endl;
exit(1);
}
//
// Table Set Type
//
if (mTableSetTypeName == string("total_and_coherent"))
mTableSetType = total_and_coherent;
else if (mTableSetTypeName == string("coherent_and_incoherent"))
mTableSetType = coherent_and_incoherent;
else {
cout << "Settings::consolidateCommonSettings(): Error, table set type '"
<< mTableSetTypeName.c_str() << "' is not defined." << endl;
exit(1);
}
}
void Settings::setUPC(bool val){ mUPC = val; }
bool Settings::UPC() const { return mUPC; }
void Settings::setUPCA(unsigned int val){ mUPCA = val; }
unsigned int Settings::UPCA() const { return mUPCA; }
Index: trunk/src/DipoleModel.h
===================================================================
--- trunk/src/DipoleModel.h (revision 490)
+++ trunk/src/DipoleModel.h (revision 491)
@@ -1,99 +1,102 @@
//==============================================================================
// DipoleModel.h
//
-// Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich
+// Copyright (C) 2010-2024 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 <http://www.gnu.org/licenses/>.
//
// Author: Tobias Toll
// Last update:
// $Date$
// $Author$
//==============================================================================
#ifndef DipoleModel_h
#define DipoleModel_h
#include "AlphaStrong.h"
#include "TableGeneratorNucleus.h"
#include "DipoleModelParameters.h"
class TH2F;
class TH1F;
class DipoleModel {
public:
DipoleModel();
virtual ~DipoleModel();
const TableGeneratorNucleus* nucleus() const;
bool configurationExists() const;
virtual void createConfiguration(int)=0;
virtual double dsigmadb2(double, double, double, double)=0;
virtual double bDependence(double);
virtual double bDependence(double, double);
virtual double dsigmadb2ep(double, double, double); // ep
virtual double coherentDsigmadb2(double, double, double) {return 0;}; // eA
virtual void createSigma_ep_LookupTable(double) {/* nothing */};
+ DipoleModelParameters* getParameters(){return mParameters;}
protected:
TableGeneratorNucleus mNucleus;
DipoleModelParameters *mParameters;
AlphaStrong mAs;
bool mConfigurationExists;
bool mIsInitialized;
};
class DipoleModel_bSat : public DipoleModel {
public:
- DipoleModel_bSat();
+ DipoleModel_bSat();
+ DipoleModel_bSat(Settings*);
DipoleModel_bSat(const DipoleModel_bSat&);
DipoleModel_bSat& operator=(const DipoleModel_bSat&);
~DipoleModel_bSat();
void createSigma_ep_LookupTable(double);
void createConfiguration(int);
double dsigmadb2(double, double, double, double);
double bDependence(double, double);
double dsigmadb2ep(double, double, double);
double coherentDsigmadb2(double, double, double);
protected:
TH2F* mBDependence;
private:
double dsigmadb2epForIntegration(double*, double*);
TH1F* mSigma_ep_LookupTable;
};
class DipoleModel_bNonSat : public DipoleModel_bSat {
public:
- DipoleModel_bNonSat();
+ DipoleModel_bNonSat();
+ DipoleModel_bNonSat(Settings*);
~DipoleModel_bNonSat();
double dsigmadb2(double, double, double, double);
double dsigmadb2ep(double, double, double);
double coherentDsigmadb2(double, double, double);
};
class DipoleModel_bCGC : public DipoleModel {
public:
DipoleModel_bCGC();
void createConfiguration(int);
double dsigmadb2(double, double, double, double);
double dsigmadb2ep(double, double, double);
double bDependence(double);
};
#endif
Index: trunk/src/ModeFinderFunctor.h
===================================================================
--- trunk/src/ModeFinderFunctor.h (revision 490)
+++ trunk/src/ModeFinderFunctor.h (revision 491)
@@ -1,70 +1,97 @@
//==============================================================================
// ModeFinderFunctor.h
//
-// Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich
+// Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
//
-// Author: Thomas Ullrich
-// Last update:
+// Author: Tobias Toll
+// Last update:
// $Date$
// $Author$
//==============================================================================
//
// Functor class.
//
// Used by BrentMinimizer1D algotithm to find maxima in cross-section
// in W2 for a given t and Q2.
//==============================================================================
#ifndef ModeFinderFunctor_h
#define ModeFinderFunctor_h
-#include "Math/IFunction.h"
+#include "Math/IFunction.h"
+#include "InclusiveDiffractiveCrossSections.h"
class CrossSection;
class ModeFinderFunctor : public ROOT::Math::IGenFunction {
public:
ModeFinderFunctor();
- ModeFinderFunctor(CrossSection*, double Q2, double vmMass, double tmin, double tmax);
+ ModeFinderFunctor(CrossSection*, double Q2, double vmMass, double tmin, double tmax);
double DoEval(double) const;
- ROOT::Math::IGenFunction* Clone() const;
- void setQ2(double);
+ void setQ2(double);
void setVmMass(double);
void setMaxT(double);
void setMinT(double);
-
-private:
- CrossSection *mCrossSection;
- double mQ2;
+
+ ROOT::Math::IGenFunction* Clone() const;
+
+private:
+ double mQ2;
double mVmMass;
double mMinT;
double mMaxT;
+ CrossSection *mCrossSection;
+};
+
+class InclusiveDiffractionModeFinderFunctor : public ROOT::Math::IGenFunction {
+public:
+ InclusiveDiffractionModeFinderFunctor();
+ InclusiveDiffractionModeFinderFunctor(InclusiveDiffractiveCrossSections* cs, double Q2, double W2, double z, double s, double MX2min, double MX2max, double Q2min, double Q2max, double W2min, double W2max, double ymin, double betamin, double betamax, double mu02);
+ InclusiveDiffractionModeFinderFunctor(InclusiveDiffractiveCrossSections* cs, double Q2, double W2, double z, double MX2min, double MX2max);
+ double DoEval(double) const;
+
+ void setQuarkMass(double);
+
+ ROOT::Math::IGenFunction* Clone() const;
+
+private:
+ InclusiveDiffractiveCrossSections *mIDCrossSection;
+ double mZ;
+ double mQ2;
+ double mMinMX2;
+ double mMaxMX2;
+ double mW2;
+ double mHBeamEnergy;
+ double mEBeamEnergy;
+ double mMq;
+ double mS;
+ double mQ2max, mQ2min, mW2max, mW2min, mYmin, mBetamin, mBetamax, mMu02, mMX2min, mMX2max;
};
class UPCModeFinderFunctor : public ROOT::Math::IGenFunction {
public:
UPCModeFinderFunctor();
UPCModeFinderFunctor(CrossSection*, double vmMass, double hBeamEnergy, double eBeamEnergy);
double DoEval(double) const; // xpom
ROOT::Math::IGenFunction* Clone() const;
private:
CrossSection *mCrossSection;
double mVmMass;
double mHBeamEnergy;
double mEBeamEnergy;
};
#endif
Index: trunk/src/Kinematics.h
===================================================================
--- trunk/src/Kinematics.h (revision 490)
+++ trunk/src/Kinematics.h (revision 491)
@@ -1,105 +1,110 @@
//==============================================================================
// Kinematics.h
//
-// Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich
+// Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich
//
-// This file is part of Sartre.
+// 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.
+// 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich
-// Last update:
+// Last update:
// $Date$
// $Author$
//
//------------------------------------------------------------------------------
//
// Note that Kinematics is only meant for ep and eA diffactive events.
// It is not applicable for UPC kinematics. Use UpcKinematics instead.
//
//==============================================================================
-#ifndef Kinematics_h
-#define Kinematics_h
-#include "Constants.h"
-#include "Settings.h"
-#include "TLorentzVector.h"
-#include "Math/IFunction.h"
-
-class Kinematics {
-public:
- static double xprobe(double Q2, double W2, double vmM);
+#ifndef Kinematics_h
+#define Kinematics_h
+#include "Constants.h"
+#include "Settings.h"
+#include "TLorentzVector.h"
+#include "Math/IFunction.h"
+
+class Kinematics {
+public:
+ static double xprobe(double Q2, double W2, double vmM);
static TLorentzVector electronBeam(double eE, bool upc = false);
- static TLorentzVector hadronBeam(double eH);
- static double s(const TLorentzVector& e, const TLorentzVector& p);
+ static TLorentzVector hadronBeam(double eH);
+ static double s(const TLorentzVector& e, const TLorentzVector& p);
static double s(double eE, double hE, bool upc = false);
- static double x(double Q2, double W2);
- static double y(double Q2, double x, double s);
- static double ymin(double s, double vmM);
- static double ymax(double s, double vmM);
- static double W2(double Q2, double x);
- static double W2(double Q2, double xprobe, double vmM);
- static double W2min(double vmM);
- static double W2max(double s);
- static double Q2min(double y);
- static double Q2max(double s);
- static double xpomeron(double t, double Q2, double W2, double vmM);
- static double tmax(double xpom); // often referred to as tmin implying min |T|
- static double tmax(double t, double Q2, double W2, double vmM);
- static double tmin(double hE); // the smallest t value possible
-
+ static double x(double Q2, double W2);
+ static double y(double Q2, double x, double s);
+ static double ymin(double s, double vmM);
+ static double ymax(double s, double vmM);
+ static double W2(double Q2, double x);
+ static double W2(double Q2, double xprobe, double vmM);
+ static double W2min(double vmM);
+ static double W2max(double s);
+ static double W2max(double s, double Q2, double MX);
+ static double Q2min(double y);
+ static double Q2max(double s);
+ static double xpomeron(double t, double Q2, double W2, double vmM);
+ static double MX2(double Q2, double beta, double t);
+ static double tmax(double xpom); // often referred to as tmin implying min |T|
+ static double tmax(double t, double Q2, double W2, double vmM);
+ static double tmin(double hE); // the smallest t value possible
+ static double betamin(double Q2, double s, double MX, double t);
static double Egamma(double xpom, double t, double vmM, double hBeamEnergy, double eBeamEnergy, double MY2minusM2 = 0);
-
+
static bool validUPC(double hBeamEnergy, double eBeamEnergy, double t,
- double xpom, double vmMass, bool verbose = false); // UPC only
- static bool valid(double s, double t, double Q2, double W2, double vmMass,
- bool useTrueXp = false,
- bool verbose = false);
+ double xpom, double vmMass, bool verbose = false); // UPC only
+ static bool valid(double s, double t, double Q2, double W2, double vmMass,
+ bool useTrueXp = false,
+ bool verbose = false);
+ static bool valid(double s, double beta, double Q2, double W2, double z, double MC,
+ bool useTrueXp = false,
+ bool verbose = false);
static bool error();
-
+
static double xpomMin(double massVM, double t, TLorentzVector hBeam, TLorentzVector eBeam, double MY2minusM2 = 0); // UPC only
-
+
private:
static double xpomMin(double s, double vmM, double t); // UPC only
-
-private:
+
+private:
static bool mError;
-
+
static double mXpomMin;
static double mTold;
static bool mXpomMinIsEvaluated;
-};
+};
-//-------------------------------------------------------------------------------
-//
+//-------------------------------------------------------------------------------
+//
// Helper class needed to find root in
// Kinematics::validUPC()
//
-//-------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------
class LowerXpomeronFormula : public ROOT::Math::IBaseFunctionOneDim
{
-public:
+public:
double DoEval(double) const;
ROOT::Math::IBaseFunctionOneDim* Clone() const;
void calculateValidRange(double&, double&);
-public:
+public:
double mT;
double mVmMass2;
double mXpomMin;
double mMY2;
TLorentzVector mElectronBeam;
TLorentzVector mHadronBeam;
double mMY2minusM2;
};
-#endif
+#endif
Index: trunk/src/FinalStateGenerator.cpp
===================================================================
--- trunk/src/FinalStateGenerator.cpp (revision 490)
+++ trunk/src/FinalStateGenerator.cpp (revision 491)
@@ -1,50 +1,51 @@
//==============================================================================
// FinalStateGenerator.cpp
//
// Copyright (C) 2010-2019 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich
// Last update:
// $Date$
// $Author$
//==============================================================================
#include "FinalStateGenerator.h"
#include "Event.h"
#include <cmath>
using namespace std;
FinalStateGenerator::FinalStateGenerator()
{
mT = 0;
mQ2 = 0;
mY = 0;
mS = 0;
mMY2 = 0;
- mMassVM = 0;
+ mMX = 0;
+ mMassVM = 0;
mA = 0;
mIsIncoherent = false;
}
FinalStateGenerator::~FinalStateGenerator() {/* no op */}
bool FinalStateGenerator::isValid(TLorentzVector & v) const
{
for (int i=0; i<4; i++) {
if (std::isnan(v[0])) return false;
if (std::isinf(v[0])) return false;
}
return true;
}
Index: trunk/src/Nucleus.h
===================================================================
--- trunk/src/Nucleus.h (revision 490)
+++ trunk/src/Nucleus.h (revision 491)
@@ -1,76 +1,76 @@
//==============================================================================
// Nucleus.h
//
-// Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich
+// Copyright (C) 2010-2019 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.
+// 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich
-// Last update:
+// Last update:
// $Date$
// $Author$
//==============================================================================
-#ifndef Nucleus_h
-#define Nucleus_h
-#include <string>
+#ifndef Nucleus_h
+#define Nucleus_h
+#include <string>
#include <memory>
using namespace std;
-
-class TH1D;
-
-class Nucleus {
-public:
- Nucleus();
- Nucleus(unsigned int A);
- Nucleus(const Nucleus&);
- virtual ~Nucleus();
-
- Nucleus& operator=(const Nucleus&);
-
- virtual void init(unsigned int A);
-
- double T(double b) const; // b in fm, returns in GeV^2
- double TofProton(double b);
- unsigned int A() const;
- unsigned int Z() const;
- float spin() const; // in hbar
- double radius() const; // in fm
- string name() const;
- int pdgID() const; // id of this nucleus
- int pdgID(int Z, int A) const;
- double nuclearMass() const;
- void normalizationOfT(double eps = 1.e-8); // for checks only
+
+class TH1D;
+
+class Nucleus {
+public:
+ Nucleus();
+ Nucleus(unsigned int A);
+ Nucleus(const Nucleus&);
+ virtual ~Nucleus();
+
+ Nucleus& operator=(const Nucleus&);
+
+ virtual void init(unsigned int A);
+
+ double T(double b) const; // b in fm, returns in GeV^2
+ double TofProton(double b);
+ unsigned int A() const;
+ unsigned int Z() const;
+ float spin() const; // in hbar
+ double radius() const; // in fm
+ string name() const;
+ int pdgID() const; // id of this nucleus
+ int pdgID(int Z, int A) const;
+ double atomicMass() const;
+ void normalizationOfT(double eps = 1.e-8); // for checks only
double rho0() const; //in fm
-protected:
- double rho(double, double);
- double rhoForIntegration(double*, double*);
- double TForIntegration(double*, double*) const;
-
-protected:
- unsigned int mA;
- unsigned int mZ;
- float mSpin;
- double mMass; // nuclear mass in GeV
+protected:
+ double rho(double, double);
+ double rhoForIntegration(double*, double*);
+ double TForIntegration(double*, double*) const;
+
+protected:
+ unsigned int mA;
+ unsigned int mZ;
+ float mSpin;
+ double mMass; // atomic mass in GeV
double mRadius; // fm - Wood-Saxon
- double mSurfaceThickness; // fm - Wood-Saxon
+ double mSurfaceThickness; // fm - Wood-Saxon
double mRho0; // fm^-3 - Wood-Saxon
double mOmega; // Wood-Saxon
double mHulthenA; // for Hulthen distribution
- double mHulthenB;
+ double mHulthenB;
string mName;
unique_ptr<TH1D> mLookupTable; // T lookup table
};
-
-#endif
-
+
+#endif
+
Index: trunk/src/CMakeLists.txt
===================================================================
--- trunk/src/CMakeLists.txt (revision 490)
+++ trunk/src/CMakeLists.txt (revision 491)
@@ -1,163 +1,169 @@
#===============================================================================
# CMakeLists.txt (src)
#
-# Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich
-#
+# Copyright (C) 2010-2024 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 <http://www.gnu.org/licenses/>.
#
# Author: Thomas Ullrich
# Last update:
# $Date$
# $Author$
#===============================================================================
include(ExternalProject)
cmake_minimum_required (VERSION 3.1)
#
# Compiler flags for release and debug version
#
set(CMAKE_C_FLAGS "-W")
set(CMAKE_C_FLAGS_DEBUG "-g")
set(CMAKE_C_FLAGS_RELEASE "-O")
message("COMPILER = ${CMAKE_CXX_COMPILER_ID}")
-set(CMAKE_CXX_FLAGS "-W -Wall -Wextra -Wpedantic -Wno-long-long")
-if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+set(CMAKE_CXX_FLAGS "-W -Wall -Wextra -pedantic -Wno-long-long")
+if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-potentially-evaluated-expression")
endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_RELEASE "-O")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
#
# Find external required packages
# (see also FindGSL.cmake and FindROOT.cmke in cmake/modules)
# Herer we need only the root library to create the table
# tools.
#
# GSL
find_package(GSL REQUIRED)
include_directories(${GSL_INCLUDE_DIR})
# ROOT
find_package(ROOT REQUIRED)
include_directories(${ROOT_INCLUDE_DIR})
set(LIBS ${LIBS} ${ROOT_LIBRARIES})
+# PYTHIA8
+find_package(Pythia8 REQUIRED)
+include_directories(${PYTHIA8_INCLUDE_DIR})
+set(LIBS ${LIBS} ${PYTHIA8_LIBRARIES})
+
#BOOST
if (MULTITHREADED)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
find_package(Boost 1.39 COMPONENTS thread REQUIRED)
- if (Boost_FOUND)
+ if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIR})
endif(Boost_FOUND)
endif (MULTITHREADED)
#
# Include files from sartre package
#
include_directories(${PROJECT_SOURCE_DIR}/src)
include_directories(${PROJECT_SOURCE_DIR}/gemini)
include_directories(${PROJECT_SOURCE_DIR}/cuba)
#
# Cuba is built using the autoconf shipped with it
#
ExternalProject_Add(
cuba
DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/cuba ${PROJECT_BINARY_DIR}/cuba
SOURCE_DIR ${PROJECT_BINARY_DIR}/cuba
PREFIX ${PROJECT_BINARY_DIR}/cuba
CONFIGURE_COMMAND ${PROJECT_BINARY_DIR}/cuba/configure --prefix=${PROJECT_BINARY_DIR}/cuba/build
BUILD_COMMAND make lib
BUILD_IN_SOURCE 1
)
#
# Defines source files for sartre library
#
set(SARTRE_SRC "AlphaStrong.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "Amplitudes.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "BreakupProduct.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "CrossSection.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "DglapEvolution.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "DipoleModel.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "DipoleModelParameters.cpp")
+set(SARTRE_SRC ${SARTRE_SRC} "EicSmearFormatWriter.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "Event.cpp")
+set(SARTRE_SRC ${SARTRE_SRC} "EventGeneratorSettings.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "ExclusiveFinalStateGenerator.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "FinalStateGenerator.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "FrangibleNucleus.cpp")
-set(SARTRE_SRC ${SARTRE_SRC} "EventGeneratorSettings.cpp")
+set(SARTRE_SRC ${SARTRE_SRC} "InclusiveDiffractionSettings.cpp")
+set(SARTRE_SRC ${SARTRE_SRC} "InclusiveDiffractiveCrossSections.cpp")
+set(SARTRE_SRC ${SARTRE_SRC} "InclusiveFinalStateGenerator.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "Integrals.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "Kinematics.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "ModeFinderFunctor.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "Nucleon.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "Nucleus.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "PhotonFlux.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "Sartre.cpp")
+set(SARTRE_SRC ${SARTRE_SRC} "SartreInclusiveDiffraction.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "Settings.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "Table.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "TableCollection.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "TableGeneratorNucleus.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "TableGeneratorSettings.cpp")
-set(SARTRE_SRC ${SARTRE_SRC} "WaveOverlap.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "TwoBodyVectorMesonDecay.cpp")
-set(SARTRE_SRC ${SARTRE_SRC} "EicSmearFormatWriter.cpp")
set(SARTRE_SRC ${SARTRE_SRC} "VectorMesonDecayMass.cpp")
+set(SARTRE_SRC ${SARTRE_SRC} "WaveOverlap.cpp")
+
add_library(sartre ${SARTRE_SRC})
#
# Table tools (all stand alone programs)
#
add_executable(tableInspector tableInspector.cpp)
add_executable(tableMerger tableMerger.cpp)
add_executable(tableQuery tableQuery.cpp)
add_executable(tableDumper tableDumper.cpp)
add_executable(tableVarianceMaker tableVarianceMaker.cpp)
-add_executable(tablePriority tablePriority.cpp)
target_link_libraries(tableInspector sartre ${LIBS})
target_link_libraries(tableMerger sartre ${LIBS})
target_link_libraries(tableQuery sartre ${LIBS})
target_link_libraries(tableDumper sartre ${LIBS})
target_link_libraries(tableVarianceMaker sartre ${LIBS})
-target_link_libraries(tablePriority sartre ${LIBS})
add_dependencies(tableInspector sartre)
add_dependencies(tableMerger sartre)
add_dependencies(tableQuery sartre)
add_dependencies(tableDumper sartre)
add_dependencies(tableVarianceMaker sartre)
-add_dependencies(tablePriority sartre)
#
# Install library and include files (make install) within
# the distribution tree. Top level CMakeLists.txt will install
# Sartre in final destination.
#
install(TARGETS sartre DESTINATION sartre/lib)
install(FILES "${PROJECT_BINARY_DIR}/cuba/build/lib/libcuba.a" DESTINATION sartre/lib)
FILE(GLOB AllIncludeFiles *.h)
install(FILES ${AllIncludeFiles} DESTINATION sartre/include)
install(FILES "${PROJECT_BINARY_DIR}/cuba/build/include/cuba.h" DESTINATION sartre/include)
install(TARGETS tableInspector DESTINATION sartre/bin)
install(TARGETS tableMerger DESTINATION sartre/bin)
install(TARGETS tableQuery DESTINATION sartre/bin)
install(TARGETS tableDumper DESTINATION sartre/bin)
install(TARGETS tableVarianceMaker DESTINATION sartre/bin)
-install(TARGETS tablePriority DESTINATION sartre/bin)
Index: trunk/src/FinalStateGenerator.h
===================================================================
--- trunk/src/FinalStateGenerator.h (revision 490)
+++ trunk/src/FinalStateGenerator.h (revision 491)
@@ -1,59 +1,54 @@
//==============================================================================
// FinalStateGenerator.h
//
// Copyright (C) 2010-2019 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich
// Last update:
// $Date$
// $Author$
//==============================================================================
#ifndef FinalStateGenerator_h
#define FinalStateGenerator_h
#include "TLorentzVector.h"
class Event;
class FinalStateGenerator {
public:
FinalStateGenerator();
virtual ~FinalStateGenerator();
-
- virtual bool generate(int id, double t, double y, double Q2,
- bool isIncoherent, int A, Event *event) = 0;
-
- virtual bool generate(int id, double t, double xpom,
- bool isIncoherent, int A, Event *event) = 0;
-
- bool isValid(TLorentzVector &) const;
+
+ bool isValid(TLorentzVector &) const;
protected:
double mT;
double mQ2;
double mY;
double mS;
- double mXp; //UPC
- double mEgam; //UPC
+ double mXp; // UPC
+ double mEgam; // UPC
+ double mMX; // inclusive diffraction
double mMY2;
double mMassVM;
double mA;
bool mIsIncoherent;
TLorentzVector mElectronBeam;
TLorentzVector mHadronBeam;
};
#endif
Index: trunk/src/PhotonFlux.cpp
===================================================================
--- trunk/src/PhotonFlux.cpp (revision 490)
+++ trunk/src/PhotonFlux.cpp (revision 491)
@@ -1,273 +1,273 @@
//==============================================================================
// PhotonFlux.cpp
//
// Copyright (C) 2010-2019 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich, Tobias Toll
// Last update:
// $Date$
// $Author$
//==============================================================================
#include "PhotonFlux.h"
#include "Constants.h"
#include "Kinematics.h"
#include "EventGeneratorSettings.h"
#include "Nucleus.h"
#include <cmath>
#include "TF1.h"
#include "Math/Functor.h"
#include "Math/IntegratorMultiDim.h"
#include "Math/WrappedTF1.h"
#include "Math/GaussIntegrator.h"
#define PR(x) cout << #x << " = " << (x) << endl;
PhotonFlux::PhotonFlux()
{
mS = 0;
mIsUPC = false;
mSettings = EventGeneratorSettings::instance();
if (mSettings->UPC()){
mNucleusUPC = new Nucleus(mSettings->UPCA());
mNucleus = new Nucleus(mSettings->A());
if (mSettings->UPCA()>1 && mSettings->A()>1) {
cout << "PhotonFlux::PhotonFlux(): Calculating TAA table ... ";
setupTAAlookupTable();
cout << "done." << endl;
}
mEBeamEnergy = mSettings->electronBeamEnergy(); // the beam that shines
mIsUPC = true;
}
mSIsSet = false;
}
PhotonFlux::PhotonFlux(double s)
{
mS = s;
mIsUPC = false;
mSettings = EventGeneratorSettings::instance();
if (mSettings->UPC()) {
mNucleusUPC = new Nucleus(mSettings->UPCA());
mNucleus = new Nucleus(mSettings->A());
if (mSettings->UPCA()>1 && mSettings->A()>1){
cout << "PhotonFlux::PhotonFlux(): Calculating TAA table ... ";
setupTAAlookupTable();
cout << "done" << endl;
}
mEBeamEnergy = mSettings->electronBeamEnergy(); //The beam that shines
mIsUPC = true;
cout<<"PhotonFlux::PhotonFlux(): Warning Sartre is not yet ready for UPC..." << endl;
}
mSIsSet = true;
}
void PhotonFlux::setS(double s)
{
mS = s;
mSIsSet = true;
}
double PhotonFlux::operator()(double Q2, double W2, GammaPolarization p) const
{
if (!mSIsSet) cout<<"Warning in PhotonFlux::operator() s is not set!"<<endl;
if (p == transverse)
return fluxTransverse(Q2, W2);
else
return fluxLongitudinal(Q2, W2);
}
double PhotonFlux::operator()(double Egamma) const
{
if (!mSIsSet) cout << "PhotonFlux::operator(): Warning, s is not set!" << endl;
return nuclearPhotonFlux(Egamma);
}
double PhotonFlux::fluxTransverse(double Q2, double W2) const
{
//
// Transverse photon flux
//
double y = Kinematics::y(Q2, Kinematics::x(Q2, W2), mS);
if (y<0 || y>1 || Kinematics::error()) return 0;
if (Q2 > Kinematics::Q2max(mS)) return 0;
double result = alpha_em/(2*M_PI*Q2*mS*y);
result *= (1 + (1-y)*(1-y)) - (2*(1-y)*Kinematics::Q2min(y)/Q2);
return result;
}
double PhotonFlux::fluxLongitudinal(double Q2, double W2) const
{
//
// Longitudinal photon flux
//
double y = Kinematics::y(Q2, Kinematics::x(Q2, W2), mS);
if (y<0 || y>1 || Kinematics::error()) return 0;
if (Q2 > Kinematics::Q2max(mS)) return 0;
double result = alpha_em/(2*M_PI*Q2*mS*y);
result *= 2*(1-y);
return result;
}
double PhotonFlux::nuclearPhotonFlux(double Egamma) const
{
if (Egamma < 0) {
if (mSettings->verbose() && mSettings->verboseLevel() > 4)
cout << "PhotonFlux::nuclearPhotonFlux(): Warning, negative Egamma as argument.\n"
<< " Return 0 for photon flux." << endl;
return 0;
}
double bmin = 0.;
double bmax = 1e10; //Could be arbitrary large (TF1 doesn't care)
TF1 fluxFunction("fluxFunction", this, &PhotonFlux::unintegratedNuclearPhotonFlux, bmin, bmax, 1);
fluxFunction.SetParameter(0, Egamma);
ROOT::Math::WrappedTF1 wrappedFluxFunction(fluxFunction);
ROOT::Math::GaussIntegrator fluxIntegrator;
fluxIntegrator.SetFunction(wrappedFluxFunction);
fluxIntegrator.SetAbsTolerance(0.);
fluxIntegrator.SetRelTolerance(1e-5);
return fluxIntegrator.IntegralUp(bmin)/hbarc; //dN/dEgamma GeV^-1
}
double PhotonFlux::unintegratedNuclearPhotonFlux(double* var, double* par) const
{
//
// https://arxiv.org/abs/1607.03838v1
//
double b = var[0]; //fm
double eGamma = par[0]; //GeV
int Apom = mNucleus->A();
int AUPC = mNucleusUPC->A();
double Z = mNucleusUPC->Z();
- double ebeamMass = mNucleusUPC->nuclearMass()/mNucleusUPC->A(); //Mass per nucleon //GeV
+ double ebeamMass = mNucleusUPC->atomicMass()/mNucleusUPC->A(); //Mass per nucleon //GeV
double beamLorentzGamma = mEBeamEnergy/ebeamMass;
double beamLorentzGamma2 = beamLorentzGamma*beamLorentzGamma;
double xi = eGamma*b/hbarc/beamLorentzGamma; //GeV0
double K0 = TMath::BesselK0(xi);
double K1 = TMath::BesselK1(xi);
double prefactor = Z*Z*alpha_em/(M_PI*M_PI)*eGamma/beamLorentzGamma2; //GeV1
double N = prefactor*(K1*K1+K0*K0/beamLorentzGamma2); //GeV1
//Spectrum is calculated under the assumption that there is no
//hadronic interaction between the beam particles.
//Therefore it has to be multiplied by the probability for this:
double Pnohad = 1;
if (Apom>1 && AUPC>1) { //nucleus-nucleus interaction
Pnohad = exp(-sigma_nn(mS)*mTAA_of_b->Interpolate(b)); //GeV0
}
else if (Apom == 1 && AUPC > 1) { //proton-nucleus
Pnohad=exp(-sigma_nn(mS)*mNucleusUPC->T(b));
}
else if (Apom > 1 && AUPC == 1) { //nucleus-proton
Pnohad = exp(-sigma_nn(mS)*mNucleus->T(b));
}
else { //proton-proton
double b02 = 19.8; //GeV^-2
double scamp = 1-exp(-b*b/hbarc2/2./b02);
Pnohad = scamp*scamp;
}
double result = 2*M_PI*b/hbarc*N*Pnohad; //GeV0
return result;
}
void PhotonFlux::setupTAAlookupTable()
{
double rbhigh = upperIntegrationLimit*(mNucleus->radius()+mNucleusUPC->radius());
mTAA_of_b = new TH1D("mTAA_of_b", "mTAA_of_b", 1000, 0, rbhigh);
for (unsigned int i=1; i<=1000; i++) {
double b = mTAA_of_b->GetBinCenter(i);
mTAA_of_b->SetBinContent(i, TAA(b));
}
}
double PhotonFlux::sigma_nn(double s) const {
//
// For parameters see
// http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20080014212.pdf table 2
//
// Following KNSGB: http://arxiv.org/abs/1607.03838v1 (eq.6)
//
double Z = 33.73; //mb
double B = 0.2838; //mb
double s0 = 1.;//GeV2
double Y1 = 13.67; //mb
double s1 = 1.; //GeV2
double eta1 = 0.412;
double Y2 = 7.77; //mb
double eta2 = 0.5626;
double result = Z+B*log(s/s0)*log(s/s0)+Y1*pow(s1/s, eta1)-Y2*pow(s1/s, eta2); //mb = 1e-3b = 1e-1 fm2
result *= 1e-1; //fm2 (1 barn = 1e2 fm2)
return result/hbarc2; //GeV^-2
}
double PhotonFlux::TAA(double b)
{
//
// Integral over dr^2=2*pi*r*dr
//
double rbhigh=upperIntegrationLimit*(mNucleus->radius()+mNucleusUPC->radius());
double lo[2] = {0., 0.}; //r, theta
double hi[2] = {rbhigh, 2*M_PI};
ROOT::Math::Functor wf(this, &PhotonFlux::TAAForIntegration, 2);
ROOT::Math::IntegratorMultiDim ig(ROOT::Math::IntegrationMultiDim::kADAPTIVE);
ig.SetFunction(wf);
ig.SetAbsTolerance(0.);
ig.SetRelTolerance(1e-4);
mB=b;
double result = ig.Integral(lo, hi); //GeV^3*fm
result /= hbarc; //GeV^2
return result;
}
double PhotonFlux::TAAForIntegration(const double* var) const
{
double r = var[0]; //fm
double phi = var[1];
double b = mB; //fm
//Put A1 in the origin, and A2 on the y-axis at distance b:
double arg1 = r;
double arg2 = sqrt(r*r+b*b-2*b*r*sin(phi)); //fm
double T1 = mNucleusUPC->T(arg1); //GeV^2
double T2 = mNucleus->T(arg2); //GeV^2
return r/hbarc*T1*T2; //GeV^3
}
Index: trunk/src/Nucleus.cpp
===================================================================
--- trunk/src/Nucleus.cpp (revision 490)
+++ trunk/src/Nucleus.cpp (revision 491)
@@ -1,355 +1,353 @@
//==============================================================================
// Nucleus.cpp
//
-// Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich
+// Copyright (C) 2010-2019 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.
+// 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich
-// Last update:
+// Last update:
// $Date$
// $Author$
//==============================================================================
-#include "Nucleus.h"
-#include "Constants.h"
-#include "TF1.h"
-#include "TH1.h"
+#include "Nucleus.h"
+#include "Constants.h"
+#include "TF1.h"
+#include "TH1.h"
#include "TH1D.h"
#include <cmath>
-#include <cstdlib>
-
-#define PR(x) cout << #x << " = " << (x) << endl;
+#include <cstdlib>
+#include "Math/WrappedTF1.h"
+#include "Math/GaussIntegrator.h"
+
+
+#define PR(x) cout << #x << " = " << (x) << endl;
Nucleus::Nucleus()
-{
- mA = mZ = 0;
- mRadius = 0;
- mSpin = 0;
- mSurfaceThickness = 0;
- mRho0 = 0;
- mOmega = 0;
+{
+ mA = mZ = 0;
+ mRadius = 0;
+ mSpin = 0;
+ mSurfaceThickness = 0;
+ mRho0 = 0;
+ mOmega = 0;
mMass = 0;
mHulthenA = 0;
mHulthenB = 0;
}
-
-Nucleus::Nucleus(unsigned int A)
+
+Nucleus::Nucleus(unsigned int A)
{
mA = mZ = 0;
mRadius = 0;
mSpin = 0;
mSurfaceThickness = 0;
mRho0 = 0;
mOmega = 0;
mMass = 0;
mHulthenA = 0;
mHulthenB = 0;
Nucleus::init(A);
-}
-
-Nucleus& Nucleus::operator=(const Nucleus& n)
-{
+}
+
+Nucleus& Nucleus::operator=(const Nucleus& n)
+{
if (this != &n) {
mA = n.mA;
- mZ = n.mZ;
- mRadius = n.mRadius;
- mSpin = n.mSpin;
- mSurfaceThickness = n.mSurfaceThickness;
- mRho0 = n.mRho0;
- mOmega = n.mOmega;
- mMass = n.mMass;
- mName = n.mName;
+ mZ = n.mZ;
+ mRadius = n.mRadius;
+ mSpin = n.mSpin;
+ mSurfaceThickness = n.mSurfaceThickness;
+ mRho0 = n.mRho0;
+ mOmega = n.mOmega;
+ mMass = n.mMass;
+ mName = n.mName;
mHulthenA = n.mHulthenA;
mHulthenB = n.mHulthenB;
mLookupTable = unique_ptr<TH1D>(new TH1D(*(n.mLookupTable)));
- mLookupTable->SetDirectory(0);
- }
- return *this;
-}
-
-Nucleus::Nucleus(const Nucleus& n)
-{
+ mLookupTable->SetDirectory(0);
+ }
+ return *this;
+}
+
+Nucleus::Nucleus(const Nucleus& n)
+{
mA = n.mA;
- mZ = n.mZ;
- mRadius = n.mRadius;
- mSpin = n.mSpin;
- mSurfaceThickness = n.mSurfaceThickness;
- mRho0 = n.mRho0;
- mOmega = n.mOmega;
- mMass = n.mMass;
- mName = n.mName;
+ mZ = n.mZ;
+ mRadius = n.mRadius;
+ mSpin = n.mSpin;
+ mSurfaceThickness = n.mSurfaceThickness;
+ mRho0 = n.mRho0;
+ mOmega = n.mOmega;
+ mMass = n.mMass;
+ mName = n.mName;
mHulthenA = n.mHulthenA;
mHulthenB = n.mHulthenB;
mLookupTable = unique_ptr<TH1D>(new TH1D(*(n.mLookupTable)));
mLookupTable->SetDirectory(0);
-}
-
+}
+
Nucleus::~Nucleus()
{
//
// This is a temorary fix of a problem in the code that is not understood.
// In the table generation code after all is calculated the ~TH1 of the
// look up table histogram causes a crash. This appears (?) to be related
// to issues in GSL and ROOT. Releasing the pointer causes a memory leak
// but this is not a big problem since it happens at the end of the program.
//
mLookupTable.release();
}
+
+void Nucleus::init(unsigned int A)
+{
+ mA = A;
-void Nucleus::init(unsigned int A)
-{
- mA = A;
-
- //
- // Set the parameters of the nucleus
- // Woods-Saxon parameter are from Ramona Vogt's paper on nuclear geometry (table 1).
- // The parametrization is a 3 parameter fermi model (or 2 parameter with omega=0).
- // One exception is the deuteron where a Hulthen function is used (nucl-ex/0701025v1).
+ //
+ // Set the parameters of the nucleus
+ // Woods-Saxon parameter are from Ramona Vogt's paper on nuclear geometry (table 1)
+ // One exception is the deuteron were a Hulthen function is used (nucl-ex/0701025v1).
// All version are defined such that Integral(d3r rho(r)) = A
- // Masses from https://wwwndc.jaea.go.jp/NuC/
//
- const double unifiedAtomicMass = 0.931494013;
- switch (mA) {
- case 208: // Pb
- mZ = 82;
- mRadius = 6.624;
- mSurfaceThickness = 0.549;
- mOmega = 0;
- mRho0 = 0.160;
- mName = "Pb";
- mMass = 207.976651189*unifiedAtomicMass-mZ*electronMass;
- mSpin = 0;
- break;
- case 197: // Au
- mZ = 79;
- mRadius = 6.38;
- mSurfaceThickness = 0.535;
- mOmega = 0;
- mRho0 = 0.1693;
- mName = "Au";
- mMass = 196.966568812*unifiedAtomicMass-mZ*electronMass;
- mSpin = 3./2.;
- break;
- case 110: // Cd
- mZ = 48;
- mRadius = 5.33;
- mSurfaceThickness = 0.535;
- mOmega = 0;
- mRho0 = 0.1577;
- mName = "Cd";
- mMass = 109.903004927*unifiedAtomicMass-mZ*electronMass;
- mSpin = 0;
+ const double unifiedAtomicMass = 0.931494013;
+ switch (mA) {
+ case 208: // Pb
+ mZ = 82;
+ mRadius = 6.624;
+ mSurfaceThickness = 0.549;
+ mOmega = 0;
+ mRho0 = 0.160;
+ mName = "Pb";
+ mMass = 207.2*unifiedAtomicMass;
+ mSpin = 1./2.;
+ break;
+ case 197: // Au
+ mZ = 79;
+ mRadius = 6.38;
+ mSurfaceThickness = 0.535;
+ mOmega = 0;
+ mRho0 = 0.1693;
+ mName = "Au";
+ mMass = 196.96655*unifiedAtomicMass;
+ mSpin = 3./2.;
+ break;
+ case 110: // Cd
+ mZ = 48;
+ mRadius = 5.33;
+ mSurfaceThickness = 0.535;
+ mOmega = 0;
+ mRho0 = 0.1577;
+ mName = "Cd";
+ mMass = 112.411*unifiedAtomicMass;
+ mSpin = 1./2.;
+ break;
+ case 63: // Cu
+ mZ = 29;
+ mRadius = 4.214;
+ mSurfaceThickness = 0.586;
+ mOmega = 0;
+ mRho0 = 0.1701;
+ mName = "Cu";
+ mMass = 63.546*unifiedAtomicMass;
+ mSpin = 3./2.;
+ break;
+ case 40: // Ca
+ mZ = 20;
+ mRadius = 3.766;
+ mSurfaceThickness = 0.586;
+ mOmega = -0.161;
+ mRho0 = 0.1699;
+ mName = "Ca";
+ mMass= 40.078*unifiedAtomicMass;
+ mSpin = 7./2.;
+ break;
+ case 27: // Al
+ mZ = 13;
+ mRadius = 3.07;
+ mSurfaceThickness = 0.519;
+ mOmega = 0;
+ mRho0 = 0.1739;
+ mName = "Al";
+ mMass = 26.981538*unifiedAtomicMass;
+ mSpin = 5./2.;
break;
- case 90: // Zr
- mZ = 40;
- mRadius = 4.9736093; // from R. Vogt 1.19*A^(1/3)-1.61*A^(-1/3)
- mSurfaceThickness = 0.54; // from R. Vogt
- mOmega = 0; // from R. Vogt
- mRho0 = 0.15643742;
- mName = "Zr";
- mMass = 89.904696939*unifiedAtomicMass-mZ*electronMass;
- mSpin = 0;
+ case 16: // O
+ mZ = 8;
+ mRadius = 2.608;
+ mSurfaceThickness = 0.513;
+ mOmega = -0.051;
+ mRho0 = 0.1654;
+ mName = "O";
+ mMass = 15.9994*unifiedAtomicMass;
+ mSpin = 5./2.;
break;
- case 63: // Cu
- mZ = 29;
- mRadius = 4.214;
- mSurfaceThickness = 0.586;
- mOmega = 0;
- mRho0 = 0.1701;
- mName = "Cu";
- mMass = 62.929597770*unifiedAtomicMass-mZ*electronMass;
- mSpin = 3./2.;
- break;
- case 40: // Ca
- mZ = 20;
- mRadius = 3.766;
- mSurfaceThickness = 0.586;
- mOmega = -0.161;
- mRho0 = 0.1699;
- mName = "Ca";
- mMass= 39.962590863*unifiedAtomicMass-mZ*electronMass;
- mSpin = 0;
- break;
- case 27: // Al
- mZ = 13;
- mRadius = 3.07;
- mSurfaceThickness = 0.519;
- mOmega = 0;
- mRho0 = 0.1739;
- mName = "Al";
- mMass = 26.981538578*unifiedAtomicMass-mZ*electronMass;
- mSpin = 5./2.;
- break;
- case 16: // O
- mZ = 8;
- mRadius = 2.608;
- mSurfaceThickness = 0.513;
- mOmega = -0.051;
- mRho0 = 0.1654;
- mName = "O";
- mMass = 15.99491461957*unifiedAtomicMass-mZ*electronMass;
- mSpin = 0;
- break;
case 2: // D
mZ = 1;
mHulthenA = 0.456;
mHulthenB = 2.36;
mRho0 = 0.39946312;
mName = "D";
- mMass = 2.01410177812*unifiedAtomicMass-mZ*electronMass;
+ mMass = 2.014102*unifiedAtomicMass;
mSpin = 1;
mRadius = 2.116; // not used for density function - taken from Jager et al.
break;
case 1:
- // When generating this nucleus, only one nucleon is put at (0, 0, 0)
- mZ = 1;
- mRadius = 1.;
- mMass = protonMass; // 1.00794*unifiedAtomicMass
- mName = "p";
- //The following 3 are dummies, needed for radial distribution etc.:
- mSurfaceThickness = 0.513;
- mOmega = -0.051;
- mRho0 = 0.1654;
- mSpin = 1./2.;
- break;
- default:
- cout << "Nucleus::init(): Error, cannot handle A=" << mA << ", no parameters defined for this mass number." << endl;
- exit(1);
- break;
- }
-
- //
- // Generate lookup table for overlap integral T
- // (b and z in fm)
- //
- double range = 3*mRadius;
+ // When generating this nucleus, only one nucleon is put at (0, 0, 0)
+ mZ = 1;
+ mRadius = 1.;
+ mMass = protonMass; // 1.00794*unifiedAtomicMass
+ mName = "p";
+ //The following 3 are dummies, needed for radial distribution etc.:
+ mSurfaceThickness = 0.513;
+ mOmega = -0.051;
+ mRho0 = 0.1654;
+ mSpin = 1./2.;
+ break;
+ default:
+ cout << "Nucleus::init(): Error, cannot handle A=" << mA << ", no parameters defined for this mass number." << endl;
+ exit(1);
+ break;
+ }
+
+ //
+ // Generate lookup table for overlap integral T
+ // (b and z in fm)
+ //
+ double range = 3*mRadius;
TF1* funcToIntegrate = new TF1("funcToIntegrate",this, &Nucleus::rhoForIntegration, -range, range, 1);
int nbins = 5000; // size of lookup table
mLookupTable = unique_ptr<TH1D>(new TH1D("mLookupTable","T lookup table", nbins, 0, range));
mLookupTable->SetDirectory(0);
+ ROOT::Math::WrappedTF1* WFlookup=new ROOT::Math::WrappedTF1(*funcToIntegrate);
+ ROOT::Math::GaussIntegrator GIlookup;
+ GIlookup.SetFunction(*WFlookup);
+ GIlookup.SetRelTolerance(1e-8);
+
for (int i=1; i<=nbins; i++) {
- double b = mLookupTable->GetBinCenter(i);
- funcToIntegrate->SetNpx(1000);
- funcToIntegrate->SetParameter(0, b);
- double res = funcToIntegrate->Integral(-range, range, 1e-8);
- mLookupTable->SetBinContent(i, res);
- }
+ double b = mLookupTable->GetBinCenter(i);
+ funcToIntegrate->SetNpx(1000);
+ funcToIntegrate->SetParameter(0, b);
+ // double res = funcToIntegrate->Integral(-range, range, 1e-8);
+ double res = GIlookup.Integral(-range, range);
+ mLookupTable->SetBinContent(i, res);
+ }
delete funcToIntegrate;
+ delete WFlookup;
}
-
-unsigned int Nucleus::A() const { return mA; }
-
-unsigned int Nucleus::Z() const { return mZ; }
-
-float Nucleus::spin() const { return mSpin; }
-
-double Nucleus::nuclearMass() const { return mMass; }
-
-string Nucleus::name() const { return mName; }
-
-double Nucleus::radius() const { return mRadius; }
-
-double Nucleus::rho(double b, double z) // returns value in units of fm^-3
-{
- // b and z in fm
+
+unsigned int Nucleus::A() const { return mA; }
+
+unsigned int Nucleus::Z() const { return mZ; }
+
+float Nucleus::spin() const { return mSpin; }
+
+double Nucleus::atomicMass() const { return mMass; }
+
+string Nucleus::name() const { return mName; }
+
+double Nucleus::radius() const { return mRadius; }
+
+double Nucleus::rho(double b, double z) // returns value in units of fm^-3
+{
+ // b and z in fm
double r = sqrt(b*b+z*z);
if (mA == 2) {
double term = (exp(-mHulthenA*r)/r) - (exp(-mHulthenB*r)/r); // Hulthen
return mRho0*term*term;
}
else {
return mRho0*(1+mOmega*(r/mRadius)*(r/mRadius))/(1+exp((r-mRadius)/mSurfaceThickness)); // 3pF
}
-}
-
-double Nucleus::rhoForIntegration(double *x, double* par)
-{
- // b and z in fm
- double b = par[0];
- double z = *x;
- return rho(b, z);
-}
-
-double Nucleus::T(double b) const
-{
- //
- // Returns overlap integral
- // b in fm, overlap function T in GeV^2
- // Returns 0 if b exceeds table range
- //
- if (mA == 0) {
- cout << "Nucleus::T(): Error, instance is not initialized - cannot calculate overlap integral." << endl;
- return 0;
- }
+}
+
+double Nucleus::rhoForIntegration(double *x, double* par)
+{
+ // b and z in fm
+ double b = par[0];
+ double z = *x;
+ return rho(b, z);
+}
+
+double Nucleus::T(double b) const
+{
+ //
+ // Returns overlap integral
+ // b in fm, overlap function T in GeV^2
+ // Returns 0 if b exceeds table range
+ //
+ if (mA == 0) {
+ cout << "Nucleus::T(): Error, instance is not initialized - cannot calculate overlap integral." << endl;
+ return 0;
+ }
int bin = mLookupTable->FindBin(b);
double res = mLookupTable->GetBinContent(bin);
return res*hbarc2;
-}
-
-double Nucleus::TForIntegration(double *x, double*) const
-{
- double b = x[0];
- return 2*b*M_PI*T(b)/hbarc2;
-}
-
+}
+
+double Nucleus::TForIntegration(double *x, double*) const
+{
+ double b = x[0];
+ return 2*b*M_PI*T(b)/hbarc2;
+}
+
void Nucleus::normalizationOfT(double eps)
-{
- //
- // This is for internal checks only.
- // Normalization of rho/T is such that fully integrated
- // function should yield A.
- //
- double range = 3*mRadius;
- TF1* func = new TF1("func",this, &Nucleus::TForIntegration, 0, range, 0);
+{
+ //
+ // This is for internal checks only.
+ // Normalization of rho/T is such that fully integrated
+ // function should yield A.
+ //
+ double range = 3*mRadius;
+ TF1* func = new TF1("func",this, &Nucleus::TForIntegration, 0, range, 0);
double res = func->Integral(0, range, eps);
cout << "Normalization of T: = " << res << endl;
delete func;
-}
-
+}
+
double Nucleus::rho0() const { return mRho0; }
-double Nucleus::TofProton(double b)
-{
- //
- // Gaussian shape for proton
- // Units:
- // b in fm
+double Nucleus::TofProton(double b)
+{
+ //
+ // Gaussian shape for proton
+ // Units:
+ // b in fm
//
- const double BG = 4; // GeV^-2
- double arg = b*b/(2*BG);
- arg /= hbarc2;
- return 1/(2*M_PI*BG) * exp(-arg);
-}
-
-int Nucleus::pdgID(int Z, int A) const
-{
- // PDG for nuclei 10LZZZAAAI
- // L = number of strange quark (for hypernuclei)
- // I = isomer level, with I = 0 corresponding to the
- // ground state and I > 0 to excitations,
- if (Z==1 && A==1)
- return 2212;
- else if (Z==0 && A==1)
- return 2112;
- else if (A > 1)
- return 1000000000 + 10000*Z + 10*A;
- else
- return 0;
-}
-
-int Nucleus::pdgID() const
-{
- return pdgID(mZ, mA);
-}
-
+ const double BG = 4; // GeV^-2
+ double arg = b*b/(2*BG);
+ arg /= hbarc2;
+ return 1/(2*M_PI*BG) * exp(-arg);
+}
+
+int Nucleus::pdgID(int Z, int A) const
+{
+ // PDG for nuclei 10LZZZAAAI
+ // L = number of strange quark (for hypernuclei)
+ // I = isomer level, with I = 0 corresponding to the
+ // ground state and I > 0 to excitations,
+ if (Z==1 && A==1)
+ return 2212;
+ else if (Z==0 && A==1)
+ return 2112;
+ else if (A > 1)
+ return 1000000000 + 10000*Z + 10*A;
+ else
+ return 0;
+}
+
+int Nucleus::pdgID() const
+{
+ return pdgID(mZ, mA);
+}
+
Index: trunk/src/FrangibleNucleus.cpp
===================================================================
--- trunk/src/FrangibleNucleus.cpp (revision 490)
+++ trunk/src/FrangibleNucleus.cpp (revision 491)
@@ -1,204 +1,204 @@
//==============================================================================
// FrangibleNucleus.cpp
//
// Copyright (C) 2010-2019 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich
// Last update:
// $Date$
// $Author$
//==============================================================================
#include "FrangibleNucleus.h"
#include "CNucleus.h"
#include "Constants.h"
#include "EventGeneratorSettings.h"
#include "TRandom3.h"
#define PR(x) cout << #x << " = " << (x) << endl;
FrangibleNucleus::FrangibleNucleus()
{
mGeminiNucleus = nullptr;
mExcitationEnergy = 0;
}
FrangibleNucleus& FrangibleNucleus::operator=(const FrangibleNucleus& gn)
{
if (this != &gn) {
delete mGeminiNucleus;
mProducts.clear();
Nucleus::operator=(gn);
mExcitationEnergy = gn.mExcitationEnergy;
copy(gn.mProducts.begin(), gn.mProducts.end(), mProducts.begin());
if (gn.mGeminiNucleus)
mGeminiNucleus = new CNucleus(gn.mZ, gn.mA);
else
mGeminiNucleus = nullptr;
}
return *this;
}
FrangibleNucleus::FrangibleNucleus(const FrangibleNucleus& gn) : Nucleus(gn)
{
mExcitationEnergy = gn.mExcitationEnergy;
copy(gn.mProducts.begin(), gn.mProducts.end(), mProducts.begin());
if (gn.mGeminiNucleus)
mGeminiNucleus = new CNucleus(gn.mZ, gn.mA);
else
- mGeminiNucleus = 0;
-}
+ mGeminiNucleus = nullptr;
+}
void FrangibleNucleus::init(unsigned int A)
{
Nucleus::init(A);
if (mGeminiNucleus) delete mGeminiNucleus;
mGeminiNucleus = nullptr;
}
void FrangibleNucleus::init(unsigned int A, bool enableBreakup)
{
Nucleus::init(A);
if (mGeminiNucleus) delete mGeminiNucleus;
//
// Init Gemini.
//
if (enableBreakup)
mGeminiNucleus = new CNucleus(mZ, mA);
else
mGeminiNucleus = nullptr;
mExcitationEnergy = 0;
}
FrangibleNucleus::FrangibleNucleus(unsigned int A, bool enableBreakup) : Nucleus(A)
{
//
// Init Gemini.
// Only if requested, not needed otherwise.
//
if (enableBreakup)
mGeminiNucleus = new CNucleus(mZ, mA);
else
mGeminiNucleus = nullptr;
mExcitationEnergy = 0;
}
FrangibleNucleus::~FrangibleNucleus()
{
delete mGeminiNucleus;
}
void FrangibleNucleus::resetBreakup()
{
mExcitationEnergy = 0;
mProducts.clear();
}
int FrangibleNucleus::breakup(const TLorentzVector& dissSystem)
{
EventGeneratorSettings *settings = EventGeneratorSettings::instance();
//
// Estimate excitation energy
// Note that the dissSystem is given in units of 'per nucleon'.
// Hence we have to multiply the excitation energy with A.
//
mExcitationEnergy = (dissSystem.M()-protonMass)*mA;
double Ex = mExcitationEnergy;
double maxEx = settings->maxNuclearExcitationEnergy();
if (Ex > maxEx) {
if (settings->verboseLevel() > 1)
cout << "FrangibleNucleus::breakup(): Actual excitation energy (" << Ex
<< ") exceeded upper limit (" << maxEx << "). Reset to maximum value." << endl;
Ex = maxEx;
}
Ex *= 1000; // Gemini uses the total energy in MeV
//
// Setup excited nucleus
//
// Pass excitation energy and spin to Gemini
mGeminiNucleus->setCompoundNucleus(Ex,mSpin); //specify the excitation energy and spin
mGeminiNucleus->setVelocityCartesian(); // set initial velocity to zero (CMS)
// Set the direction of the spin vector (random)
TRandom3 *rndm = Settings::randomGenerator();
double phi = rndm->Uniform(2*M_PI);
double theta = acos(rndm->Uniform(-1, 1));
CAngle spin(theta, phi);
mGeminiNucleus->setSpinAxis(spin);
//
// Let the nucleus breakup
//
mGeminiNucleus->decay();
mProducts.clear();
if (mGeminiNucleus->abortEvent) {
cout << "Nucleus::breakup(): Error, decay aborted in Gemini++." << endl;
mGeminiNucleus->reset();
return 0;
}
int nfragments = mGeminiNucleus->getNumberOfProducts();
mProducts.resize(nfragments);
for (int i=0; i<nfragments; i++) {
CNucleus *product = mGeminiNucleus->getProducts(i); //set pointer to first stable product
mProducts[i].Z = product->iZ;
mProducts[i].A = product->iA;
mProducts[i].emissionTime = product->getTime();
mProducts[i].p = product->getLorentzVector();
mProducts[i].p.Boost(dissSystem.BoostVector());
mProducts[i].name = product->getName();
if (product->iZ == 1 && product->iA == 1)
mProducts[i].pdgId = 2212; // p
else if (product->iZ == 0 && product->iA == 1)
mProducts[i].pdgId = 2112; // n
else
mProducts[i].pdgId = pdgID(product->iZ, product->iA);
}
mGeminiNucleus->reset();
return nfragments;
}
const vector<BreakupProduct>& FrangibleNucleus::breakupProducts() const
{
return mProducts;
}
void FrangibleNucleus::listBreakupProducts(ostream& os) const
{
TLorentzVector sys;
cout << "Excitation energy = " << mExcitationEnergy << endl;
cout << "Number of fragments = " << mProducts.size() << endl;
for (unsigned int i=0; i<mProducts.size(); i++) {
os << mProducts[i] << endl;
sys += mProducts[i].p;
}
cout << "Invariant mass of dissociated system = " << sys.M() << endl;
cout << "Dissociated system 4-vector p=(" << sys.Px() << ", "
<< sys.Py() << ", " << sys.Pz() << ", " << sys.E() << ')' << endl;
cout << endl;
}
Index: trunk/src/ExclusiveFinalStateGenerator.cpp
===================================================================
--- trunk/src/ExclusiveFinalStateGenerator.cpp (revision 490)
+++ trunk/src/ExclusiveFinalStateGenerator.cpp (revision 491)
@@ -1,612 +1,617 @@
//==============================================================================
// ExclusiveFinalStateGenerator.cpp
//
// Copyright (C) 2010-2019 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich
// Last update:
// $Date$
// $Author$
//==============================================================================
-#include "ExclusiveFinalStateGenerator.h"
-#include "EventGeneratorSettings.h"
-#include "Kinematics.h"
-#include "Event.h"
-#include "VectorMesonDecayMass.h"
-#include "Math/BrentRootFinder.h"
-#include "Math/GSLRootFinder.h"
-#include "Math/RootFinderAlgorithms.h"
-#include "Math/IFunction.h"
-#include <cmath>
-#include <algorithm>
-#include <limits>
-#include <iomanip>
-
+ #include <algorithm>
+ #include <limits>
+ #include <iomanip>
+ #include <cmath>
+ #include "ExclusiveFinalStateGenerator.h"
+ #include "EventGeneratorSettings.h"
+ #include "Kinematics.h"
+ #include "Event.h"
+ #include "VectorMesonDecayMass.h"
+ #include "Math/BrentRootFinder.h"
+ #include "Math/GSLRootFinder.h"
+ #include "Math/RootFinderAlgorithms.h"
+ #include "Math/IFunction.h"
+ #include "Math/SpecFuncMathCore.h"
+ #include "Math/WrappedTF1.h"
+ #include "Math/GaussIntegrator.h"
+ #include "TF1.h"
+
#define PR(x) cout << #x << " = " << (x) << endl;
//-------------------------------------------------------------------------------
//
// Helper class needed to find root in
// ExclusiveFinalStateGenerator::generate()
//
//-------------------------------------------------------------------------------
class ScatteredProtonEnergyFormula : public ROOT::Math::IBaseFunctionOneDim
{
public:
double DoEval(double) const;
ROOT::Math::IBaseFunctionOneDim* Clone() const;
void calculateValidRange(double&, double&);
public:
double mT;
double mVmMass2;
double mMY2;
double mPhi; // azimuthal angle for scattered proton
TLorentzVector mProtonIn;
TLorentzVector mVirtualPhoton;
};
ROOT::Math::IBaseFunctionOneDim* ScatteredProtonEnergyFormula::Clone() const
{
return new ScatteredProtonEnergyFormula();
}
double ScatteredProtonEnergyFormula::DoEval(double Ep) const
{
double m2 = mProtonIn.M2();
double pzp = (mT - m2 - mMY2 + 2*mProtonIn.E() * Ep)/(2*mProtonIn.Pz());
double term = Ep*Ep-pzp*pzp-mMY2;
if (term < 0) return 99999; // out of kinematically allowed range
double ptp = sqrt(term);
TLorentzVector p_out(ptp*cos(mPhi), ptp*sin(mPhi), pzp, Ep);
double f = (mVirtualPhoton + mProtonIn - p_out)*(mVirtualPhoton + mProtonIn - p_out) - mVmMass2;
return f;
}
void ScatteredProtonEnergyFormula::calculateValidRange(double& lower, double& upper)
{
double m2 = mProtonIn.M2();
double term1 = mT-m2-mMY2;
double termA = mProtonIn.E()*term1;
double termB = sqrt(mProtonIn.Pz()*mProtonIn.Pz()*(term1*term1-4*m2*mMY2));
double termC = -2*m2;
lower = (termA+termB)/termC;
upper = (termA-termB)/termC;
if (lower > upper) swap(lower, upper);
lower += numeric_limits<float>::epsilon();
upper -= numeric_limits<float>::epsilon();
}
//-------------------------------------------------------------------------------
//
// Implementation of ExclusiveFinalStateGenerator
//
//-------------------------------------------------------------------------------
ExclusiveFinalStateGenerator::ExclusiveFinalStateGenerator() {/* no op */}
ExclusiveFinalStateGenerator::~ExclusiveFinalStateGenerator() {/* no op */}
bool ExclusiveFinalStateGenerator::generate(int id, double t, double y, double Q2,
bool isIncoherent, int A, Event *event)
{
//
// Get generator settings and the random generator
//
EventGeneratorSettings *settings = EventGeneratorSettings::instance();
TRandom3 *rndm = settings->randomGenerator();
//
// The beam particles must be present in the event list
//
int ePos = -1;
int hPos = -1;
bool parentsOK = true;
if (event->particles.size() == 2) {
if (abs(event->particles[0].pdgId) == 11) {
ePos = 0;
hPos = 1;
}
else if (abs(event->particles[1].pdgId) == 11) {
ePos = 1;
hPos = 0;
}
else
parentsOK = false;
}
else
parentsOK = false;
if (!parentsOK) {
cout << "ExclusiveFinalStateGenerator::generate(): error, no beam particles in event list." << endl;
return false;
}
//
// Store arguments locally
// (Some could also be obtained from the event structure)
//
mA = A;
mT = t;
if (mT > 0) mT = -mT; // ensure t<0
mQ2 = Q2;
mY = y;
mIsIncoherent = isIncoherent;
mElectronBeam = event->particles[ePos].p;
mHadronBeam = event->particles[hPos].p;
mMassVM = VectorMesonDecayMass::mass(id);
mS = Kinematics::s(mElectronBeam, mHadronBeam);
//
// Constants
//
double const twopi = 2*M_PI;
double const hMass2 = mHadronBeam.M2();
//
// Incoherent diffarction
//
// Generate hadron dissociation mass according to
// dN/dM2 ~ 1/M2. Lower bound is of course the hadron
// mass and upper bound is some arbitrary value (for now).
//
// Note that we calculate and quote eA kinematics always in
// units of 'per nucleon'. Our model of incoherence is that the
// difference of the diffractive mass of one (1) proton out
// of the nucleus gives the final excitation energy E*.
// Hence we have to calculate E* and divide it by A to keep
// the kinematic consistent.
//
if (mIsIncoherent && mA > 1) {
const double lower = hMass2;
const double upper = 9; // GeV2
mMY2 = lower*upper/(upper - rndm->Uniform()*(upper-lower));
double MY_per_nucleon = (sqrt(hMass2)*(mA-1) + sqrt(mMY2))/mA;
mMY2 = MY_per_nucleon*MY_per_nucleon;
if (mMY2 < hMass2) mMY2 = hMass2;
}
else {
mMY2 = hMass2;
}
//
// Re-engineer scattered electron
//
// e'=(E', pt', pz') -> 3 unknowns
//
// Three equations:
// 1: me*me=E'*E'-pt'*pt'-pz'*pz'
// 2: Q2=-(e-e')^2=-2*me*me + 2*(E*E'-pz*pz')
// 3: W2=(P+e-e')^2=mp2+2*me2+2*(Ep*E-Pz*pz)-2*(Ep*E'-Pz*pz')-2*(E*E'-pz*pz')
//
double Ee = mElectronBeam.E();
double Pe = mElectronBeam.Pz();
double Ep = mHadronBeam.E();
double Pp = mHadronBeam.Pz();
double W = event->W;
double W2 = W*W;
// Take masses from the beams in case they are not actually electrons or protons
double me2 = mElectronBeam.M2();
double mp2 = mHadronBeam.M2();
//
// What we want for each particle:
//
double E, pz, pt, px, py, phi;
//
// Equations 2 and 3 yield:
//
E = Pe*(W2-mp2-2*Ee*Ep) + (Pp+Pe)*Q2 + 2*Pe*Pe*Pp + 2*me2*Pp;
E /= 2*(Ee*Pp-Ep*Pe);
pz = Ee*(W2-mp2) + (Ep+Ee)*Q2 + 2*Ee*Pe*Pp + 2*Ep*me2 - 2*Ee*Ee*Ep;
pz /= 2*(Ee*Pp-Ep*Pe);
//
// Equation 1:
//
pt = sqrt(E*E-pz*pz-me2);
phi = rndm->Uniform(twopi);
TLorentzVector theScatteredElectron(pt*sin(phi), pt*cos(phi), pz, E);
//
// Re-engineer virtual photon
//
// gamma=E-E'
E = mElectronBeam.E()-theScatteredElectron.E();
pz = mElectronBeam.Pz()-theScatteredElectron.Pz();
px = mElectronBeam.Px()-theScatteredElectron.Px();
py = mElectronBeam.Py()-theScatteredElectron.Py();
TLorentzVector theVirtualPhoton = TLorentzVector(px, py, pz, E);
//
// Re-engineer scattered proton/dissociated proton
//
// No analytic solution. Need to run a root finder that does
// not need derivates but uses a bracketing algorithm (Brent).
// Correct brackets are crucial since ScatteredProtonEnergyFormula
// produces sqrt(-x) if outside the kinematically allowed range (it
// actually catches it and returns a large positive number, 0 doesn't
// work).
//
//
// Setup formula to solve root
//
phi = rndm->Uniform(twopi);
ScatteredProtonEnergyFormula formula;
formula.mT = mT;
formula.mVmMass2 = mMassVM*mMassVM;
formula.mPhi = phi;
formula.mProtonIn = mHadronBeam;
formula.mVirtualPhoton = theVirtualPhoton;
formula.mMY2 = mMY2;
//
// Find correct brackets to start with
//
double lower, upper;
formula.calculateValidRange(lower, upper);
if (upper > mHadronBeam.E() + theVirtualPhoton.E()) // limit excessive values
upper = mHadronBeam.E() + theVirtualPhoton.E(); // make it easier for Brent
//
// Run root finder
//
ROOT::Math::BrentRootFinder rootfinder;
rootfinder.SetFunction(formula, lower, upper);
rootfinder.Solve(10000, 0, 1.e-12);
E = rootfinder.Root();
if (/* rootfinder.Status() || */ fabs(formula(E)) > 1e-6) {
if (settings->verboseLevel() > 2) cout << "ExclusiveFinalStateGenerator::generate(): error, cannot find root. No final state defined." << endl;
- return false;
- }
+ return false;
+ }
//
// Outgoing proton (hadron) system
//
pz = (mT- hMass2 - mMY2 + 2*mHadronBeam.E()*E)/(2*mHadronBeam.Pz());
pt = sqrt(E*E-pz*pz-mMY2);
px = pt*cos(phi);
py = pt*sin(phi);
TLorentzVector theScatteredProton(px, py, pz, E);
//
// Finally the vector meson
//
TLorentzVector theVectorMeson((mHadronBeam + mElectronBeam) - (theScatteredElectron + theScatteredProton));
//
// Check for numerical glitches
//
if (!isValid(theScatteredElectron)) {
if (settings->verboseLevel() > 2) cout << "ExclusiveFinalStateGenerator::generate(): error, scattered electron 4-vector is invalid." << endl;
return false;
}
if (!isValid(theScatteredProton)) {
if (settings->verboseLevel() > 2) cout << "ExclusiveFinalStateGenerator::generate(): error, scattered hadron 4-vector is invalid." << endl;
return false;
}
if (!isValid(theVectorMeson)) {
if (settings->verboseLevel() > 2) cout << "ExclusiveFinalStateGenerator::generate(): error, vector meson 4-vector is invalid." << endl;
return false;
}
//
// Add particles to event record
//
event->particles.resize(2+5);
unsigned int eOut = 2;
unsigned int gamma = 3;
unsigned int vm = 4;
unsigned int pomeron = 5;
unsigned int hOut = 6;
// Global indices
event->particles[eOut].index = eOut;
event->particles[gamma].index = gamma;
event->particles[vm].index = vm;
event->particles[pomeron].index = pomeron;
event->particles[hOut].index = hOut;
// 4-vectors
event->particles[eOut].p = theScatteredElectron;
event->particles[hOut].p = theScatteredProton;
event->particles[gamma].p = theVirtualPhoton;
event->particles[vm].p = theVectorMeson;
event->particles[pomeron].p = theScatteredProton - mHadronBeam;
// PDG Ids
event->particles[eOut].pdgId = event->particles[ePos].pdgId; // same as incoming
event->particles[hOut].pdgId = event->particles[hPos].pdgId; // same as incoming (breakup happens somewhere else)
event->particles[gamma].pdgId = 22;
event->particles[vm].pdgId = id;
event->particles[pomeron].pdgId = 990;
// status
//
// HepMC conventions (February 2009).
// 0 : an empty entry, with no meaningful information
// 1 : a final-state particle, i.e. a particle that is not decayed further by
// the generator (may also include unstable particles that are to be decayed later);
// 2 : a decayed hadron or tau or mu lepton
// 3 : a documentation entry (not used in PYTHIA);
// 4 : an incoming beam particle;
// 11 - 200 : an intermediate (decayed/branched/...) particle that does not
// fulfill the criteria of status code 2
event->particles[ePos].status = 4;
event->particles[hPos].status = 4;
event->particles[eOut].status = 1;
event->particles[hOut].status = mIsIncoherent ? 2 : 1;
event->particles[gamma].status = 2;
event->particles[vm].status = 1;
event->particles[pomeron].status = 2;
// parents (ignore dipole)
event->particles[eOut].parents.push_back(ePos);
event->particles[gamma].parents.push_back(ePos);
event->particles[hOut].parents.push_back(hPos);
event->particles[hOut].parents.push_back(pomeron);
event->particles[pomeron].parents.push_back(gamma);
event->particles[pomeron].parents.push_back(gamma);
event->particles[vm].parents.push_back(gamma);
// daughters (again ignore dipole)
event->particles[ePos].daughters.push_back(eOut);
event->particles[ePos].daughters.push_back(gamma);
event->particles[gamma].daughters.push_back(vm);
event->particles[gamma].daughters.push_back(pomeron);
event->particles[pomeron].daughters.push_back(hOut);
event->particles[hPos].daughters.push_back(hOut);
return true;
}
//
// UPC version
//
// Note: We call the beam particle that emits the photon "electron"
// even if its a proton/nucleus
//
bool ExclusiveFinalStateGenerator::generate(int id, double t, double xpom,
bool isIncoherent, int A, Event *event)
{
//
// Get generator settings and the random generator
//
EventGeneratorSettings *settings = EventGeneratorSettings::instance();
TRandom3 *rndm = settings->randomGenerator();
//
// The beam particles must be present in the event list
//
int ePos = 0;
int hPos = 1;
bool parentsOK = true;
if (event->particles.size() != 2)
parentsOK = false;
if (!parentsOK) {
cout << "ExclusiveFinalStateGenerator::generate(): error, no beam particles in event list." << endl;
return false;
}
//
// Store arguments locally
// (Some could also be obtained from the event structure)
//
mA = A;
mT = t;
if (mT > 0) mT = -mT; // ensure t<0
mIsIncoherent = isIncoherent;
mElectronBeam = event->particles[ePos].p;
mHadronBeam = event->particles[hPos].p;
+
//
// For the final state we pick a VM mass according to the
// specific line shape/width.
//
mMassVM = VectorMesonDecayMass::mass(id);
// mMassVM = settings->lookupPDG(id)->Mass(); // old fixed mass version
mS = Kinematics::s(mElectronBeam, mHadronBeam);
mXp = xpom;
//
// Constants
//
double const twopi = 2*M_PI;
double const hMass2 = mHadronBeam.M2();
//
// Incoherent diffraction
//
// Generate hadron dissociation mass according to
// dN/dM2 ~ 1/M2. Lower bound is of course the hadron
// mass and upper bound is some arbitrary value (for now).
//
// Note that we calculate and quote eA kinematics always in
// units of 'per nucleon'. Our model of incoherence is that the
// difference of the diffractive mass of one (1) proton out
// of the nucleus gives the final excitation energy E*.
// Hence we have to calculate E* and divide it by A to keep
// the kinematic consistent.
//
if (mIsIncoherent && mA > 1) {
const double lower = hMass2;
const double upper = 9; // GeV2
mMY2 = lower*upper/(upper - rndm->Uniform()*(upper-lower));
double MY_per_nucleon = (sqrt(hMass2)*(mA-1) + sqrt(mMY2))/mA;
mMY2 = MY_per_nucleon*MY_per_nucleon;
if (mMY2 < hMass2) mMY2 = hMass2;
}
else {
mMY2 = hMass2;
}
//
// Check for smallest allowed xpom
//
double xpom_min = Kinematics::xpomMin(mMassVM, mT, mHadronBeam, mElectronBeam, mMY2-hMass2);
if (xpom < xpom_min){
if (settings->verboseLevel() > 2) cout<<"xpom = "<<xpom<<", which is smaller than xpom_min="<<xpom_min<<endl;
return false;
}
//
// We have three unknown: E_gamma, P_z,gamma, E_pomeron
// and three equations M^2(scattered electrons), M^2(scattered proton),
// and M^2(vector meson)
//
//Start by setting up the knowns: Incoming beams, xpom, and t:
double Ee = mElectronBeam.E();
double Pe = mElectronBeam.Pz();
double Pp = mHadronBeam.Pz();
double Ep = mHadronBeam.E();
//
// What we want for each particle:
//
double E, pz, pt, phi;
//
// Use scattered proton to set up four momentum of pomeron:
//
double sqrtarg= 1 - ( (2*xpom - xpom*xpom)*Pp*Pp + mT + hMass2 - mMY2) / (Ep*Ep);
E = Ep*(1-sqrt(sqrtarg)); //this is close to xpom*Ep
phi = rndm->Uniform(twopi);
pt = sqrt(-t);
pz = xpom*Pp;
TLorentzVector thePomeron = TLorentzVector(pt*sin(phi), pt*cos(phi), xpom*Pp, E);
//
// That give scattered proton:
//
TLorentzVector theScatteredProton = mHadronBeam-thePomeron;
//
// Fill Virtual Photon:
//
mEgam = Kinematics::Egamma(xpom, t, mMassVM, Ep, Ee, mMY2-hMass2);
E = mEgam;
pz = Pe*(1 - sqrt( 1 - ( 2*Ee*E - E*E )/(Pe*Pe) ) ); //this is close to Egamma
TLorentzVector theVirtualPhoton = TLorentzVector(0, 0, pz, E);
//
// Scattered Electron:
//
TLorentzVector theScatteredElectron = mElectronBeam - theVirtualPhoton ;
//
// Vector Meson:
//
TLorentzVector theVectorMeson = theVirtualPhoton + thePomeron;
//
// Check for numerical glitches
//
if (!isValid(theScatteredElectron)) {
if (settings->verboseLevel() > 2) cout << "ExclusiveFinalStateGenerator::generate(): error, scattered electron 4-vector is invalid." << endl;
return false;
}
if (!isValid(theScatteredProton)) {
if (settings->verboseLevel() > 2) cout << "ExclusiveFinalStateGenerator::generate(): error, scattered hadron 4-vector is invalid." << endl;
return false;
}
if (!isValid(theVectorMeson)) {
if (settings->verboseLevel() > 2) cout << "ExclusiveFinalStateGenerator::generate(): error, vector meson 4-vector is invalid." << endl;
return false;
}
//
// Add particles to event record
//
event->particles.resize(2+5);
unsigned int eOut = 2;
unsigned int gamma = 3;
unsigned int vm = 4;
unsigned int pomeron = 5;
unsigned int hOut = 6;
// Global indices
event->particles[eOut].index = eOut;
event->particles[gamma].index = gamma;
event->particles[vm].index = vm;
event->particles[pomeron].index = pomeron;
event->particles[hOut].index = hOut;
// 4-vectors
event->particles[eOut].p = theScatteredElectron;
event->particles[hOut].p = theScatteredProton;
event->particles[gamma].p = theVirtualPhoton;
event->particles[vm].p = theVectorMeson;
event->particles[pomeron].p = thePomeron;
// PDG Ids
event->particles[eOut].pdgId = event->particles[ePos].pdgId; // same as incoming
event->particles[hOut].pdgId = event->particles[hPos].pdgId; // same as incoming (breakup happens somewhere else)
event->particles[gamma].pdgId = 22;
event->particles[vm].pdgId = id;
event->particles[pomeron].pdgId = 990;
// status
//
// HepMC conventions (February 2009).
// 0 : an empty entry, with no meaningful information
// 1 : a final-state particle, i.e. a particle that is not decayed further by
// the generator (may also include unstable particles that are to be decayed later);
// 2 : a decayed hadron or tau or mu lepton
// 3 : a documentation entry (not used in PYTHIA);
// 4 : an incoming beam particle;
// 11 - 200 : an intermediate (decayed/branched/...) particle that does not
// fulfill the criteria of status code 2
event->particles[ePos].status = 4;
event->particles[hPos].status = 4;
event->particles[eOut].status = 1;
event->particles[hOut].status = mIsIncoherent ? 2 : 1;
event->particles[gamma].status = 2;
event->particles[vm].status = 1;
event->particles[pomeron].status = 2;
// parents (ignore dipole)
event->particles[eOut].parents.push_back(ePos);
event->particles[gamma].parents.push_back(ePos);
event->particles[hOut].parents.push_back(hPos);
event->particles[hOut].parents.push_back(pomeron);
event->particles[pomeron].parents.push_back(gamma);
event->particles[pomeron].parents.push_back(gamma);
event->particles[vm].parents.push_back(gamma);
// daughters (again ignore dipole)
event->particles[ePos].daughters.push_back(eOut);
event->particles[ePos].daughters.push_back(gamma);
event->particles[gamma].daughters.push_back(vm);
event->particles[gamma].daughters.push_back(pomeron);
event->particles[pomeron].daughters.push_back(hOut);
event->particles[hPos].daughters.push_back(hOut);
//fill event structure
double y = mHadronBeam*theVirtualPhoton/(mHadronBeam*mElectronBeam);
double W2 = (theVirtualPhoton+mHadronBeam).M2();
mQ2 = -theVirtualPhoton.M2();
event->Q2 = mQ2;
event->W = sqrt(W2);
event->y = y;
return true;
}
Index: trunk/src/Version.h
===================================================================
--- trunk/src/Version.h (revision 490)
+++ trunk/src/Version.h (revision 491)
@@ -1,29 +1,29 @@
//==============================================================================
// Version.h
//
// Copyright (C) 2010-2019 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich
// Last update:
// $Date$
// $Author$
//==============================================================================
#ifndef Version_h
#define Version_h
-#define VERSION "1.40"
-#define VERSION_NUMBER 1.40
+#define VERSION "2.00"
+#define VERSION_NUMBER 2.00
#endif
Index: trunk/src/DipoleModel.cpp
===================================================================
--- trunk/src/DipoleModel.cpp (revision 490)
+++ trunk/src/DipoleModel.cpp (revision 491)
@@ -1,337 +1,369 @@
//==============================================================================
// DipoleModel.cpp
//
// Copyright (C) 2010-2019 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 <http://www.gnu.org/licenses/>.
//
// Author: Tobias Toll
// Last update:
// $Date$
// $Author$
//==============================================================================
#include <fstream>
#include <iostream>
#include <sstream>
#include <cmath>
#include "DipoleModel.h"
#include "TableGeneratorSettings.h"
#include "DglapEvolution.h"
#include "Constants.h"
#include "TFile.h"
#include "TVector3.h"
#include "TMath.h"
#include "TH2F.h"
#include "TF1.h"
+#include "Math/WrappedTF1.h"
+#include "Math/GaussIntegrator.h"
+
#define PR(x) cout << #x << " = " << (x) << endl;
using namespace std;
DipoleModel::DipoleModel()
{
mConfigurationExists = false;
TableGeneratorSettings* settings = TableGeneratorSettings::instance();
unsigned int A = settings->A();
mNucleus.init(A);
mIsInitialized = true;
mParameters = nullptr;
-}
+}
DipoleModel::~DipoleModel()
{
delete mParameters;
}
const TableGeneratorNucleus* DipoleModel::nucleus() const { return &mNucleus; }
bool DipoleModel::configurationExists() const { return mConfigurationExists; }
double DipoleModel::bDependence(double) { return 0; }
double DipoleModel::bDependence(double, double) { return 0; }
double DipoleModel::dsigmadb2ep(double, double, double) { return 0;}
//***********bSat:*****************************************************
DipoleModel_bSat::DipoleModel_bSat()
{
mBDependence = 0;
mSigma_ep_LookupTable = 0;
//
// Set the parameters. Note that we enforce here the bSat model
// independent of what the settings say.
//
TableGeneratorSettings* settings = TableGeneratorSettings::instance();
mParameters = new DipoleModelParameters(bSat, settings->dipoleModelParameterSet());
}
+DipoleModel_bSat::DipoleModel_bSat(Settings* settings)
+{
+ //
+ // Set the parameters. Note that we enforce here the bSat model
+ // independent of what the settings say.
+ //
+ mParameters = new DipoleModelParameters(settings);
+}
+
+
DipoleModel_bSat::~DipoleModel_bSat()
{
delete mSigma_ep_LookupTable;
delete mBDependence;
-}
+ delete mParameters;
+}
DipoleModel_bSat& DipoleModel_bSat::operator=(const DipoleModel_bSat& dp)
{
if (this != &dp) {
delete mBDependence;
delete mSigma_ep_LookupTable;
DipoleModel::operator=(dp);
mBDependence = new TH2F(*(dp.mBDependence));
mBDependence->SetDirectory(0);
mSigma_ep_LookupTable = new TH1F(*(dp.mSigma_ep_LookupTable));
mSigma_ep_LookupTable->SetDirectory(0);
}
return *this;
}
DipoleModel_bSat::DipoleModel_bSat(const DipoleModel_bSat& dp) : DipoleModel(dp)
{
+ if (mBDependence) delete mBDependence;
mBDependence = new TH2F(*(dp.mBDependence));
mBDependence->SetDirectory(0);
}
void DipoleModel_bSat::createConfiguration(int iConfiguration)
{
if (!mIsInitialized) {
cout << "DipoleModel_bSat::createConfiguration(): DipoleModel class has not been initialized! Stopping." << endl;
exit(1);
}
TableGeneratorSettings* settings = TableGeneratorSettings::instance();
unsigned int A = mNucleus.A();
- string path = settings->bSatLookupPath();
+ string path=settings->bSatLookupPath();
ostringstream filename;
filename.str("");
- filename << path;// << "/bSat_bDependence_A" << A <<".root";
+ filename << path << "/bSat_bDependence_A" << A <<".root";
ifstream ifs(filename.str().c_str());
if (!ifs) {
cout << "DipoleModel_bSat::createConfiguration(): File does not exist: " << filename.str().c_str() << endl;
cout << "Stopping." << endl;
exit(1);
}
TFile* lufile= new TFile(filename.str().c_str());
ostringstream histoName;
histoName.str( "" );
histoName << "Configuration_" << iConfiguration;
lufile->GetObject( histoName.str().c_str(), mBDependence );
mBDependence->SetDirectory(0);
lufile->Close();
- mConfigurationExists = true;
+ mConfigurationExists=true;
}
double DipoleModel_bSat::dsigmadb2(double r, double b, double phi, double xprobe)
{
if (mParameters->dipoleModelParameterSet() == STU) {
double rm = mParameters->rMax();
r = rm*sqrt(log(1+r*r/(rm*rm)));
}
- double bDep = bDependence(b, phi);
+ double bDep=bDependence(b, phi);
double muQ2 = mParameters->C()/(r*r/hbarc2) + mParameters->mu02();
double asxg = DglapEvolution::instance().alphaSxG(xprobe, muQ2);
double omega = ((M_PI*M_PI)/Nc)*(r*r/hbarc2)*asxg*bDep;
double result = 2.*(1. - exp(-omega/2));
return result;
}
double DipoleModel_bSat::bDependence(double b, double phi)
{
double result = mBDependence->Interpolate(b, phi);
return result;
}
double DipoleModel_bSat::dsigmadb2ep(double r, double b, double xprobe)
{
if (mParameters->dipoleModelParameterSet() == STU) {
double rm = mParameters->rMax();
r = rm*sqrt(log(1+r*r/(rm*rm)));
}
const double BG = mParameters->BG(); // GeV^-2
double arg = b*b/(2*BG);
arg /= hbarc2;
double bDep= 1/(2*M_PI*BG) * exp(-arg);
double Mu02 = mParameters->mu02(); // GeV^2
double muQ2 = mParameters->C()/(r*r/hbarc2) + Mu02;
+ if(muQ2>1e7 or muQ2<1) PR(muQ2);
double asxg = DglapEvolution::instance().alphaSxG(xprobe, muQ2);
double omega = ((M_PI*M_PI)/Nc)*(r*r/hbarc2)*asxg*bDep;
double result = 2.*(1. - exp(-omega/2));
return result;
}
-double DipoleModel_bSat::coherentDsigmadb2(double r, double b, double xprobe) {
+double DipoleModel_bSat::coherentDsigmadb2(double r, double b, double xprobe) {
if (mParameters->dipoleModelParameterSet() == STU) {
double rm = mParameters->rMax();
r = rm*sqrt(log(1+r*r/(rm*rm)));
}
- xprobe*=1.;
double sigmap = mSigma_ep_LookupTable->Interpolate(r);
- int A = nucleus()->A();
- double TA = nucleus()->T(b)/A;
+ int A=nucleus()->A();
+ double TA=nucleus()->T(b)/A;
double result = 2 * ( 1 - pow(1 - TA/2.*sigmap, A) );
return result;
}
void DipoleModel_bSat::createSigma_ep_LookupTable(double xprobe)
{
- double rbRange = 3.*nucleus()->radius();
+ double rbRange=3.*nucleus()->radius();
TF1* dsigmaForIntegration = new TF1("dsigmaForIntegration", this, &DipoleModel_bSat::dsigmadb2epForIntegration, 0., rbRange, 2);
+ if(mSigma_ep_LookupTable) delete mSigma_ep_LookupTable;
mSigma_ep_LookupTable = new TH1F("", "", 1000, 0, rbRange);
- dsigmaForIntegration->SetNpx(1000);
+ ROOT::Math::WrappedTF1* WFlookup=new ROOT::Math::WrappedTF1(*dsigmaForIntegration);
+ ROOT::Math::GaussIntegrator GIlookup;
+ GIlookup.SetFunction(*WFlookup);
+ GIlookup.SetRelTolerance(1e-8);
+ GIlookup.SetAbsTolerance(0.);
+
+// dsigmaForIntegration->SetNpx(1000);
for (int iR=1; iR<=1000; iR++) {
- double r = mSigma_ep_LookupTable->GetBinCenter(iR);
+ double r=mSigma_ep_LookupTable->GetBinCenter(iR);
dsigmaForIntegration->SetParameter(0, r);
dsigmaForIntegration->SetParameter(1, xprobe);
- double result = dsigmaForIntegration->Integral(0, rbRange);
+// double result=dsigmaForIntegration->Integral(0, rbRange);
+ double result = GIlookup.IntegralUp(0.); //GeV-2
mSigma_ep_LookupTable->SetBinContent(iR, result);
}
- delete dsigmaForIntegration;
-}
+ delete dsigmaForIntegration; //GeV-2
+ delete WFlookup;
+}
double DipoleModel_bSat::dsigmadb2epForIntegration(double *x, double* par)
{
- double r = par[0];
- double xprobe = par[1];
- double b = *x;
- return 2*M_PI*b/hbarc2*dsigmadb2ep(r, b, xprobe);
-}
+ double r=par[0]; //fm
+ double xprobe=par[1];
+ double b = *x; //fm
+ return 2*M_PI*b/hbarc2*dsigmadb2ep(r, b, xprobe); //GeV-2fm-1
+}
//***********bNonSat:*************************************************
DipoleModel_bNonSat::DipoleModel_bNonSat()
{
//
// Set the parameters. Note that we need bNonSat to calculate
// the skewedness correction for bSat.
//
TableGeneratorSettings* settings = TableGeneratorSettings::instance();
+ mParameters = new DipoleModelParameters( settings->dipoleModelType(), settings->dipoleModelParameterSet());
+}
+DipoleModel_bNonSat::DipoleModel_bNonSat(Settings* settings)
+{
+ //
+ // Set the parameters. Note that we need bNonSat to calculate
+ // the skewedness correction for bSat.
+ //
mParameters = new DipoleModelParameters(settings->dipoleModelType(), settings->dipoleModelParameterSet());
}
-DipoleModel_bNonSat::~DipoleModel_bNonSat(){}
+DipoleModel_bNonSat::~DipoleModel_bNonSat(){
+ delete mParameters;
+}
double DipoleModel_bNonSat::dsigmadb2ep(double r, double b, double xprobe)
{
if (mParameters->dipoleModelParameterSet() == STU) {
double rm = mParameters->rMax();
r = rm*sqrt(log(1+r*r/(rm*rm)));
}
const double BG = mParameters->BG(); // GeV^-2
double arg = b*b/(2*BG);
arg /= hbarc2;
double bDep= 1/(2*M_PI*BG) * exp(-arg);
double Mu02 = mParameters->mu02(); // GeV^2
double muQ2 = mParameters->C()/(r*r/hbarc2) + Mu02;
double asxg = DglapEvolution::instance().alphaSxG(xprobe, muQ2);
double omega = ((M_PI*M_PI)/Nc)*(r*r/hbarc2)*asxg*bDep;
return omega;
}
double DipoleModel_bNonSat::dsigmadb2(double r, double b, double phi, double xprobe)
{
if (mParameters->dipoleModelParameterSet() == STU) {
double rm = mParameters->rMax();
r = rm*sqrt(log(1+r*r/(rm*rm)));
}
- double bDep = bDependence(b, phi);
+ double bDep=bDependence(b, phi);
double muQ2 = mParameters->C()/(r*r/hbarc2) + mParameters->mu02();
double asxg = DglapEvolution::instance().alphaSxG(xprobe, muQ2);
double omega = ((M_PI*M_PI)/Nc)*(r*r/hbarc2)*asxg*bDep;
return omega;
}
double DipoleModel_bNonSat::coherentDsigmadb2(double r, double b, double xprobe){
if (mParameters->dipoleModelParameterSet() == STU) {
double rm = mParameters->rMax();
r = rm*sqrt(log(1+r*r/(rm*rm)));
}
- int A = nucleus()->A();
- double TA = nucleus()->T(b)/A;
+ int A=nucleus()->A();
+ double TA=nucleus()->T(b)/A;
double muQ2 = mParameters->C()/(r*r/hbarc2) + mParameters->mu02();
double asxg = DglapEvolution::instance().alphaSxG(xprobe, muQ2);
- double result = A*TA*M_PI*M_PI/Nc*r*r/hbarc2*asxg;
+ double result=A*TA*M_PI*M_PI/Nc*r*r/hbarc2*asxg;
return result;
}
//***********bCGC:*****************************************************
DipoleModel_bCGC::DipoleModel_bCGC()
{
//
// Set the parameters. Note that we enforce here the bNonSat model
// independent of what the settings say.
//
TableGeneratorSettings* settings = TableGeneratorSettings::instance();
mParameters = new DipoleModelParameters(bCGC, settings->dipoleModelParameterSet());
}
void DipoleModel_bCGC::createConfiguration(int iConfiguration)
{
if (!mIsInitialized) {
cout << "DipoleModel_bCGC::createConfigurationDipoleModel class has not been initialized! Stopping." << endl;
exit(1);
}
- //iConfiguration is a dummy for bCGC. Do this to avoid compiler warnings:
- iConfiguration++;
mNucleus.generate();
- mConfigurationExists = true;
+ mConfigurationExists=true;
}
double DipoleModel_bCGC::dsigmadb2(double r, double b, double phi, double x)
{
- double result = 1;
+ double result=1;
for (unsigned int iA=0; iA<mNucleus.A(); iA++) {
double absdeltab=( TVector3(b*cos(phi), b*sin(phi), 0.)
-mNucleus.configuration.at(iA).position() ).Perp();
result*=(1.-0.5*dsigmadb2ep(r, absdeltab, x));
}
return 2.*(1.-result);
}
double DipoleModel_bCGC::dsigmadb2ep(double r, double b, double xprobe)
{
double Y = log(1/xprobe);
double kappa = mParameters->kappa();
double N0 = mParameters->N0();
double x0 = mParameters->x0();
double lambda = mParameters->lambda();
double gammas = mParameters->gammas();
double A = -N0*N0*gammas*gammas/((1-N0)*(1-N0)*log(1-N0));
double B = 0.5*pow(1-N0,-(1-N0)/(N0*gammas));
double Qs = pow(x0/xprobe,lambda/2)*sqrt(DipoleModel_bCGC::bDependence(b));
double rQs = r*Qs/hbarc;
- double result = 0;
+ double result=0;
if (rQs <= 2)
result = 2*N0*pow(0.5*rQs, 2*(gammas+(1/(kappa*lambda*Y))*log(2/rQs)));
else
result = 2*(1 - exp(-A*log(B*rQs)*log(B*rQs)));
return result;
}
double DipoleModel_bCGC::bDependence(double b)
{
double gammas = mParameters->gammas();
double Bcgc = mParameters->Bcgc();
return exp(-0.5*b*b/Bcgc/gammas/hbarc2);
}
Index: trunk/src/Settings.h
===================================================================
--- trunk/src/Settings.h (revision 490)
+++ trunk/src/Settings.h (revision 491)
@@ -1,190 +1,197 @@
//==============================================================================
// Settings.h
//
// Copyright (C) 2010-2019 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich
// Last update:
// $Date$
// $Author$
//==============================================================================
#ifndef Settings_h
#define Settings_h
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include "TDatabasePDG.h"
#include "TRandom3.h"
#include "Enumerations.h"
using namespace std;
class TParticlePDG;
class SettingsParameterBase {
public:
virtual ~SettingsParameterBase() {}
public:
string name;
};
template<typename T> class SettingsParameter : public SettingsParameterBase {
public:
T* address;
T defaultValue;
};
class Settings {
public:
Settings();
virtual ~Settings();
bool readSettingsFromFile(const char*);
virtual bool list(ostream& = cout);
TParticlePDG* lookupPDG(int) const;
string particleName(int pdgID);
static TRandom3* randomGenerator();
unsigned int seed() const;
void setSeed(unsigned int);
int userInt() const;
double userDouble() const;
string userString() const;
void setUserInt(int);
void setUserDouble(double);
void setUserString(const string&);
void setVerbose(bool);
bool verbose() const;
void setVerboseLevel(int);
int verboseLevel() const;
void setQ2min(double);
double Q2min() const;
double Qmin() const;
void setQ2max(double);
double Q2max() const;
double Qmax() const;
void setWmin(double);
void setW2min(double);
double Wmin() const;
double W2min() const;
void setWmax(double);
void setW2max(double);
double Wmax() const;
double W2max() const;
void setXpomMin(double); // UPC only
void setXpomMax(double);
double xpomMin() const;
double xpomMax() const;
+ void setbetamin(double); // Inclusive diffraction
+ double betamin() const;
+ void setbetamax(double);
+ double betamax() const;
+
int vectorMesonId() const;
void setVectorMesonId(int);
string dipoleModelName() const;
DipoleModelType dipoleModelType() const;
void setDipoleModelType(DipoleModelType);
string dipoleModelParameterSetName() const;
DipoleModelParameterSet dipoleModelParameterSet() const;
void setDipoleModelParameterSet(DipoleModelParameterSet);
string tableSetTypeName() const;
TableSetType tableSetType() const;
void setTableSetType(TableSetType);
unsigned int A() const;
void setA(unsigned int);
string rootfile() const;
void setRootfile(const char*);
void setUPC(bool);
bool UPC() const;
void setUPCA(unsigned int);
unsigned int UPCA() const;
protected:
template<typename T> void registerParameter(T*, const char*, T);
virtual void consolidateSettings() = 0;
virtual void consolidateCommonSettings();
protected:
vector<SettingsParameterBase*> mRegisteredParameters;
static TRandom3 mRandomGenerator;
unsigned int mSeed;
bool mVerbose;
int mVerboseLevel;
double mQ2min;
double mQ2max;
double mWmin;
double mWmax;
double mXpomMin;
double mXpomMax;
+ double mbetamin;
+ double mbetamax;
int mVectorMesonId;
string mDipoleModelName;
DipoleModelType mDipoleModelType;
DipoleModelParameterSet mDipoleModelParameterSet;
string mDipoleModelParameterSetName;
TableSetType mTableSetType;
string mTableSetTypeName;
unsigned int mA;
string mRootfile;
bool mUPC;
unsigned int mUPCA;
private:
string mRuncard;
vector<string> mLines;
TDatabasePDG *mPDG;
map<int, string> mPeriodicTable;
int mUserInt;
double mUserDouble;
string mUserString;
};
template<typename T> void Settings::registerParameter(T* var, const char* name, T def)
{
SettingsParameter<T>* sv = new SettingsParameter<T>;
sv->address = var;
sv->name = name;
sv->defaultValue = def;
*var = def;
mRegisteredParameters.push_back(sv);
}
inline TRandom3* Settings::randomGenerator() {return &mRandomGenerator;}
#endif
Index: trunk/src/ModeFinderFunctor.cpp
===================================================================
--- trunk/src/ModeFinderFunctor.cpp (revision 490)
+++ trunk/src/ModeFinderFunctor.cpp (revision 491)
@@ -1,110 +1,183 @@
//==============================================================================
// ModeFinderFunctor.cpp
//
-// Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich
+// Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
//
-// Author: Thomas Ullrich
-// Last update:
+// Author: Tobias Toll
+// Last update:
// $Date$
// $Author$
//==============================================================================
#include "ModeFinderFunctor.h"
-#include "CrossSection.h"
-#include "Kinematics.h"
+#include "CrossSection.h"
+#include "Kinematics.h"
#include <iostream>
using namespace std;
#define PR(x) cout << #x << " = " << (x) << endl;
ModeFinderFunctor::ModeFinderFunctor()
{
mCrossSection = 0;
mQ2 = mVmMass = mMinT = mMaxT = 0;
}
ModeFinderFunctor::ModeFinderFunctor(CrossSection* cs, double Q2, double vmMass, double tmin, double tmax)
{
mCrossSection = cs;
mQ2 = Q2;
mVmMass = vmMass;
mMinT = tmin;
mMaxT = tmax;
}
-
+
+InclusiveDiffractionModeFinderFunctor::InclusiveDiffractionModeFinderFunctor(InclusiveDiffractiveCrossSections* cs, double Q2, double W2, double z, double MX2min, double MX2max)
+{
+ mIDCrossSection = cs;
+ mQ2 = Q2;
+ mW2 = W2;
+ mZ = z;
+
+ mMX2max=MX2max;
+ mMX2min=MX2min;
+}
+
+InclusiveDiffractionModeFinderFunctor::InclusiveDiffractionModeFinderFunctor(InclusiveDiffractiveCrossSections* cs, double Q2, double W2, double z, double s, double MX2min, double MX2max, double Q2min, double Q2max, double W2min, double W2max, double ymin, double betamin, double betamax, double mu02){
+ mIDCrossSection = cs;
+ mQ2 = Q2;
+ mW2 = W2;
+ mZ = z;
+ mS = s;
+ mMinMX2 = MX2min;
+ mMaxMX2 = MX2max;
+
+ mQ2max=Q2max;
+ mQ2min=Q2min;
+ mW2max=W2max;
+ mW2min=W2min;
+ mYmin=ymin;
+ mBetamin=betamin;
+ mBetamax=betamax;
+ mMu02=mu02;
+ mMX2max=MX2max;
+ mMX2min=MX2min;
+}
+
+ROOT::Math::IGenFunction* InclusiveDiffractionModeFinderFunctor::Clone() const
+{
+ return new InclusiveDiffractionModeFinderFunctor(mIDCrossSection, mQ2, mW2, mZ, mS, mMinMX2, mMaxMX2, mQ2min, mQ2max, mW2min, mW2max, mYmin, mBetamin, mBetamax, mMu02);
+}
+
+double InclusiveDiffractionModeFinderFunctor::DoEval(double MX2) const {
+// if(mQ2<mQ2min or mQ2>mQ2max){
+// cout<<"Q2 out of range! Q2="<<mQ2<<", ["<<mQ2min<<", "<<mQ2max<<"]"<<endl;
+// return 0;
+// }
+ if(MX2>mMX2max or MX2<mMX2min){
+// if(cout<<"MX2 out of range! MX2="<<MX2<<", ["<<mMX2min<<", "<<mMX2max<<"]"<<endl;
+ return 0;
+ }
+// if(mW2>mW2max or mW2<mW2min){
+// cout<<"MX2 out of range! MX2="<<MX2<<", ["<<mMX2min<<", "<<mMX2max<<"]"<<endl;
+// return 0;
+// }
+// double x = Kinematics::x(mQ2, mW2);
+// double y = Kinematics::y(mQ2, x, mS);
+// double beta=mQ2/(mQ2+MX2);
+// double xpom=x/beta;
+// if(x<0 or x>1 or beta<0 or beta>1 or xpom<0 or xpom>1){
+// PR(x);
+// PR(y);
+// PR(beta);
+// PR(xpom);
+// return 0;
+// }
+ if (mIDCrossSection) {
+ double result = (*mIDCrossSection)(MX2, mQ2, mW2, mZ);
+ return -result;
+ }
+ else {
+ return 0;
+ }
+}
+
+void InclusiveDiffractionModeFinderFunctor::setQuarkMass(double val) {mMq=val;}
+
void ModeFinderFunctor::setVmMass(double val) {mVmMass = val;}
void ModeFinderFunctor::setQ2(double val) {mQ2 = val;}
void ModeFinderFunctor::setMinT(double val) {mMinT = val;}
void ModeFinderFunctor::setMaxT(double val) {mMaxT = val;}
double ModeFinderFunctor::DoEval(double W2) const
{
if (mCrossSection) {
double t = Kinematics::tmax(0, mQ2, W2, mVmMass); // first arg (t) set to 0 here
if (t > mMaxT) t = mMaxT; // don't exceed given (table) maximum (smallest |t|)
if (t < mMinT) return 0; // lower table limits (treat different than max limit)
double result = (*mCrossSection)(t, mQ2, W2); // t, Q2, W2
return -result; // minimum=maximum
}
else {
return 0;
}
}
ROOT::Math::IGenFunction* ModeFinderFunctor::Clone() const
{
return new ModeFinderFunctor(mCrossSection, mQ2, mVmMass, mMinT, mMaxT);
}
UPCModeFinderFunctor::UPCModeFinderFunctor()
{
mCrossSection = 0;
mVmMass = mHBeamEnergy = mEBeamEnergy = 0;
}
UPCModeFinderFunctor::UPCModeFinderFunctor(CrossSection* cs, double vmMass, double hEnergy, double eEnergy)
{
mCrossSection = cs;
mVmMass = vmMass;
mHBeamEnergy = hEnergy;
mEBeamEnergy = eEnergy;
}
double UPCModeFinderFunctor::DoEval(double val) const
{
if (mCrossSection) {
double xpom = exp(val); // x comes as log(x)
double t = Kinematics::tmax(xpom);
bool ok = Kinematics::validUPC(mHBeamEnergy, mEBeamEnergy, t, xpom, mVmMass, false);
if (ok) {
double result = (*mCrossSection)(t, xpom);
return -result; // minimum=maximum
}
else {
return 0;
}
}
else {
return 0;
}
}
ROOT::Math::IGenFunction* UPCModeFinderFunctor::Clone() const
{
return new UPCModeFinderFunctor(mCrossSection, mVmMass, mHBeamEnergy, mEBeamEnergy);
}
+
Index: trunk/src/TableGeneratorSettings.cpp
===================================================================
--- trunk/src/TableGeneratorSettings.cpp (revision 490)
+++ trunk/src/TableGeneratorSettings.cpp (revision 491)
@@ -1,217 +1,217 @@
//==============================================================================
// TableGeneratorSettings.cpp
//
-// Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich
+// Copyright (C) 2010-2024 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 <http://www.gnu.org/licenses/>.
//
// Author: Tobias Toll
// Last update:
// $Date$
// $Author$
//==============================================================================
#include "Settings.h"
#include "TableGeneratorSettings.h"
#include "Constants.h"
#include <cmath>
#include <ctime>
#include <vector>
#include <stdlib.h>
using namespace std;
TableGeneratorSettings* TableGeneratorSettings::mInstance = 0; // initialize static
TableGeneratorSettings* TableGeneratorSettings::instance()
{
if (mInstance == 0)
mInstance = new TableGeneratorSettings;
return mInstance;
}
TableGeneratorSettings::TableGeneratorSettings()
{
//
// Register all the parameters that can be defined
// via a runcard.
// Arguments for registerParameter():
// 1. pointer to data memeber
// 2. text string to be used in the runcard
// 3. default parameter set
//
registerParameter(&mBSatLookupPath, "bSatLookupPath", string("./"));
registerParameter(&mTmin, "tmin", -2.);
registerParameter(&mTmax, "tmax", 0.);
registerParameter(&mXmin, "xmin", 1e-9); //UPC
registerParameter(&mXmax, "xmax", 3e-2); //UPC
registerParameter(&mQ2bins, "Q2bins", static_cast<unsigned int>(1));
registerParameter(&mW2bins, "W2bins", static_cast<unsigned int>(1));
registerParameter(&mTbins, "tbins", static_cast<unsigned int>(1));
registerParameter(&mXbins, "xbins", static_cast<unsigned int>(1)); //UPC
registerParameter(&mNumberOfConfigurations, "numberOfConfigurations", static_cast<unsigned int>(1000));
vector<double> vec;
registerParameter(&mDipoleModelCustomParameters, "dipoleModelCustomParameters", vec);
registerParameter(&mUseBackupFile, "useBackupFile", false);
registerParameter(&mStartingBinFromBackup, "startingBinFromBackup", 0);
registerParameter(&mStartBin, "startBin", -1);
registerParameter(&mEndBin, "endBin", -1);
registerParameter(&mModesToCalculate, "modesToCalculate", 0);
registerParameter(&mPriority, "priority", 0);
registerParameter(&mHasSubstructure, "hasSubstructure", false);
registerParameter(&mFractionOfBinsToFill, "fractionOfBinsToFill", 1.);
}
void TableGeneratorSettings::consolidateSettings() // called after runcard is read
{
//
// Kinematic limits
//
if (mQ2min>=mQ2max && !mUPC) {
cout << "TableGeneratorSettings::consolidateSettings(): Error, Q2min >= Q2max. Stopping" << endl;
exit(1);
}
if (mWmin>=mWmax && !mUPC) {
cout << "TableGeneratorSettings::consolidateSettings(): Error, Wmin >= Wmax. Stopping" << endl;
exit(1);
}
if (mTmin>=mTmax) {
cout << "TableGeneratorSettings::consolidateSettings(): Error, tmin >= tmax. Stopping" << endl;
exit(1);
}
if (mTmin>0. || mTmax >0.) {
cout << "TableGeneratorSettings::consolidateSettings(): Error, t must be negative, please change t-limits. Stopping" << endl;
exit(1);
}
if (mXmin>=mXmax && mUPC) {
cout << "TableGeneratorSettings::consolidateSettings(): Error, xmin >= xmax. Stopping" << endl;
exit(1);
}
if ((mXmin>=1 || mXmin<=0 || mXmax>=1 || mXmax<=0) && mUPC) {
cout << "TableGeneratorSettings::consolidateSettings(): Error, xmin or xmax out of range. Stopping" << endl;
exit(1);
}
if (mXmax>0.01 && mUPC){
cout << "TableGeneratorSettings::consolidateSettings(): Warning, xmax>1e-2, model may be unreliable." << endl;
}
if (mA==1 && !mHasSubstructure) mNumberOfConfigurations = 1;
if (!mUseBackupFile) mStartingBinFromBackup = 0;
if (!mUPC)
mXbins=1;
else {
mQ2bins=1;
mW2bins=1;
}
if (mStartBin >= 0 && mEndBin >= 0 && mStartBin>mEndBin) {
cout << "TableGeneratorSettings::consolidateSettings(): Error, endBin < startBin : " << mEndBin << " <= " << mStartBin << "! Stopping." << endl;
exit(1);
}
if ( mStartBin < 0 ) mStartBin=0;
if ( mStartBin >= signed(mQ2bins*mW2bins*mTbins*mXbins) ) {
cout << "TableGeneratorSettings::consolidateSettings(): Error, starting bin >= table! Stopping." << endl;
exit(1);
}
if ( mEndBin > signed(mQ2bins*mW2bins*mTbins*mXbins) || mEndBin < 0) {
cout << "TableGeneratorSettings::consolidateSettings(): endBin is set to table size=" << mQ2bins*mW2bins*mTbins << endl;
mEndBin=mQ2bins*mW2bins*mTbins*mXbins;
}
if ( mModesToCalculate < 0 || mModesToCalculate > 2 ) {
cout << "TableGeneratorSettings::consolidateSettings(): Error, modesToCalculate can only take values 0, 1, or 2; not "
<< mModesToCalculate << endl;
exit(1);
}
//
// Make sure the W range is allowed
//
double VMMass=lookupPDG(mVectorMesonId)->Mass();
double W2min=VMMass*VMMass+protonMass2;
double Wmin=sqrt(W2min);
if (mWmin<Wmin){
mWmin=Wmin;
cout << "TableGeneratorSettings::consolidateSettings(): Warning, Wmin is smaller than allowed value." << endl;
cout << " It has been changed to Wmin=" << mWmin << endl;
}
}
//
// Access functions
//
void TableGeneratorSettings::setTmax(double val){ mTmax=val; }
double TableGeneratorSettings::tmax() const { return mTmax; }
void TableGeneratorSettings::setTmin(double val){ mTmin=val; }
double TableGeneratorSettings::tmin() const { return mTmin; }
void TableGeneratorSettings::setXmax(double val){ mXmax=val; }
double TableGeneratorSettings::xmax() const { return mXmax; }
void TableGeneratorSettings::setXmin(double val){ mXmin=val; }
double TableGeneratorSettings::xmin() const { return mXmin; }
void TableGeneratorSettings::setQ2bins(unsigned int val){ mQ2bins=val; }
unsigned int TableGeneratorSettings::Q2bins() const { return mQ2bins; }
void TableGeneratorSettings::setW2bins(unsigned int val){ mW2bins=val; }
unsigned int TableGeneratorSettings::W2bins() const { return mW2bins; }
void TableGeneratorSettings::setTbins(unsigned int val){ mTbins=val; }
unsigned int TableGeneratorSettings::tbins() const { return mTbins; }
void TableGeneratorSettings::setXbins(unsigned int val){ mXbins=val; }
unsigned int TableGeneratorSettings::xbins() const { return mXbins; }
void TableGeneratorSettings::setBSatLookupPath(string val){ mBSatLookupPath = val; }
string TableGeneratorSettings::bSatLookupPath() const { return mBSatLookupPath; }
void TableGeneratorSettings::setNumberOfConfigurations(unsigned int val){ mNumberOfConfigurations=val; }
unsigned int TableGeneratorSettings::numberOfConfigurations() const { return mNumberOfConfigurations; }
vector<double> TableGeneratorSettings::dipoleModelCustomParameters() const {return mDipoleModelCustomParameters;}
void TableGeneratorSettings::setUseBackupFile(bool val){ mUseBackupFile = val; }
bool TableGeneratorSettings::useBackupFile() const { return mUseBackupFile; }
void TableGeneratorSettings::setStartingBinFromBackup(int val){ mStartingBinFromBackup = val; }
int TableGeneratorSettings::startingBinFromBackup() const { return mStartingBinFromBackup; }
void TableGeneratorSettings::setStartBin(int val){ mStartBin = val; }
int TableGeneratorSettings::startBin() const { return mStartBin; }
void TableGeneratorSettings::setEndBin(int val){ mEndBin = val; }
int TableGeneratorSettings::endBin() const{ return mEndBin; }
void TableGeneratorSettings::setModesToCalculate(int val){ mModesToCalculate = val; }
int TableGeneratorSettings::modesToCalculate() const { return mModesToCalculate; }
void TableGeneratorSettings::setPriority(unsigned char val){ mPriority = val; }
unsigned char TableGeneratorSettings::priority() const { return mPriority; }
void TableGeneratorSettings::setHasSubstructure(bool val){ mHasSubstructure = val; }
bool TableGeneratorSettings::hasSubstructure() const { return mHasSubstructure; }
void TableGeneratorSettings::setFractionOfBinsToFill(double val){ mFractionOfBinsToFill = val; }
double TableGeneratorSettings::fractionOfBinsToFill() const { return mFractionOfBinsToFill; }
Index: trunk/src/Kinematics.cpp
===================================================================
--- trunk/src/Kinematics.cpp (revision 490)
+++ trunk/src/Kinematics.cpp (revision 491)
@@ -1,455 +1,531 @@
//==============================================================================
// Kinematics.cpp
//
-// Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich
+// Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich
//
-// This file is part of Sartre.
+// 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.
+// 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 <http://www.gnu.org/licenses/>.
//
// Author: Thomas Ullrich
-// Last update:
+// Last update:
// $Date$
// $Author$
//------------------------------------------------------------------------------
//
// Note that Kinematics is only meant for ep and eA scattering.
// It is not applicable for UPC kinematics. Use UpcKinematics instead.
//
//==============================================================================
-#include "Kinematics.h"
-#include <cmath>
-#include <iostream>
+#include "Kinematics.h"
+#include <cmath>
+#include <iostream>
#include "Math/RootFinder.h"
#include "Math/BrentRootFinder.h"
#include "Math/GSLRootFinder.h"
-#include "Math/RootFinderAlgorithms.h"
+#include "Math/RootFinderAlgorithms.h"
#include "Math/IFunction.h"
#include "Math/BrentMinimizer1D.h"
// TMP
#include "TH1D.h"
#include "TFile.h"
-#define PR(x) cout << #x << " = " << (x) << endl;
-
-using namespace std;
-
-bool Kinematics::mError = false;
-
-bool Kinematics::error() {return mError;}
+#define PR(x) cout << #x << " = " << (x) << endl;
+
+using namespace std;
+
+bool Kinematics::mError = false;
+
+bool Kinematics::error() {return mError;}
//UPC:
double Kinematics::mXpomMin=0;
double Kinematics::mTold=0;
bool Kinematics::mXpomMinIsEvaluated=false;
//
-double Kinematics::xprobe(double Q2, double W2, double vmMass)
-{
- mError = false;
- double val = ( Q2 + vmMass*vmMass ) / (W2 - protonMass2 + Q2);
- if (val > 1 || val < 0) mError = true;
- return val;
-}
+double Kinematics::xprobe(double Q2, double W2, double vmMass)
+{
+ mError = false;
+ double val = ( Q2 + vmMass*vmMass ) / (W2 - protonMass2 + Q2);
+ if (val > 1 || val < 0) mError = true;
+ return val;
+}
TLorentzVector Kinematics::electronBeam(double eE, bool upc)
-{
+{
mError = false;
if (upc)
return TLorentzVector(0, 0, -sqrt(eE*eE-protonMass2), eE);
else
return TLorentzVector(0, 0, -sqrt(eE*eE-electronMass2), eE);
-}
-
-TLorentzVector Kinematics::hadronBeam(double hE)
-{
- mError = false;
- return TLorentzVector(0, 0, sqrt(hE*hE-protonMass2), hE);
-}
-
-double Kinematics::s(const TLorentzVector& e, const TLorentzVector& p)
-{
- mError = false;
- return (e+p)*(e+p);
-}
-
-double Kinematics::s(double eE, double hE, bool upc)
-{
- mError = false;
- TLorentzVector e = electronBeam(eE, upc);
- TLorentzVector p = hadronBeam(hE);
- return (e+p)*(e+p);
-}
-
-double Kinematics::x(double Q2, double W2)
-{
- mError = false;
- double val = Q2/(W2-protonMass2+Q2);
- if (val > 1 || val < 0) mError = true;
+}
+
+TLorentzVector Kinematics::hadronBeam(double hE)
+{
+ mError = false;
+ return TLorentzVector(0, 0, sqrt(hE*hE-protonMass2), hE);
+}
+
+double Kinematics::s(const TLorentzVector& e, const TLorentzVector& p)
+{
+ mError = false;
+ return (e+p)*(e+p);
+}
+
+double Kinematics::s(double eE, double hE, bool upc)
+{
+ mError = false;
+ TLorentzVector e = electronBeam(eE, upc);
+ TLorentzVector p = hadronBeam(hE);
+ return (e+p)*(e+p);
+}
+
+double Kinematics::x(double Q2, double W2)
+{
+ mError = false;
+ double val = Q2/(W2-protonMass2+Q2);
+ if (val > 1 || val < 0) mError = true;
return val;
-}
-
-double Kinematics::y(double Q2, double x, double s)
-{
- mError = false;
- double val = Q2/(x*(s-electronMass2-protonMass2));
- if (val > 1 || val < 0) mError = true;
- return val;
-}
-
-double Kinematics::ymin(double s, double vmMass)
-{
- mError = false;
- double W2min = Kinematics::W2min(vmMass);
- double val = (s + W2min - sqrt((s-W2min)*(s-W2min)-4*electronMass2*W2min))/2/(s+electronMass2);
- if (val > 1 || val < 0) mError = true;
- return val;
-}
-
-double Kinematics::ymax(double s, double vmMass)
-{
- mError = false;
- double W2min = Kinematics::W2min(vmMass);
- double val = (s + W2min + sqrt((s-W2min)*(s-W2min)-4*electronMass2*W2min))/2/(s+electronMass2);
- if (val > 1 || val < 0) mError = true;
- return val;
-}
-
-double Kinematics::W2(double Q2, double x)
-{
- //
- // Returns W2 at a given Q2 and Bjorken x
- //
- mError = false;
- return protonMass2 + Q2*(1-x)/x;
-}
-
-double Kinematics::W2(double Q2, double xprobe, double vmMass)
-{
- //
- // Returns W2 at a given Q2 and xprobe
- // where xprobe is
- // xprobe = xBJ * (1 + MV^2/Q2)
- //
- mError = false;
- return protonMass2 + vmMass*vmMass/xprobe + Q2*(1-xprobe)/xprobe;
-}
-
-double Kinematics::W2min(double vmMass)
-{
- mError = false;
- // return vmMass*vmMass + protonMass2;
- return (vmMass + protonMass)*(vmMass + protonMass);
-}
-
-double Kinematics::W2max(double s)
-{
- mError = false;
- return s; // check !?
-}
-
-double Kinematics::Q2min(double y)
-{
- mError = false;
- return electronMass2*y*y/(1-y);
-}
-
-double Kinematics::Q2max(double s)
-{
- mError = false;
- return s-electronMass2-protonMass2;
-}
-
-double Kinematics::xpomeron(double t, double Q2, double W2, double vmM)
-{
- mError = false;
- double val = (vmM*vmM + Q2 - t)/(W2 + Q2 - protonMass2); // full expression
- if (val > 1 || val < 0) mError = true;
- return val;
-}
-
-double Kinematics::tmax(double xpom)
-{
- mError = false;
- return (- xpom*xpom * protonMass2 / (1-xpom)); // only if m_p (in) = m_p' (out) - to be fixed
-}
-
-double Kinematics::tmax(double t, double Q2, double W2, double vmM)
-{
- return tmax(xpomeron(t, Q2, W2, vmM));
-}
-
-double Kinematics::tmin(double eE)
-{
- mError = false;
- return -2*(eE*protonMass-protonMass2); // check ?!
-}
+}
+
+double Kinematics::y(double Q2, double x, double s)
+{
+ mError = false;
+ double val = Q2/(x*(s-electronMass2-protonMass2));
+ if (val > 1 || val < 0) mError = true;
+ if( val>1 ) val=0.9999; //#TT hack
+ return val;
+}
+
+double Kinematics::ymin(double s, double vmMass)
+{
+ mError = false;
+ double W2min = Kinematics::W2min(vmMass);
+ double val = (s + W2min - sqrt((s-W2min)*(s-W2min)-4*electronMass2*W2min))
+ /2/(s+electronMass2);
+ if (val > 1 || val < 0) mError = true;
+ return val;
+}
+
+double Kinematics::ymax(double s, double vmMass)
+{
+ mError = false;
+ double W2min = Kinematics::W2min(vmMass);
+ double val = (s + W2min + sqrt((s-W2min)*(s-W2min)-4*electronMass2*W2min))/2/(s+electronMass2);
+ if (val > 1 || val < 0) mError = true;
+ return val;
+}
+
+double Kinematics::W2(double Q2, double x)
+{
+ //
+ // Returns W2 at a given Q2 and Bjorken x
+ //
+ mError = false;
+ return protonMass2 + Q2*(1-x)/x;
+}
+
+double Kinematics::W2(double Q2, double xprobe, double vmMass)
+{
+ //
+ // Returns W2 at a given Q2 and xprobe
+ // where xprobe is
+ // xprobe = xBJ * (1 + MV^2/Q2)
+ //
+ mError = false;
+ return protonMass2 + vmMass*vmMass/xprobe + Q2*(1-xprobe)/xprobe;
+}
+
+double Kinematics::W2min(double vmMass)
+{
+ mError = false;
+ return vmMass*vmMass + protonMass2;
+}
+
+double Kinematics::W2max(double s)
+{
+ mError = false;
+ return s; // check !?
+}
+double Kinematics::W2max(double s, double Q2, double MX)
+{
+ double ymax=Kinematics::ymax(s, MX);
+ mError = false;
+ return ymax*s-Q2+protonMass2; // check !?
+}
+double Kinematics::betamin(double Q2, double s, double MX, double t){
+ double ymax=Kinematics::ymax(s, MX);
+ return Q2/(ymax*s-protonMass2-t);
+}
+
+double Kinematics::Q2min(double y)
+{
+ mError = false;
+ return electronMass2*y*y/(1-y);
+}
+
+double Kinematics::Q2max(double s)
+{
+ mError = false;
+ return s-electronMass2-protonMass2;
+}
+double Kinematics::xpomeron(double t, double Q2, double W2, double vmM)
+{
+ mError = false;
+ double val = (vmM*vmM + Q2 - t)/(W2 + Q2 - protonMass2); // full expression
+ if (val > 1 || val < 0) mError = true;
+ return val;
+}
+
+double Kinematics::tmax(double xpom)
+{
+ mError = false;
+ return (- xpom*xpom * protonMass2 / (1-xpom)); // only if m_p (in) = m_p' (out) - to be fixed
+}
+
+double Kinematics::tmax(double t, double Q2, double W2, double vmM)
+{
+ return tmax(xpomeron(t, Q2, W2, vmM));
+}
+
+double Kinematics::tmin(double eE)
+{
+ mError = false;
+ return -2*(eE*protonMass-protonMass2); // check ?!
+}
+double Kinematics::MX2(double Q2, double beta, double t){
+ return Q2*(1-beta)/beta+t;
+}
//
// UPC only
//
double Kinematics::xpomMin(double massVM, double t, TLorentzVector hBeam, TLorentzVector eBeam, double MY2minusM2){
- if (mXpomMinIsEvaluated && mTold == t) return mXpomMin;
+ if(mXpomMinIsEvaluated and mTold == t) return mXpomMin;
LowerXpomeronFormula formula;
mTold = t;
formula.mT = t;
formula.mVmMass2=massVM*massVM;
formula.mElectronBeam = eBeam;
formula.mHadronBeam = hBeam;
formula.mMY2minusM2 = MY2minusM2;
//
//Find starting brackets
//
double lower=1e-12;
double upper=1e-1;
//
// Find minimum and use as lower
// bracket to avoid two roots
//
ROOT::Math::BrentMinimizer1D bm;
bm.SetFunction(formula, log(lower), log(upper));
bm.Minimize(100000, 1e-8, 1e-10);
double theMin = bm.XMinimum();
-
+
//
// Run root finder
//
ROOT::Math::RootFinder rootfinder(ROOT::Math::RootFinder::kBRENT);
rootfinder.SetFunction(formula, theMin, log(upper));
rootfinder.Solve(100000000, 1e-14, 0);
-
+
//
// Now some fine adjustements
//
double bestGuess = rootfinder.Root();
int ntimes = 0;
while (formula.DoEval(bestGuess) < 0) {
bestGuess += 1e-14;
ntimes++;
if (ntimes> 10000) break;
}
double result = exp(bestGuess);
double s = (hBeam+eBeam).M2();
mXpomMin = max(result, xpomMin(s, massVM, t));
mXpomMinIsEvaluated = true;
return mXpomMin;
}
double Kinematics::xpomMin(double s, double vmM, double t) {
- //
- // This is the threshold value.
- // In some cases a more restrictive value may be needed
- //
- return (electronMass2 + protonMass2 + vmM*vmM - t)/s;
+ //
+ // This is the threshold value.
+ // In some cases a more restrictive value may be needed
+ //
+ return (electronMass2 + protonMass2 + vmM*vmM - t)/s;
}
double Kinematics::Egamma(double xpom, double t, double vmM, double hBeamEnergy, double eBeamEnergy, double MY2minusM2)
{
//
// We use that the vector meson = photon + pomeron to calculate Egamma
// (keeping the pomeron variables from above)
// We solve a quadratic equation to get the photon energy such that
// the vector meson has the correct mass.
//
double Ep=hBeamEnergy;
double Pp=-sqrt(Ep*Ep-protonMass2);
double Ee=eBeamEnergy;
double Pe=sqrt(Ee*Ee-protonMass2);
double sqrtarg= 1 - ( (2*xpom - xpom*xpom)*Pp*Pp + t - MY2minusM2) / (Ep*Ep);
double Epom=Ep*(1-sqrt(sqrtarg)); //this is close to xpom*Ep
double Ppom=xpom*Pp;
double AA = vmM*vmM - Epom*Epom - t + Ppom*Ppom + 2*Pe*(Pe+Ppom); //GeV^2
double aa = 4*(Pe+Ppom)*(Pe+Ppom) - 4*(Ee+Epom)*(Ee+Epom); //GeV^2
double bb = 4*AA*(Ee+Epom) - 8*(Pe+Ppom)*(Pe+Ppom)*Ee; //GeV^3
double cc = 4*(Pe+Ppom)*(Pe+Ppom)*Pe*Pe - AA*AA;
sqrtarg = bb*bb-4*aa*cc;
if (sqrtarg < 0) {
//This is used by validUPC as a sign of failure, needs to return something negative
return -1.;
}
return ( -bb + sqrt(sqrtarg) )/(2*aa); //GeV
-}
+}
//
// UPC only
//
bool Kinematics::validUPC(double hBeamEnergy, double eBeamEnergy, double t, double xpom, double vmMass, bool verbose)
{
//
// Here we perform all complete test of all kinematic variables
//
//
// xpom
//
double s = Kinematics::s(eBeamEnergy, hBeamEnergy, true);
double Egam = Egamma(xpom, t, vmMass, hBeamEnergy, eBeamEnergy);
double minxpom = xpomMin(s, vmMass, t);
if (xpom < minxpom) {
- if (verbose) cout << "Kinematics::validUPC(): reject t=" << t << " and xpom=" << xpom
+ if(verbose) cout << "Kinematics::validUPC(): reject t=" << t << " and xpom=" << xpom
<< " because xpom < xpomMin (" << minxpom << ")" << endl;
return false;
}
if (Egam < 0) {
- if (verbose) cout << "Kinematics::validUPC(): reject t=" << t << " and xpom=" << xpom
+ if(verbose) cout << "Kinematics::validUPC(): reject t=" << t << " and xpom=" << xpom
<< " because Egamma < 0 (" << Egam << ")" << endl;
return false;
}
if (xpom > 1) {
- if (verbose) cout << "Kinematics::validUPC(): reject xpom="<<xpom<< " because xpom > 1" << endl;
+ if(verbose) cout << "Kinematics::validUPC(): reject xpom="<<xpom<< " because xpom > 1" << endl;
return false;
}
//
// t
//
double t_max=tmax(xpom);
if (t > t_max) {
if (verbose) cout << "Kinematics::validUPC(): reject t=" << t << " because t > tmax (" << t_max << ")" << endl;
return false;
}
return true; //survived all tests
}
-bool Kinematics::valid(double s, double t, double Q2, double W2, double vmMass,
- bool useTrueXp, bool verbose)
-{
- //
- // Here we perform all complete test of all kinematic variables
- //
- double x = Kinematics::x(Q2, W2);
- double y = Kinematics::y(Q2, x, s);
-
- //
- // W
- //
- if (W2 < Kinematics::W2min(vmMass)) {
- if (verbose) cout << "Kinematics::valid(): reject W=" << sqrt(W2) << " because W < Wmin" << endl;
- return false;
- }
- if (W2 > Kinematics::W2max(s)) {
- if (verbose) cout << "Kinematics::valid(): reject W=" << sqrt(W2) << " because W > Wmax" << endl;
- return false;
- }
-
- //
- // y range
- //
- double ymin = Kinematics::ymin(s, vmMass);
- double ymax = Kinematics::ymax(s, vmMass);
- if (y < ymin || y > ymax) {
- if (verbose) cout << "Kinematics::valid(): reject y=" << y << " because y < ymin (" << ymin
- << ") || y > ymax (" << ymax << ")" << endl;
- return false;
- }
-
- //
- // x and y
- //
- if (x < 0 || x > 1) {
- if (verbose) cout << "Kinematics::valid(): reject x=" << x << " because x < 0 || x > 1" << endl;
- return false;
- }
-
- //
- // Q2
- //
- if (Q2 > Kinematics::Q2max(s)) {
- if (verbose) cout << "Kinematics::valid(): reject Q2=" << Q2 << " because Q2 > Q2max" << endl;
- return false;
- }
- if (Q2 < Kinematics::Q2min(y)) {
- if (verbose) cout << "Kinematics::valid(): reject Q2=" << Q2 << " because Q2 < Q2min" << endl;
- return false;
- }
-
- //
- // t
- //
- // On calculating xpomeron. xpomeron() provides the correct value
- // (not neglecting t or nucleon mass). However, during initialization
- // to avoid recursion we set t=0. Calling valid() with t != 0 would
- // reject these values. In this case useTrueXp is set to false.
- // For final checks if an event has the correct kinematics we have
- // to set useTrueXp = true.
- //
- double xpom;
- if (useTrueXp)
- xpom = Kinematics::xpomeron(t, Q2, W2, vmMass);
- else
- xpom = Kinematics::xpomeron(0, Q2, W2, vmMass);
- double tmax = Kinematics::tmax(xpom);
- if (t > tmax) {
- if (verbose) cout << "Kinematics::valid(): reject t=" << t << " because t > tmax (" << tmax << ")" << endl;
- return false;
- }
-
-
- //
- // xpom
- //
- if (xpom < 0 || xpom > 1) {
- if (verbose) cout << "Kinematics::valid(): reject xpom=" << xpom << " because xpom < 0 || xpom > 1" << endl;
- return false;
- }
- if (x > xpom) {
- if (verbose) cout << "Kinematics::valid(): reject since x=" << x << " > xpom = " << xpom << endl;
- return false;
- }
-
- return true; // survived all tests
-}
+bool Kinematics::valid(double s, double beta, double Q2, double W2, double z, double MX, bool useTrueXp, bool verbose){
+ double x = Kinematics::x(Q2, W2);
+ double y = Kinematics::y(Q2, x, s);
+ double xpom=x/beta;
+ if(beta<x){
+ if (verbose) cout << "Kinematics::valid(): reject beta=" << beta << " because beta < x=" << x<<endl;
+ return false;
+ }
+ if(beta>1.){
+ if (verbose) cout << "Kinematics::valid(): reject beta=" << beta << " because beta > 1" <<endl;
+ return false;
+ }
+ if(z<0 or z>1)
+ return false;
+ if (W2 < Kinematics::W2min(MX)) {
+ if (verbose) cout << "Kinematics::valid(): reject W=" << sqrt(W2) << " because W < Wmin" << endl;
+ return false;
+ }
+ if (W2 > Kinematics::W2max(s, Q2, MX)) {
+ if (verbose) cout << "Kinematics::valid(): reject W=" << sqrt(W2) << " because W > Wmax="<<sqrt(Kinematics::W2max(s, Q2, MX)) << endl;
+ return false;
+ }
+ double ymin = Kinematics::ymin(s, MX);
+ double ymax = Kinematics::ymax(s, MX);
+ if (y < ymin || y > ymax) {
+ if (verbose) cout << "Kinematics::valid(): reject y=" << y << " because y < ymin (" << ymin
+ << ") || y > ymax (" << ymax << ")" << endl;
+ return false;
+ }
+ //
+ // x and y
+ //
+ if (x < 0 || x > 1) {
+ if (verbose) cout << "Kinematics::valid(): reject x=" << x << " because x < 0 || x > 1" << endl;
+ return false;
+ }
+
+ //
+ // Q2
+ //
+ if (Q2 > Kinematics::Q2max(s)) {
+ if (verbose) cout << "Kinematics::valid(): reject Q2=" << Q2 << " because Q2 > Q2max (" << Kinematics::Q2max(s) << ")" << endl;
+ return false;
+ }
+ if (Q2 < Kinematics::Q2min(y)) {
+ if (verbose) cout << "Kinematics::valid(): reject Q2=" << Q2 << " because Q2 < Q2min (" <<Kinematics::Q2min(y)<<")" << endl;
+ return false;
+ }
+ //
+ // xpom
+ //
+ if (xpom < 0 || xpom > 1) {
+ if (verbose) cout << "Kinematics::valid(): reject xpom=" << xpom << " because xpom < 0 || xpom > 1" << endl;
+ return false;
+ }
+ if (x > xpom) {
+ if (verbose) cout << "Kinematics::valid(): reject since x=" << x << " > xpom = " << xpom << endl;
+ return false;
+ }
+
+ return true;
+}
+
+bool Kinematics::valid(double s, double t, double Q2, double W2, double vmMass,
+ bool useTrueXp, bool verbose)
+{
+ //
+ // Here we perform all complete test of all kinematic variables
+ //
+ double x = Kinematics::x(Q2, W2);
+ double y = Kinematics::y(Q2, x, s);
+
+ //
+ // W
+ //
+ if (W2 < Kinematics::W2min(vmMass)) {
+ if (verbose) cout << "Kinematics::valid(): reject W=" << sqrt(W2) << " because W < Wmin" << endl;
+ return false;
+ }
+ if (W2 > Kinematics::W2max(s)) {
+ if (verbose) cout << "Kinematics::valid(): reject W=" << sqrt(W2) << " because W > Wmax" << endl;
+ return false;
+ }
+
+ //
+ // y range
+ //
+ double ymin = Kinematics::ymin(s, vmMass);
+ double ymax = Kinematics::ymax(s, vmMass);
+ if (y < ymin || y > ymax) {
+ if (verbose) cout << "Kinematics::valid(): reject y=" << y << " because y < ymin (" << ymin
+ << ") || y > ymax (" << ymax << ")" << endl;
+ return false;
+ }
+
+ //
+ // x and y
+ //
+ if (x < 0 || x > 1) {
+ if (verbose) cout << "Kinematics::valid(): reject x=" << x << " because x < 0 || x > 1" << endl;
+ return false;
+ }
+
+ //
+ // Q2
+ //
+ if (Q2 > Kinematics::Q2max(s)) {
+ if (verbose) cout << "Kinematics::valid(): reject Q2=" << Q2 << " because Q2 > Q2max" << endl;
+ return false;
+ }
+ if (Q2 < Kinematics::Q2min(y)) {
+ if (verbose) cout << "Kinematics::valid(): reject Q2=" << Q2 << " because Q2 < Q2min" << endl;
+ return false;
+ }
+
+ //
+ // t
+ //
+ // On calculating xpomeron. xpomeron() provides the correct value
+ // (not neglecting t or nucleon mass). However, during initialization
+ // to avoid recursion we set t=0. Calling valid() with t != 0 would
+ // reject these values. In this case useTrueXp is set to false.
+ // For final checks if an event has the correct kinematics we have
+ // to set useTrueXp = true.
+ //
+ double xpom;
+ if (useTrueXp)
+ xpom = Kinematics::xpomeron(t, Q2, W2, vmMass);
+ else
+ xpom = Kinematics::xpomeron(0, Q2, W2, vmMass);
+ double tmax = Kinematics::tmax(xpom);
+ if (t > tmax) {
+ if (verbose) cout << "Kinematics::valid(): reject t=" << t << " because t > tmax (" << tmax << ")" << endl;
+ return false;
+ }
+
+
+ //
+ // xpom
+ //
+ if (xpom < 0 || xpom > 1) {
+ if (verbose) cout << "Kinematics::valid(): reject xpom=" << xpom << " because xpom < 0 || xpom > 1" << endl;
+ return false;
+ }
+ if (x > xpom) {
+ if (verbose) cout << "Kinematics::valid(): reject since x=" << x << " > xpom = " << xpom << endl;
+ return false;
+ }
+
+ return true; // survived all tests
+}
ROOT::Math::IBaseFunctionOneDim* LowerXpomeronFormula::Clone() const
{
return new LowerXpomeronFormula();
}
double LowerXpomeronFormula::DoEval(double logxpom) const
{
double xpom = exp(logxpom);
//Start by setting up the knowns: Incoming beams, xpom, and t:
double Ee=mElectronBeam.E();
double Pe=mElectronBeam.Pz();
double Pp=mHadronBeam.Pz();
double Ep=mHadronBeam.E();
double E, pz;
//
// Use scattered proton to set up four momentum of pomeron (so far assuming no break-up):
//
double sqrtarg= 1 - ( (2*xpom - xpom*xpom)*Pp*Pp + mT - mMY2minusM2) / (Ep*Ep);
E=Ep*(1-sqrt(sqrtarg)); //this is close to xpom*Ep
pz=xpom*Pp;
//
// Next we use that the vector meson = photon + pomeron to calculate Egamma
// (keeping the pomeron variables from above)
// We solve a quadratic equation to get the photon energy such that
// the vector meson has the correct mass.
//
double AA = mVmMass2 - E*E - mT + pz*pz + 2*Pe*(Pe+pz); //GeV^2
double aa = 4*(Pe+pz)*(Pe+pz) - 4*(Ee+E)*(Ee+E); //GeV^2
double bb = 4*AA*(Ee+E) - 8*(Pe+pz)*(Pe+pz)*Ee; //GeV^3
double cc = 4*(Pe+pz)*(Pe+pz)*Pe*Pe - AA*AA;
sqrtarg = bb*bb-4*aa*cc;
return sqrtarg;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, May 3, 6:27 AM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4983028
Default Alt Text
(176 KB)
Attached To
rSARTRESVN sartresvn
Event Timeline
Log In to Comment