diff --git a/IOMC/Elegent/BuildFile.xml b/IOMC/Elegent/BuildFile.xml new file mode 100644 index 00000000000..981a835f04d --- /dev/null +++ b/IOMC/Elegent/BuildFile.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/IOMC/Elegent/bin/BuildFile.xml b/IOMC/Elegent/bin/BuildFile.xml new file mode 100644 index 00000000000..d77077d2305 --- /dev/null +++ b/IOMC/Elegent/bin/BuildFile.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/IOMC/Elegent/bin/ElegentBDistributionSampler.cc b/IOMC/Elegent/bin/ElegentBDistributionSampler.cc new file mode 100644 index 00000000000..30198804b61 --- /dev/null +++ b/IOMC/Elegent/bin/ElegentBDistributionSampler.cc @@ -0,0 +1,253 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include +#include +#include + +#include "interface/Constants.h" +#include "interface/ModelFactory.h" + +#include "TFile.h" +#include "TGraph.h" + +using namespace Elegent; +using namespace std; + + +//---------------------------------------------------------------------------------------------------- + +void PrintUsage() +{ + printf("USAGE: ElegentBDistributionSampler [option] [option] ...\n"); + printf("OPTIONS:\n"); + printf("\t-h\t\t\tprint this help and exit\n"); + printf("\t-energy \t\tset collision energy (i.e. sqrt(s)), in GeV\n"); + printf("\t-pp\t\t\tselect proton-proton interactions\n"); + printf("\t-app\t\t\tselect antiproton-proton interactions\n"); + printf("\t-N \t\tnumber of sampling points\n"); + printf("\t-bmin \t\tlower bound of b (in fm) for sampling\n"); + printf("\t-bmax \t\tupper bound of b (in fm) for sampling\n"); + printf("\t-models \tsemicolon-separated list of model tags\n"); + printf("\t-l, -model-list\t\tprint list of available model tags and exit\n"); + printf("\t-output \toutput file name\n"); +} + +//---------------------------------------------------------------------------------------------------- + +void PrintModelList() +{ + Constants::Init(1., Constants::mPP); + ModelFactory mf; + mf.PrintList(); +} + +//---------------------------------------------------------------------------------------------------- + +int InitModels(const string& hadronicModelsString, vector &models) +{ + ModelFactory mf; + + size_t p_curr = 0; + while (true) + { + size_t p_next = hadronicModelsString.find(';', p_curr); + string tag = (p_next != string::npos) ? hadronicModelsString.substr(p_curr, p_next - p_curr) : hadronicModelsString.substr(p_curr); + + model = mf.MakeInstance(tag); + + if (model == NULL) + return 3; + + models.push_back(model); + + printf("\n>> model with tag `%s':\n", tag.c_str()); + model->Print(); + + if (p_next == string::npos) + break; + else + p_curr = p_next + 1; + } + + return 0; +} + +//---------------------------------------------------------------------------------------------------- + +int main(int argc, char **argv) +{ + // defaults + double W = 0.; + Constants::ParticleMode pMode = Constants::mPP; + + unsigned int N = 1001; + double b_min = 0., b_max = 10.; + + string hadronicModelsString = ""; + + string outputFileName = ""; + + // process command line + for (int i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-h") == 0) + { + PrintUsage(); + return 0; + } + + if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "-model-list") == 0) + { + PrintModelList(); + return 0; + } + + if (strcmp(argv[i], "-energy") == 0) + { + if (argc-1 > i) + W = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-pp") == 0) + { + pMode = Constants::mPP; + continue; + } + + if (strcmp(argv[i], "-app") == 0) + { + pMode = Constants::mAPP; + continue; + } + + if (strcmp(argv[i], "-N") == 0) + { + if (argc-1 > i) + N = atoi(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-bmax") == 0) + { + if (argc-1 > i) + b_max = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-bmin") == 0) + { + if (argc-1 > i) + b_min = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-models") == 0) + { + if (argc-1 > i) + hadronicModelsString = argv[++i]; + continue; + } + + + if (strcmp(argv[i], "-output") == 0) + { + if (argc-1 > i) + outputFileName = argv[++i]; + continue; + } + + printf("ERROR: unrecognised parameter `%s'.\n", argv[i]); + PrintUsage(); + return 10; + } + + // test input + bool stop = false; + if (W == 0.) + { + printf("ERROR: collision energy not specified.\n"); + stop = true; + } + + if (outputFileName.empty()) + { + printf("ERROR: output not specified.\n"); + stop = true; + } + + if (N < 2) + { + printf("ERROR: N (%u) < 2\n", N); + stop = true; + } + + if (b_max <= b_min) + { + printf("ERROR: b_max (%.3E) <= b_min (%.3E)\n", b_max, b_min); + stop = true; + } + + if (stop) + { + PrintUsage(); + return 1; + } + + // print input + printf(">> ElegentBDistributionSampler > input:\n"); + printf("\tsqrt s = %E\n", W); + printf("\tparticle mode %u\n", pMode); + + printf("\tsamples = %u, b_min, = %.2E, b_max = %.2E\n", N, b_min, b_max); + + printf("\tmodels = %s\n", hadronicModelsString.c_str()); + printf("\toutput = %s\n", outputFileName.c_str()); + + // initialise constants etc. + Constants::Init(W, pMode); + cnts->Print(); + + // inialise models + vector models; + if (InitModels(hadronicModelsString, models) != 0) + return 3; + + // prepare output + TFile *outF = new TFile(outputFileName.c_str(), "recreate"); + + // a trick to save E, since of->WriteObject(&E, "cmsEnergy") doesn't work + TGraph *data = new TGraph(); + data->SetName("data"); + data->SetPoint(0, 0., W/2.); + data->Write(); + + // build the profile-function plots + for (unsigned int mi = 0; mi < models.size(); mi++) + { + model = models[mi]; + + gDirectory = outF->mkdir(model->CompileShortLabel().c_str()); + + TGraph *g_prf_re = new TGraph(); g_prf_re->SetName("prf_re"); g_prf_re->SetTitle(model->CompileFullLabel().c_str()); + TGraph *g_prf_im = new TGraph(); g_prf_im->SetName("prf_im"); g_prf_im->SetTitle(model->CompileFullLabel().c_str()); + + double db = (b_max - b_min) / (N - 1); + double b = b_min; + for (unsigned int pi = 0; pi < N; pi++, b += db) + { + TComplex prf = model->Prf(b); + g_prf_re->SetPoint(pi, b, prf.Re()); + g_prf_im->SetPoint(pi, b, prf.Im()); + } + + g_prf_re->Write(); + g_prf_im->Write(); + } + + delete outF; + return 0; +} diff --git a/IOMC/Elegent/bin/ElegentSDistributionSampler.cc b/IOMC/Elegent/bin/ElegentSDistributionSampler.cc new file mode 100644 index 00000000000..8a79cb23743 --- /dev/null +++ b/IOMC/Elegent/bin/ElegentSDistributionSampler.cc @@ -0,0 +1,255 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include +#include +#include + +#include "interface/Constants.h" +#include "interface/ModelFactory.h" + +#include "TFile.h" +#include "TGraph.h" + +using namespace Elegent; +using namespace std; + + +//---------------------------------------------------------------------------------------------------- + +void PrintUsage() +{ + printf("USAGE: ElegentSDistributionSampler [option] [option] ...\n"); + printf("OPTIONS:\n"); + printf("\t-h\t\t\tprint this help and exit\n"); + printf("\t-pp\t\t\tselect proton-proton interactions\n"); + printf("\t-app\t\t\tselect antiproton-proton interactions\n"); + printf("\t-N \t\tnumber of sampling points\n"); + printf("\t-Wmin \t\tlower bound of sqrt(s) (in GeV) for sampling\n"); + printf("\t-Wmax \t\tupper bound of sqrt(s) (in GeV) for sampling\n"); + printf("\t-models \tsemicolon-separated list of model tags\n"); + printf("\t-l, -model-list\t\tprint list of available model tags and exit\n"); + printf("\t-output \toutput file name\n"); +} + +//---------------------------------------------------------------------------------------------------- + +void PrintModelList() +{ + Constants::Init(1., Constants::mPP); + ModelFactory mf; + mf.PrintList(); +} + +//---------------------------------------------------------------------------------------------------- + +int InitModels(const string& hadronicModelsString, vector &models) +{ + + ModelFactory mf; + + size_t p_curr = 0; + while (true) + { + size_t p_next = hadronicModelsString.find(';', p_curr); + string tag = (p_next != string::npos) ? hadronicModelsString.substr(p_curr, p_next - p_curr) : hadronicModelsString.substr(p_curr); + + model = mf.MakeInstance(tag, false); + + if (model == NULL) + return 3; + + // force no presampling for model of Bourrely et al. + if (model->shortLabel.name.compare("bourrely") == 0) + { + BSWModel *bswm = (BSWModel *) model; + bswm->presampled = false; + bswm->highAccuracy = false; + } + + models.push_back(model); + + printf("\n>> model with tag `%s':\n", tag.c_str()); + + if (p_next == string::npos) + break; + else + p_curr = p_next + 1; + } + + return 0; +} + +//---------------------------------------------------------------------------------------------------- + +int main(int argc, char **argv) +{ + // defaults + Constants::ParticleMode pMode = Constants::mPP; + + unsigned int N = 1001; + double W_min = 5E0, W_max = 1E5; + + string hadronicModelsString = ""; + + string outputFileName = ""; + + // process command line + for (int i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-h") == 0) + { + PrintUsage(); + return 0; + } + + if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "-model-list") == 0) + { + PrintModelList(); + return 0; + } + + if (strcmp(argv[i], "-pp") == 0) + { + pMode = Constants::mPP; + continue; + } + + if (strcmp(argv[i], "-app") == 0) + { + pMode = Constants::mAPP; + continue; + } + + if (strcmp(argv[i], "-N") == 0) + { + if (argc-1 > i) + N = atoi(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-Wmax") == 0) + { + if (argc-1 > i) + W_max = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-Wmin") == 0) + { + if (argc-1 > i) + W_min = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-models") == 0) + { + if (argc-1 > i) + hadronicModelsString = argv[++i]; + continue; + } + + if (strcmp(argv[i], "-output") == 0) + { + if (argc-1 > i) + outputFileName = argv[++i]; + continue; + } + + printf("ERROR: unrecognised parameter `%s'.\n", argv[i]); + PrintUsage(); + return 10; + } + + // test input + bool stop = false; + if (outputFileName.empty()) + { + printf("ERROR: output not specified.\n"); + stop = true; + } + + if (N < 2) + { + printf("ERROR: N (%u) < 2\n", N); + stop = true; + } + + if (W_max <= W_min) + { + printf("ERROR: W_max (%.3E) <= W_min (%.3E)\n", W_max, W_min); + stop = true; + } + + if (stop) + { + PrintUsage(); + return 1; + } + + // print input + printf(">> ElegentSDistributionSampler > input:\n"); + printf("\tparticle mode %u\n", pMode); + + printf("\tsamples = %u, W_min, = %.2E, W_max = %.2E\n", N, W_min, W_max); + + printf("\tmodels = %s\n", hadronicModelsString.c_str()); + printf("\toutput = %s\n", outputFileName.c_str()); + + // initialise constants instance with dummy values + Constants::Init(1., pMode); + + // inialise models + vector models; + if (InitModels(hadronicModelsString, models) != 0) + return 3; + + // prepare output + TFile *outF = new TFile(outputFileName.c_str(), "recreate"); + + // build the s-distributions + for (unsigned int mi = 0; mi < models.size(); mi++) + { + model = models[mi]; + + string fullLabel = model->CompileFullLabel(); + //printf(">> %s\n", fullLabel.c_str()); + + gDirectory = outF->mkdir(model->CompileShortLabel().c_str()); + + TGraph *g_si_tot = new TGraph(); g_si_tot->SetName("si_tot"); g_si_tot->SetTitle(fullLabel.c_str()); + TGraph *g_rho = new TGraph(); g_rho->SetName("rho"); g_rho->SetTitle(fullLabel.c_str()); + TGraph *g_B0 = new TGraph(); g_B0->SetName("B0"); g_B0->SetTitle(fullLabel.c_str()); + + double f = exp( log(W_max / W_min) / (N - 1) ); + double W = W_min; + for (unsigned int pi = 0; pi < N; pi++, W *= f) + { + cnts->Configure(W, pMode); + + model->Init(); + + double ep = 1E-5; + TComplex amp0 = model->Amp(0.); + TComplex amp_ep = model->Amp(-ep); + + double si_tot = 4.*cnts->pi*cnts->sq_hbarc/cnts->p_cms/cnts->sqrt_s * amp0.Im(); + double rho = (amp0.Im() != 0.) ? amp0.Re() / amp0.Im() : 0.; + double B0 = ( log(amp0.Rho2()) - log(amp_ep.Rho2()) ) / ep; + + // fill graphs + g_si_tot->SetPoint(pi, W, si_tot); + g_rho->SetPoint(pi, W, rho); + g_B0->SetPoint(pi, W, B0); + } + + g_si_tot->Write(); + g_rho->Write(); + g_B0->Write(); + } + + delete outF; + return 0; +} diff --git a/IOMC/Elegent/bin/ElegentTDistributionSampler.cc b/IOMC/Elegent/bin/ElegentTDistributionSampler.cc new file mode 100644 index 00000000000..84d237bf1f1 --- /dev/null +++ b/IOMC/Elegent/bin/ElegentTDistributionSampler.cc @@ -0,0 +1,513 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include +#include +#include + +#include "interface/Constants.h" +#include "interface/ModelFactory.h" +#include "interface/InterpolationModel.h" +#include "interface/CoulombInterference.h" + +#include "TFile.h" +#include "TGraph.h" + +using namespace Elegent; +using namespace std; + +//---------------------------------------------------------------------------------------------------- + +struct AmplitudeGraph +{ + TGraph *re, *im; +}; + +//---------------------------------------------------------------------------------------------------- + +void PrintUsage() +{ + printf("USAGE: ElegentTDistributionSampler [option] [option] ...\n"); + printf("OPTIONS:\n"); + printf("\t-h\t\t\tprint this help and exit\n"); + printf("\t-energy \t\tset collision energy (i.e. sqrt(s)), in GeV\n"); + printf("\t-pp\t\t\tselect proton-proton interactions\n"); + printf("\t-app\t\t\tselect antiproton-proton interactions\n"); + printf("\t-models \tsemicolon-separated list of model tags\n"); + printf("\t-l, -model-list\t\tprint list of available model tags and exit\n"); + printf("\t-output \toutput file name\n"); + printf("\n"); + printf("OPTIONS for hadronic-model sampling:\n"); + printf("\t-model-N \tnumber of sampling points\n"); + printf("\t-model-tmax \tmaximum |t| value (in GeV^2)\n"); + printf("\n"); + printf("OPTIONS for `full-range' graphs (sampling with linear steps in |t|):\n"); + printf("\t-full-N \tnumber of sampling points\n"); + printf("\t-full-tmax \tmaximum |t| value (in GeV^2)\n"); + printf("\n"); + printf("OPTIONS for `low-t' graphs (sampling with linear steps in log |t|):\n"); + printf("\t-lowt-N \tnumber of sampling points\n"); + printf("\t-lowt-tmax \tmaximum |t| value (in GeV^2)\n"); +} + +//---------------------------------------------------------------------------------------------------- + +void PrintModelList() +{ + Constants::Init(1., Constants::mPP); + ModelFactory mf; + mf.PrintList(); +} + +//---------------------------------------------------------------------------------------------------- + +int InitModels(const string& hadronicModelsString, vector &models) +{ + ModelFactory mf; + + size_t p_curr = 0; + while (true) + { + size_t p_next = hadronicModelsString.find(';', p_curr); + string tag = (p_next != string::npos) ? hadronicModelsString.substr(p_curr, p_next - p_curr) : hadronicModelsString.substr(p_curr); + + model = mf.MakeInstance(tag); + + if (model == NULL) + return 3; + + models.push_back(model); + + printf("\n>> model with tag `%s':\n", tag.c_str()); + model->Print(); + + if (p_next == string::npos) + break; + else + p_curr = p_next + 1; + } + + return 0; +} + +//---------------------------------------------------------------------------------------------------- + +void SampleModels(const vector &models, double t_max, unsigned int N, vector &models_sampled) +{ + for (unsigned int mi = 0; mi < models.size(); mi++) + { + model = models[mi]; + + InterpolationModel *ms = new InterpolationModel(N, -t_max, 0.); + ms->fullLabel.name = ms->fullLabel.name + ":interpolated"; + ms->shortLabel.name = ms->shortLabel.name + ":interpolated"; + + for (unsigned int pi = 0; pi < N; pi++) + { + double t = ms->GetT(pi); + TComplex a = model->Amp(t); + ms->SetPoint(pi, a); + } + + models_sampled.push_back(ms); + } +} + +//---------------------------------------------------------------------------------------------------- + +void SampleAmplitude(bool logarithmic, unsigned int N, double t_min, double t_max, double t_min_coulomb, + AmplitudeGraph &a, bool full) +{ + double dt = (t_max - t_min) / (N - 1); + double xi = pow(t_min/t_max, 1./(N - 1)); + + a.re = new TGraph(); a.re->SetName("re"); + a.im = new TGraph(); a.im->SetName("im"); + + unsigned int idx = 0; + for (unsigned int pi = 0; pi < N; pi++) + { + double t = (logarithmic) ? t_max * pow(xi, pi) : t_max - dt * pi; + + if (!full) + { + if (fabs(t) < 1E-6) + continue; + + if (t < t_min_coulomb) + continue; + } + + TComplex v = coulomb->Amp(t); + a.re->SetPoint(idx, -t, v.Re()); + a.im->SetPoint(idx, -t, v.Im()); + idx++; + } +} + +//---------------------------------------------------------------------------------------------------- + +void BuildAmplitudes(const vector &models_sampled, + bool logarithmic, unsigned int N, double t_min, double t_max, + const vector &litudeModes, + double t_min_coulomb, + AmplitudeGraph &litude_pc, vector< map > &litudes) +{ + // PC amplitude + coulomb->mode = CoulombInterference::mPC; + SampleAmplitude(logarithmic, N, t_min, t_max, t_min_coulomb, amplitude_pc, false); + + // other amplitudes + amplitudes.clear(); + amplitudes.resize(models_sampled.size()); + for (unsigned int mi = 0; mi < models_sampled.size(); mi++) + { + model = models_sampled[mi]; + + map &as = amplitudes[mi]; + + for (unsigned int cii = 0; cii < amplitudeModes.size(); cii++) + { + coulomb->mode = amplitudeModes[cii]; + + AmplitudeGraph &a = as[amplitudeModes[cii]]; + SampleAmplitude(logarithmic, N, t_min, t_max, t_min_coulomb, a, (amplitudeModes[cii] == CoulombInterference::mPH)); + } + } +} + +//---------------------------------------------------------------------------------------------------- + +void WriteOneAmplitudeGraphs(const AmplitudeGraph &a, const string &label) +{ + a.re->SetTitle(label.c_str()); + a.re->Write("amplitude_re"); + a.im->SetTitle(label.c_str()); + a.im->Write("amplitude_im"); + + // build differential and cumulative cross-sections + TGraph *phase = new TGraph(); phase->SetName("phase"); phase->SetTitle(label.c_str()); + TGraph *rho = new TGraph(); rho->SetName("rho"); rho->SetTitle(label.c_str()); + TGraph *B = new TGraph(); B->SetName("B"); B->SetTitle(label.c_str()); + TGraph *dif = new TGraph(); dif->SetName("differential cross-section"); dif->SetTitle(label.c_str()); + TGraph *cum = new TGraph(); cum->SetName("cumulative cross-section"); cum->SetTitle(label.c_str()); + + double *at = a.re->GetX(); + double *ar = a.re->GetY(); + double *ai = a.im->GetY(); + + double S=0., prev_t=0., prev_cs=0.; + for (int i = 0; i < a.re->GetN(); i++) + { + TComplex A(ar[i], ai[i]); + double cs = cnts->sig_fac * A.Rho2(); + + dif->SetPoint(i, at[i], cs); + phase->SetPoint(i, at[i], A.Theta()); + rho->SetPoint(i, at[i], 1./tan(A.Theta())); + + if (i > 0) + B->SetPoint(i-1, (at[i] + prev_t)/2., (log(prev_cs) - log(cs)) / (at[i] - prev_t)); + + if (i > 0) + S += (cs + prev_cs) * (at[i] - prev_t) / 2.; + + cum->SetPoint(i, at[i], S); + + prev_cs = cs; + prev_t = at[i]; + } + + phase->Write(); + rho->Write(); + B->Write(); + dif->Write(); + cum->Write(); +} + +//---------------------------------------------------------------------------------------------------- + +void WriteCRZGraphs(const AmplitudeGraph &_pc, const AmplitudeGraph &_ph, + const AmplitudeGraph &_kl, const AmplitudeGraph &_swy, const string &label) +{ + TGraph *C = new TGraph(); C->SetName("C"); C->SetTitle(label.c_str()); + TGraph *R = new TGraph(); R->SetName("R"); R->SetTitle(label.c_str()); + TGraph *Z = new TGraph(); Z->SetName("Z"); Z->SetTitle(label.c_str()); + + for (int i = 0; i < amp_kl.re->GetN(); i++) + { + double t, pcR, pcI, phR, phI, klR, klI, swyR, swyI; + amp_kl.re->GetPoint(i, t, klR); + amp_kl.im->GetPoint(i, t, klI); + + pcR = amp_pc.re->Eval(t); + pcI = amp_pc.im->Eval(t); + phR = amp_ph.re->Eval(t); + phI = amp_ph.im->Eval(t); + swyR = amp_swy.re->Eval(t); + swyI = amp_swy.im->Eval(t); + + TComplex ph(phR, phI), pc(pcR, pcI), swy(swyR, swyI), kl(klR, klI); + + double vC = (kl.Rho2() - ph.Rho2()) / ph.Rho2(); + double vZ = (kl.Rho2() - ph.Rho2() - pc.Rho2()) / kl.Rho2(); + double vR = (kl.Rho2() - swy.Rho2()) / kl.Rho2(); + + Z->SetPoint(i, t, vZ); + C->SetPoint(i, t, vC); + R->SetPoint(i, t, vR); + } + + C->Write(); + R->Write(); + Z->Write(); +} + +//---------------------------------------------------------------------------------------------------- + +void WriteGraphs(const vector &models, const AmplitudeGraph &litude_pc, + const vector< map > &litudes) +{ + TDirectory *topDir = gDirectory; + + // coulomb graphs + gDirectory = topDir->mkdir("PC"); + WriteOneAmplitudeGraphs(amplitude_pc, "Coulomb"); + + for (unsigned int mi = 0; mi < amplitudes.size(); mi++) + { + string shortLabel = models[mi]->CompileShortLabel(); + string fullLabel = models[mi]->CompileFullLabel(); + + TDirectory *modelDir = topDir->mkdir(shortLabel.c_str()); + + for (map::const_iterator mit = amplitudes[mi].begin(); mit != amplitudes[mi].end(); ++mit) + { + coulomb->mode = mit->first; + gDirectory = modelDir->mkdir(coulomb->GetModeString().c_str()); + + WriteOneAmplitudeGraphs(mit->second, fullLabel); + } + + gDirectory = modelDir; + const map &m = amplitudes[mi]; + map::const_iterator it_ph = m.find(CoulombInterference::mPH); + map::const_iterator it_kl = m.find(CoulombInterference::mKL); + map::const_iterator it_swy = m.find(CoulombInterference::mSWY); + + if (it_ph == m.end() || it_kl == m.end() || it_swy == m.end()) + { + printf("ERROR: some of the PH, KL, SWY amplitudes are missing for model `%s'.\n", shortLabel.c_str()); + continue; + } + + WriteCRZGraphs(amplitude_pc, it_ph->second, it_kl->second, it_swy->second, fullLabel); + } +} + +//---------------------------------------------------------------------------------------------------- + +int main(int argc, char **argv) +{ + // defaults + double W = 0.; + Constants::ParticleMode pMode = Constants::mPP; + + unsigned int model_N = 10001, fullRange_N = 5001, lowt_N = 501; + double model_t_max = 20., fullRange_t_max = 20., lowt_t_max = 1.; + + string hadronicModelsString = ""; + + string outputFileName = ""; + + // process command line + for (int i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-h") == 0) + { + PrintUsage(); + return 0; + } + + if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "-model-list") == 0) + { + PrintModelList(); + return 0; + } + + if (strcmp(argv[i], "-energy") == 0) + { + if (argc-1 > i) + W = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-pp") == 0) + { + pMode = Constants::mPP; + continue; + } + + if (strcmp(argv[i], "-app") == 0) + { + pMode = Constants::mAPP; + continue; + } + + if (strcmp(argv[i], "-model-N") == 0) + { + if (argc-1 > i) + model_N = atoi(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-model-tmax") == 0) + { + if (argc-1 > i) + model_t_max = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-full-N") == 0) + { + if (argc-1 > i) + fullRange_N = atoi(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-full-tmax") == 0) + { + if (argc-1 > i) + fullRange_t_max = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-lowt-N") == 0) + { + if (argc-1 > i) + lowt_N = atoi(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-lowt-tmax") == 0) + { + if (argc-1 > i) + lowt_t_max = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-models") == 0) + { + if (argc-1 > i) + hadronicModelsString = argv[++i]; + continue; + } + + + if (strcmp(argv[i], "-output") == 0) + { + if (argc-1 > i) + outputFileName = argv[++i]; + continue; + } + + printf("ERROR: unrecognised parameter `%s'.\n", argv[i]); + PrintUsage(); + return 10; + } + + // test input + bool stop = false; + if (W == 0.) + { + printf("ERROR: collision energy not specified.\n"); + stop = true; + } + + if (outputFileName.empty()) + { + printf("ERROR: output not specified.\n"); + stop = true; + } + + if (stop) + { + PrintUsage(); + return 1; + } + + // print input + printf(">> ElegentTDistributionSampler > input:\n"); + printf("\tsqrt(s) = %E\n", W); + printf("\tparticle mode %u\n", pMode); + + printf("\tmodel sampling: samples = %u, t_max = %.2E\n", model_N, model_t_max); + printf("\tfull-range plots: samples = %u, t_max = %.2E\n", fullRange_N, fullRange_t_max); + printf("\tlow-|t| plots: samples = %u, t_max = %.2E\n", lowt_N, lowt_t_max); + + printf("\tmodels = %s\n", hadronicModelsString.c_str()); + printf("\toutput = %s\n", outputFileName.c_str()); + + // initialise constants etc. + Constants::Init(W, pMode); + cnts->Print(); + coulomb->Print(); + + // is model_t_max high enough + if (model_t_max < coulomb->T) + { + printf("ERROR: model_t_max = %.2E is lower than CoulombInterference::T = %.2E\n", model_t_max, coulomb->T); + return 2; + } + double t_min_coulomb = -(model_t_max - coulomb->T); + + // inialise models + vector models; + if (InitModels(hadronicModelsString, models) != 0) + return 3; + + // prepare output + TFile *outF = new TFile(outputFileName.c_str(), "recreate"); + + // a trick to save E, since of->WriteObject(&E, "cmsEnergy") doesn't work + TGraph *data = new TGraph(); + data->SetName("data"); + data->SetPoint(0, 0., W/2.); + data->Write(); + + // sample the models + vector models_sampled; + SampleModels(models, model_t_max, model_N, models_sampled); + + // select amplitudes to be generated + vector amplitudeModes; + amplitudeModes.push_back(CoulombInterference::mPH); + //amplitudeModes.push_back(CoulombInterference::mWY); + amplitudeModes.push_back(CoulombInterference::mSWY); + amplitudeModes.push_back(CoulombInterference::mKL); + + // build full-range amplitudes + AmplitudeGraph amplitude_pc_full; + vector< map > amplitudes_full; + BuildAmplitudes(models_sampled, false, fullRange_N, -fullRange_t_max, 0., amplitudeModes, + t_min_coulomb, amplitude_pc_full, amplitudes_full); + + // write full-range graphs + gDirectory = outF->mkdir("full range"); + WriteGraphs(models, amplitude_pc_full, amplitudes_full); + + // build low-|t| amplitudes + AmplitudeGraph amplitude_pc_lowt; + vector< map > amplitudes_lowt; + BuildAmplitudes(models_sampled, true, lowt_N, -lowt_t_max, -1E-5, amplitudeModes, + t_min_coulomb, amplitude_pc_lowt, amplitudes_lowt); + + // build low-|t| graphs + gDirectory = outF->mkdir("low |t|"); + WriteGraphs(models, amplitude_pc_lowt, amplitudes_lowt); + + delete outF; + return 0; +} diff --git a/IOMC/Elegent/bin/ElegentTest.cc b/IOMC/Elegent/bin/ElegentTest.cc new file mode 100644 index 00000000000..6de167e00aa --- /dev/null +++ b/IOMC/Elegent/bin/ElegentTest.cc @@ -0,0 +1,49 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include +#include + +#include "interface/Generator.h" + +#include "HepMC/GenEvent.h" + +using namespace Elegent; +using namespace std; +using namespace HepMC; + +//---------------------------------------------------------------------------------------------------- + +void PrintUsage() +{ + printf("USAGE: ElegentTest \n"); +} + +//---------------------------------------------------------------------------------------------------- + +int main(int argc, char **argv) +{ + if (argc != 6) + { + PrintUsage(); + return 1; + } + + Generator generator(argv[1], argv[2], atof(argv[3]), atof(argv[4])); + if (generator.Init() != 0) + return 2; + + unsigned int N = atoi(argv[5]); + for (unsigned int i = 0; i < N; i++) + { + GenEvent* gEv = new GenEvent(); + gEv->set_event_number(i); + generator.Generate(gEv); + gEv->print(); + delete gEv; + } + + return 0; +} diff --git a/IOMC/Elegent/data/README b/IOMC/Elegent/data/README new file mode 100644 index 00000000000..7494c652b24 --- /dev/null +++ b/IOMC/Elegent/data/README @@ -0,0 +1,9 @@ +More datasheets (t-distribution files) can be obtained at: + http://elegent.hepforge.org/ + +Naming scheme: + t-distributions,,GeV.root +particle mode can be + pp for proton-proton collisions + app for antiproton-proton collisions +energy corresponds to sqrt(s) diff --git a/IOMC/Elegent/data/t-distributions,pp,13000GeV.root b/IOMC/Elegent/data/t-distributions,pp,13000GeV.root new file mode 100644 index 00000000000..88081700757 Binary files /dev/null and b/IOMC/Elegent/data/t-distributions,pp,13000GeV.root differ diff --git a/IOMC/Elegent/data/t-distributions,pp,14000GeV.root b/IOMC/Elegent/data/t-distributions,pp,14000GeV.root new file mode 100644 index 00000000000..c43e85c8490 Binary files /dev/null and b/IOMC/Elegent/data/t-distributions,pp,14000GeV.root differ diff --git a/IOMC/Elegent/data/t-distributions,pp,2760GeV.root b/IOMC/Elegent/data/t-distributions,pp,2760GeV.root new file mode 100644 index 00000000000..b620f542f6c Binary files /dev/null and b/IOMC/Elegent/data/t-distributions,pp,2760GeV.root differ diff --git a/IOMC/Elegent/data/t-distributions,pp,7000GeV.root b/IOMC/Elegent/data/t-distributions,pp,7000GeV.root new file mode 100644 index 00000000000..578ccf89cb7 Binary files /dev/null and b/IOMC/Elegent/data/t-distributions,pp,7000GeV.root differ diff --git a/IOMC/Elegent/data/t-distributions,pp,8000GeV.root b/IOMC/Elegent/data/t-distributions,pp,8000GeV.root new file mode 100644 index 00000000000..acc920fa052 Binary files /dev/null and b/IOMC/Elegent/data/t-distributions,pp,8000GeV.root differ diff --git a/IOMC/Elegent/elegent/CHANGELOG b/IOMC/Elegent/elegent/CHANGELOG new file mode 100644 index 00000000000..6e0816f782c --- /dev/null +++ b/IOMC/Elegent/elegent/CHANGELOG @@ -0,0 +1,10 @@ +future release + * naming scheme for distributions and plots + ...,GeV... + * minor modification: JenkovszkyModel updated to match with Int. J. Mod. Phys. A26 (2011) + * BHModel: updated to match with BLOCK, M. M., Phys. Rept. 436 (2006) 71-215 + * new model labeling scheme: name:mode (variant) [version] + * added s-distribution sampler + +release 1.0 + * first fully operational version diff --git a/IOMC/Elegent/elegent/Doxyfile b/IOMC/Elegent/elegent/Doxyfile new file mode 100644 index 00000000000..2be383d1adb --- /dev/null +++ b/IOMC/Elegent/elegent/Doxyfile @@ -0,0 +1,1890 @@ +# Doxyfile 1.8.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed +# in front of the TAG it is preceding . +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "Elegent" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, +# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, +# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields or simple typedef fields will be shown +# inline in the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO (the default), structs, classes, and unions are shown on a separate +# page (for HTML and Man pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can +# be an expensive process and often the same symbol appear multiple times in +# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too +# small doxygen will become slower. If the cache is too large, memory is wasted. +# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid +# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 +# symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = NO + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = NO + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= NO + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = interface src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.h *.cc + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be ignored. +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = doxygen + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript +# pieces of code that will be used on startup of the MathJax code. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search +# engine library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4 will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images +# or other source files which should be copied to the LaTeX output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files +# that can be used to generate PDF. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. If left blank docbook will be used as the default path. + +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed +# in the related pages index. If set to NO, only the current project's +# pages will be listed. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# manageable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/IOMC/Elegent/elegent/README b/IOMC/Elegent/elegent/README new file mode 100644 index 00000000000..a0d5123863b --- /dev/null +++ b/IOMC/Elegent/elegent/README @@ -0,0 +1,75 @@ +---------------------------------------------------------------------------------------------------- +PACKGAGE CONTENTS +---------------------------------------------------------------------------------------------------- + +interface/Math.h, src/Math.cc : implementation of numerical integration routines + +interface/Constants.h, src/Constants.cc : mathematical and physics constants as well as process +description (proton-proton or proton-antiproton mode, cetre-of-mass energy) + +interface/Model.h, src/Model.cc : the base class for all hadronic models + +interface/*Model.h, src/*Model.cc : implementation of hadronic models + +interface/CoulombInterference.h, src/CoulombInterference.cc : implementation of Coulomb amplitude +and Coulomb-hadronic interference models + +interface/ModelFactory.h, src/ModelFactory.cc : class to instantiate a hadronic model class +specified by name + +interface/Generator.h, src/Generator.cc : Monte-Carlo event generator according to cumulative +distribution function + +src/ElegentTest.cc : an example application of the Generator class + +src/Elegent?DistributionSampler.cc : set of programs to sample various distributions in +four-momentum transfer squared (t), impact parameter (b) or collision energy (s) + +distributions/generate_?_distributions : scripts to generate t-, b- and s- distribution at both +collision modes (pp and app) and at various energies of interest + +plots/generate_plots, plots/code.asy : scripts to produce the plots available at the project web + +scripts/make_release : script to make a release tar ball + +test/package_test : script to test various functionalities of the package + +CHANGELOG : history of changes relevant for a user + +Doxyfile : configuration file for code documentation generation by Doxygen + +makefile : build system configuration + +README : this file + +TODO : a "to do" list + + +---------------------------------------------------------------------------------------------------- +USAGE INSTRUCTIONS +---------------------------------------------------------------------------------------------------- + +DOWNLOAD + +Either download an Elegent release (http://www.hepforge.org/downloads/elegent) or checkout the code +from Subversion: + svn co http://elegent.hepforge.org/svn/trunk + +BUILD + +Edit the `makefile' such that `ROOTDIR' and `HepMCDIR' point to your ROOT and HepMC installations. +The run + make + +ENVIRONMENT + +Depending on your system, you might want to add + * `lib' sub-directory to the `LD_LIBRARY_PATH' environment variable and + * `bin' sub-directory to `PATH' +before your run any of the programs below. + +PROGRAM EXECUTION + +All executable programs can be run with `-h' option in oder to get help. Alternatively, you can +consult the Wiki pages: + http://elegent.hepforge.org/trac/wiki diff --git a/IOMC/Elegent/elegent/TODO b/IOMC/Elegent/elegent/TODO new file mode 100644 index 00000000000..e23d07de61d --- /dev/null +++ b/IOMC/Elegent/elegent/TODO @@ -0,0 +1,41 @@ +* BH model - problem with N_g + +* BSW model - investigate first, then send email + - problem with complex logarithm + - factor in front of the regeon term + - energy dependence S0 does actually depend on t. + - signatures of reggeons? + - make sure that the integration accuracy is sufficient! + +* model problems (BH, BSW) to Wiki + +* finish Wiki + +* add `environment' hints to README + +* README + - the names and a brief description of all the files that make up the package + - clear instructions on the installation and execution of the program + +* update make_release + +* update TOTEM TWiki, cfg files (new label scheme, how to get available model list) + +* check compatibility with old curves + +* plots: grid in Asymptote + +* problem with low |t| sampling: visible in B(t) + +* web - distributions - naming scheme + + +-------------------- long term -------------------- + +* add more models (e.g. Brazilian group)? + +* Jenkovszky model: other trajectory parameterisations than Eq. (8)? + +* custom integration --> some standard library (e.g. GSL) + +* use of GNU automake system diff --git a/IOMC/Elegent/elegent/distributions/generate_b_distributions b/IOMC/Elegent/elegent/distributions/generate_b_distributions new file mode 100755 index 00000000000..65dd35da766 --- /dev/null +++ b/IOMC/Elegent/elegent/distributions/generate_b_distributions @@ -0,0 +1,38 @@ +#!/bin/bash + +function Generate() +{ + local mode="$1" + local energy="$2" + + echo ">> Generate: mode = $mode, sqrt(s) = $energy GeV" + + tag="b-distributions,${mode},${energy}GeV" + + generator="../bin/ElegentBDistributionSampler" + models="block [06];bourrely [03];islam (hp) [06,09];islam (lxg) [06,09];jenkovszky [11];petrov (2p) [02];petrov (3p) [02]" + $generator "-$mode" -energy "$energy" -output "$tag.root" -models "$models" &> "$tag.log" + + tar czf "$tag.tar.gz" "$tag.root" "$tag.log" + + #rm "$tag.root" + #rm "$tag.log" +} + +#---------------------------------------------------------------------------------------------------- + +Generate "pp" "23" & +Generate "pp" "31" & +Generate "pp" "53" & +Generate "pp" "200" & +Generate "pp" "2760" & +Generate "pp" "7000" & +Generate "pp" "8000" & +Generate "pp" "13000" & +Generate "pp" "14000" & + +Generate "app" "31" & +Generate "app" "53" & +Generate "app" "546" & +Generate "app" "630" & +Generate "app" "1800" & diff --git a/IOMC/Elegent/elegent/distributions/generate_s_distributions b/IOMC/Elegent/elegent/distributions/generate_s_distributions new file mode 100755 index 00000000000..b66d9a3a493 --- /dev/null +++ b/IOMC/Elegent/elegent/distributions/generate_s_distributions @@ -0,0 +1,24 @@ +#!/bin/bash + +function Generate() +{ + local mode="$1" + + echo ">> Generate: mode = $mode" + + tag="s-distributions,${mode}" + + generator="../bin/ElegentSDistributionSampler" + models="block [06];bourrely [03];islam (hp) [06,09];islam (lxg) [06,09];jenkovszky [11];petrov (2p) [02];petrov (3p) [02]" + $generator "-$mode" -output "$tag.root" -models "$models" &> "$tag.log" + + tar czf "$tag.tar.gz" "$tag.root" "$tag.log" + + #rm "$tag.root" + #rm "$tag.log" +} + +#---------------------------------------------------------------------------------------------------- + +Generate "pp" & +Generate "app" & diff --git a/IOMC/Elegent/elegent/distributions/generate_t_distributions b/IOMC/Elegent/elegent/distributions/generate_t_distributions new file mode 100755 index 00000000000..4296977b66d --- /dev/null +++ b/IOMC/Elegent/elegent/distributions/generate_t_distributions @@ -0,0 +1,38 @@ +#!/bin/bash + +function Generate() +{ + local mode="$1" + local energy="$2" + + echo ">> Generate: mode = $mode, sqrt(s) = $energy GeV" + + tag="t-distributions,${mode},${energy}GeV" + + generator="../bin/ElegentTDistributionSampler" + models="block [06];bourrely [03];islam (hp) [06,09];islam (lxg) [06,09];jenkovszky [11];petrov (2p) [02];petrov (3p) [02]" + $generator "-$mode" -energy "$energy" -output "$tag.root" -models "$models" &> "$tag.log" + + tar czf "$tag.tar.gz" "$tag.root" "$tag.log" + + #rm "$tag.root" + #rm "$tag.log" +} + +#---------------------------------------------------------------------------------------------------- + +Generate "pp" "23" & +Generate "pp" "31" & +Generate "pp" "53" & +Generate "pp" "200" & +Generate "pp" "2760" & +Generate "pp" "7000" & +Generate "pp" "8000" & +Generate "pp" "13000" & +Generate "pp" "14000" & + +Generate "app" "31" & +Generate "app" "53" & +Generate "app" "546" & +Generate "app" "630" & +Generate "app" "1800" & diff --git a/IOMC/Elegent/elegent/interface/BHModel.h b/IOMC/Elegent/elegent/interface/BHModel.h new file mode 100644 index 00000000000..4afd7d38234 --- /dev/null +++ b/IOMC/Elegent/elegent/interface/BHModel.h @@ -0,0 +1,72 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_bh_model_ +#define _elegent_bh_model_ + +#include "Model.h" + +namespace Elegent +{ + +/** + * \brief Block-Halzen model of p-p and p-anti p elastic scattering. + * References: + * [1] BLOCK, M. M., GREGORES, E. M., HALZEN, F. and PANCHERI, G., Phys. Rev. D60 (1999) 054024 + * [2] BLOCK, M. M., Phys. Rept. 436 (2006) 71-215 + **/ +class BHModel : public Model +{ + public: + BHModel(); + + void Configure(); + virtual void Init(); + virtual void Print() const; + virtual TComplex Amp(double t) const; + virtual TComplex Prf(double b) const; + + protected: + /// common parameters + double m0, s0, al_s, Sigma_gg; + + /// parameters for sigma_gg + double Cp_gg, epsilon, Ng; + std::vector a, b; + + /// parameters for sigma_gg + double C_qg_log; + + /// parameters for sigma_qg + double C, C_even_regge; + + /// parameters for sigma_qq + double C_odd; + + /// effective areas + double mu_gg, mu_qg, mu_qq, mu_odd; + + /// the integral cross-sections + TComplex sigma_gg, sigma_qq, sigma_qg, sigma_odd; + + /// integration parameters + double precision, upper_bound; + + /// profile defined by Eq. (B2) in [1] + double W(double b, double mi) const; + + /// sum in Eq. (B5) in [1] + TComplex Sum(double s) const; + + /// the full eikonal: Eq. (1) without the leading factor i and Eq. (12) + TComplex chi_without_i(double b) const; + + TComplex prf0(double b) const; + static TComplex prf0_J0(double *y, double *t, const void *obj); +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/interface/BSWModel.h b/IOMC/Elegent/elegent/interface/BSWModel.h new file mode 100644 index 00000000000..386f3152707 --- /dev/null +++ b/IOMC/Elegent/elegent/interface/BSWModel.h @@ -0,0 +1,128 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_bsw_model_ +#define _elegent_bsw_model_ + +#include "Model.h" + +#include + +//#define DEBUG + +namespace Elegent +{ + +/** + * \brief Bourelly, Soffer and Wu model of p-p and p-anti p elastic scattering. + * References: + * [1] BOURRELY C., SOFFER, J. and WU, T. T., Phys. Rev. D19 (1979) 3249 + * [2] BOURRELY C., SOFFER, J. and WU, T. T., Nucl. Phys. B247 (1984) 15 + * [3] BOURRELY C., SOFFER, J. and WU, T. T., Eur. Phys. J. C28 (2003) 97-105 + * [4] BOURRELY C., SOFFER, J. and WU, T. T., Eur. Phys. J. C71 (2011) 1601 + **/ +class BSWModel : public Model +{ + public: + /// a Regge trajectory + struct Trajectory + { + double C, b, a, ap, sig; + void Init(double _C, double _b, double _a, double _ap, double _sig) + { C=_C; b=_b; a=_a; ap=_ap; sig = _sig; } + }; + + /// available modes + enum ModeType + { + mPomReg, ///< both Pomeron and Reggeon contributions + mPom, ///< only Pomeron contribution + mReg ///< only Reggeon contribution + } mode; + + BSWModel(); + + ~BSWModel() {} + + /// the Pom+Reg mode still broken + void Configure(ModeType _mode = mPomReg, bool _presampled = true); + + virtual void Init(); + + virtual void Print() const; + + virtual TComplex Amp(double t) const; + virtual TComplex Prf(double b) const; + + public: + /// flag whether the presampled mode is on + bool presampled; + + /// accuracy level (use true for differential cross-section, false is sufficient for total cross-section) + bool highAccuracy; + + /// the pomeron exchange parameters + double c, cp, a, f, m1, m2, asq, m1sq, m2sq; + + /// the 3 Regge trajectories + Trajectory A2, rho, omega; + + /// temporary constants: Omega0 = S0*F + R0 / s / regge_fac; + TComplex regge_fac; + + double upper_bound_t, precision_t; + double upper_bound_b, precision_b; + + /// \tilde F(t), Eq. (4) + double Ft(double t) const; + + /// generic Regge trajectory amplitude, Eq. (7) + TComplex Rt(Trajectory tr, double t) const; + + /// the sum of allowed Regge trajctories (A2, rho, omega) + TComplex R0t(double t) const; + + /// S_0(s), Eq(3) + TComplex S0(double t) const; + + /// S_0(0) + TComplex S00; + + /// the Bessel transform of \Omega_0(s, b) in Eq. (2) + TComplex Omega0t(double t) const; + + static TComplex Omega0t_J0(double *t, double *b, const void *obj); + + /// \Omega_0(s, b) + TComplex Omega0b(double b) const; + + /// the profile function with b in GeV^-1 + TComplex prf0(double b) const; + + static TComplex prf0_J0(double *b, double *q, const void *obj); + + /// the sampling-step size + double data_db; + + /// the number of sampled points + unsigned int data_N; + + /// the sampled real and imaginary values of prf0(b) + std::vector data_re, data_im; + +#ifdef DEBUG + std::vector data_b; +#endif + + /// samples the prf0 function + void BuildSample(unsigned int samples); + + /// interpolates (linearly) the sample at point b + TComplex SampleEval(double b); +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/interface/Constants.h b/IOMC/Elegent/elegent/interface/Constants.h new file mode 100644 index 00000000000..8703f7f40a3 --- /dev/null +++ b/IOMC/Elegent/elegent/interface/Constants.h @@ -0,0 +1,66 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_constants_ +#define _elegent_constants_ + +#include "TComplex.h" + +namespace Elegent +{ + +/** + *\brief Set of constants used in Elegent calculations. + **/ +struct Constants +{ + // physics constants + static double alpha; ///< fine structure constant + static double proton_mass; ///< GeV + static double neutron_mass; ///< GeV + static double hbarc; ///< GeV * fm + static double sq_hbarc; ///< GeV^2 * mbarn + ///< sigma/mbarn = sigma/GeV^-2 * sq_hbarc + static double M; ///< abbreviation for proton mass in GeV + static double M_sq; ///< proton mass squared, GeV^2 + static double kappa; ///< the anomalous magnetic moment of proton + + // mathematics constants + static double pi; ///< pi + static double gamma; ///< Euler's constant + + // physics data + double sqrt_s; ///< sqrt_s / GeV + double s; ///< s / GeV^2 + double ln_s; ///< ln(s / GeV^2) + double p_cms; ///< particle CMS impuls + double sig_fac; ///< d sig/dt = sig_fac * |A|^2 + double t_min; ///< negative + + enum ParticleMode {mPP, mAPP} pMode; ///< particle mode + + /// \param W = sqrt(s) + Constants(double W = 0., ParticleMode mode = mPP) + { + Configure(W, mode); + } + + void Configure(double W, ParticleMode mode); + + /// \brief initilize new instance of Constants and save its pointer to the `cnts' global variable + /// \param W = sqrt(s) + static void Init(double W, ParticleMode mode); + + /// print the actual values + void Print(); +}; + + +extern TComplex i; +extern Constants *cnts; + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/interface/CoulombInterference.h b/IOMC/Elegent/elegent/interface/CoulombInterference.h new file mode 100644 index 00000000000..5ba4d2bb398 --- /dev/null +++ b/IOMC/Elegent/elegent/interface/CoulombInterference.h @@ -0,0 +1,173 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_coulomb_ +#define _elegent_coulomb_ + +#include "Model.h" + +namespace Elegent +{ + +/** + * \brief Coulomb hadron interference for elastic scattering. + **/ +class CoulombInterference +{ + public: + /// the mode of coulomb interference + enum CIMode + { + mPC, ///< pure electromagnetic amplitude (Born/OPE approximation) [default] + mPH, ///< pure hadronic amplitude + mWY, ///< WY formula + mSWY, ///< simplified WY formula + mKL ///< (corrected) KL formula (includes the one of Cahn) + } mode; + + std::string GetModeString() const; + + /// form factor type + enum FFType + { + ffNone, ///< form factor = 1 + ffDipole, ///< dipole form factor, in G_eff, G_E and G_M (G_M(0) = 1) + ffHofstadter, ///< Hofstader et al.: Rev. Mod. Phys. 30 (1958) + ffBorkowski, ///< Borkowski et al.: Nucl. Phys. B93 (1975) + ffKelly, ///< Kelly: Phys. Rev. C70 (2004) + ffArrington, ///< Arrington et al.: Phys. Rev C76 (2007) + ffPuckett, ///< Puckett et al.: arXiv 1008.0855v1 [default] + ffPuckettEl ///< only electric form-factor of Puckett et al. + } ffType; + + CoulombInterference(); + + double GetT() + { return T; } + + /// the size of the region around t=t' which is cut off from integration, see B_term method + double tau; + + /// the upper bound of the integration in A_term and B_term is |t|+T + double T; + + /// precision of the integration + double precision; + + /// print the parameters + void Print() const; + + protected: + /// the integrand of I(t, t') integral + static double I_integrand(double *phi, double *par, const void *obj); + + /// the integrand of the A term + static double A_integrand(double *tt, double *t, const void *obj); + + /// the integrand of the B term + static TComplex B_integrand(double *tt, double *par, const void *obj); + + public: + /// A: $\int_{t_{min}}^0 \log(t'/t) * d/dt(FF^2(t'))$ + /// \par t in GeV^2, negative + double A_term(double t) const; + + double I_integral(double t, double tp) const; + + /// B: ${1 / 2\pi} \int_{t_{min}}^0 [ F^N(t') / F^N(t) - 1] I(t, t')$ + /// \par t in GeV^2, negative + TComplex B_term(double t) const; + + /// C: the correction for non-vanishing form factors at t_min + /// $FF^2(t_{min} \log(t/t_{min}))$ + /// \par t in GeV^2, negative + double C_term(double t) const; + + //-------------------- form factors -------------------- + + public: + std::string GetFFName() const; + + /// dipole form factor + double FF_dipole(double t) const; + + /// eletric form factor + /// normalized such FF_e(0) = 1, t negative + double FF_e(double t) const; + + /// magnetic form factor + /// normalized such FF_m(0) = 1, t negative + double FF_m(double t) const; + + /// square of the effective form factor + /// \par t in GeV^2, negative + double FF_sq(double t) const; + + /// d/dt of the effective form factor square + /// \par t in GeV^2, negative + double FF_sq_prime(double t) const + { + double ep = 1E-5; + return (FF_sq(t + ep) - FF_sq(t)) / ep; + } + + //-------------------- interference phases -------------------- + + /// full West-Yennie phase (with alpha factor) + /// that is the $\alpha\Phi$ in the decomposition $F^{C+H} = F^C e^{i \alpha \Phi} + F^H$ + /// \par t in GeV^2, negative + TComplex Phi_WY(double t) const; + + /// simplified West-Yennie phase + TComplex Phi_SWY(double t) const; + + /// Kundrat-Lokajicek phase (with alpha factor) + /// that is the $\alpha\Phi$ in the decomposition $F^{C+H} = F^C + F^H * e^{i \alpha \Psi}$ + /// \par t in GeV^2, negative + TComplex Psi_KL(double t) const; + + ///\brief the interference phase WITH the alpha factor + /// returns either $-\Phi$ or $\Psi$ + /// \par t in GeV^2, negative + TComplex Phase(double t) const; + + //-------------------- amplitudes -------------------- + + /// pure Coulomb amplitude (PC) + /// \par t in GeV^2, negative + TComplex Amp_pure(double t) const; + + TComplex Amp_WY(double t) const; + TComplex Amp_SWY(double t) const; + TComplex Amp_KL(double t) const; + + /// total Amplitude according to the choice in `mode' + TComplex Amp(double t) const; + + //-------------------- standard quantities -------------------- + + /// ratio (|KL|^2 - |WY|^2) / |KL|^2 + /// \par t in GeV^2, negative + TComplex R(double t) const; + + /// for |t| < |cutoff|: (|KL|^2 - |WY|^2) / |KL|^2, otherwise (|KL|^2 - |PH|^2) / |KL|^2 + /// \par t in GeV^2, negative + /// \par cutoff in GeV^2, negative + TComplex R_with_cutoff(double t, double cutoff) const; + + /// ratio (|KL|^2 - |PH|^2 - |PC|^2) / |KL|^2 + /// \par t in GeV^2, negative + TComplex Z(double t) const; + + /// ratio (|KL|^2 - |PH|^2) / |PH|^2 + /// \par t in GeV^2, negative + TComplex C(double t) const; +}; + +extern CoulombInterference *coulomb; + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/interface/ExpModel.h b/IOMC/Elegent/elegent/interface/ExpModel.h new file mode 100644 index 00000000000..baaa7b6ea2b --- /dev/null +++ b/IOMC/Elegent/elegent/interface/ExpModel.h @@ -0,0 +1,36 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_exp_model_ +#define _elegent_exp_model_ + +#include "Model.h" + +namespace Elegent +{ + +/** + * \brief Exponential model of p-p and p-anti p elastic scattering. + * amplitude(t) = a * exp( b1*t + b2*t*t + i*(p0 + p1*t) ) + * For reference pourposes only. + **/ +class ExpModel : public Model +{ + public: + ExpModel(); + + void Configure(); + virtual void Init(); + virtual void Print() const; + virtual TComplex Amp(double t) const; + virtual TComplex Prf(double b) const; + + public: + double a, b1, b2, p0, p1; +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/interface/Generator.h b/IOMC/Elegent/elegent/interface/Generator.h new file mode 100644 index 00000000000..62a924c0bed --- /dev/null +++ b/IOMC/Elegent/elegent/interface/Generator.h @@ -0,0 +1,69 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_elegent_ +#define _elegent_elegent_ + +#include + +class TGraph; + +namespace HepMC { + class GenEvent; +} + +namespace Elegent +{ + +/** + * \brief MC generator of proton-proton elastic scattering events. + * All internal quantities are in GeV or in mm. + **/ +class Generator +{ + public: + Generator(const std::string &_file, const std::string &_path, double _t_min, double _t_max, unsigned int _verbosity=1); + ~Generator() {} + + unsigned int Init(); + + static const int PID = 2212; + static const int ElasticScattering = 91; + static const int FinalState = 1; + static const int NullState = 0; + + protected: + /// name of file containing the cumulative distribution function (CDF) + std::string fileName; + + /// path of the (CDF) within the file + std::string modelPath; + + /// |t| values in GeV^2, bounds for CDF + double t_min, t_max; + + /// verbosity level (0 = no, 1 = normal, 2 = debug) + unsigned int verbosity; + + /// [GeV] cms (one) proton energy + double E_cms; + + /// [GeV] cms proton momentum + double p_cms; + + /// graph with inverse c.d.f. + TGraph *icdf; + + public: + /// generates one event provided two random numbers with uniform distribution on (0, 1) + void GenerateBase(double rn1, double rn2, HepMC::GenEvent* gE); + + /// generates one event, using ROOT random number generator TRandom2 + void Generate(HepMC::GenEvent* gE); +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/interface/InterpolationModel.h b/IOMC/Elegent/elegent/interface/InterpolationModel.h new file mode 100644 index 00000000000..23372f831d4 --- /dev/null +++ b/IOMC/Elegent/elegent/interface/InterpolationModel.h @@ -0,0 +1,84 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_interpolation_model_ +#define _elegent_interpolation_model_ + +#include "Model.h" + +#include + +class TGraph; + +namespace Elegent +{ + +/** + * \brief Model that interpolates stored amplitude points. + **/ +class InterpolationModel : public Model +{ + public: + /// number of points (samples) + unsigned int N; + + /// the lower boundary + double t_min; + + /// the upper boundary + double t_max; + + /// the t interval between two adjacent (equidistant) points + double dt; + + /// amplitude samples + std::vector amp_data; + + public: + InterpolationModel(unsigned int _N, double _t_min, double _t_max); + + virtual ~InterpolationModel(); + + void Configure(); + + virtual void Init() {} + + virtual void Print() const; + + /// amplitude, t in GeV^-2, t < 0 + virtual TComplex Amp(double t) const + { + double f = (t - t_min) / dt; + unsigned int idx = (unsigned int) f; + + if (idx + 1 > N - 1) + { + if (fabs(t - t_max) < 1E-10) + return amp_data[N-1]; + return TComplex(0, 0); + } + + f -= idx; + + return amp_data[idx] + (amp_data[idx+1] - amp_data[idx]) * f; + } + + virtual TComplex Prf(double b) const; + + /// returns the value of t corresponding to the point with index `idx' (between 0 and N-1 inclusively) + inline double GetT(unsigned int idx) const + { + return t_min + dt * idx; + } + + inline void SetPoint(unsigned int idx, const TComplex &v) + { + amp_data[idx] = v; + } +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/interface/IslamModel.h b/IOMC/Elegent/elegent/interface/IslamModel.h new file mode 100644 index 00000000000..8af3f91b32f --- /dev/null +++ b/IOMC/Elegent/elegent/interface/IslamModel.h @@ -0,0 +1,121 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_islam_model_ +#define _elegent_islam_model_ + +#include "Model.h" + +namespace Elegent +{ + + +/** + * \brief Islam model of p-p and p-anti p elastic scattering. + * References: + * [1] ISLAM, M. M., FEARNLEY, T. and GUILLAUD, J. P., Nuovo Cim. A81 (1984) 737 + * [2] ISLAM, M. M., INNOCENTE V., FEARNLEY T. and SANGUIETTI, G., Europhys. Lett. 4 (1987) 189-196 + * [3] ISLAM, M. M., LUDDY, R. J. and PROKUDIN, A. V., Phys. Lett. B605 (2005) 115-122 + * [4] ISLAM, M. M., LUDDY, R. J. and PROKUDIN, A. V., Int. J. Mod. Phys. A21 (2006) 1-42 + * [5] ISLAM, M. M., KASPAR, J. and LUDDY, R. J., Mod. Phys. Lett. A24 (2009) 485-496 + **/ +class IslamModel : public Model +{ + public: + /// variant of the model + enum VariantType + { + vHP, ///< hard Pomeron + vLxG ///< low-x gluons + } variant; + + /// mode of the model + enum ModeType + { + mDiff, ///< diffraction amplitude + mCore, ///< core amplitude + mQuark, ///< quark-quark amplitude + mDiffCore, ///< diffraction and core amplitude + mFull ///< diffraction, core and quark-quark amplitude + } mode; + + IslamModel(); + + void Configure(VariantType _v, ModeType _m); + + virtual void Init(); + + static TComplex CEF(double a, double b, double c); + + void SetUnitarizationOrders(int qq, int cgc) + { + qqMaxOrder = qq; + cgcMaxOrder = cgc; + } + + virtual void Print() const; + + virtual TComplex Amp(double t) const; + virtual TComplex Prf(double b) const; + + protected: + /// diffraction variables + TComplex R, a, Diff_fac_profile, Diff_fac; + + /// hard scattering variables + TComplex Abs_fac; + + /// core scattering variables + double beta, m_omega_sq, Core_fac; + + /// quark confinement parameters + double m0sq; + + /// "hard pomeron" scattering variables + double r0, omega; + TComplex Quark_fac; + TComplex Quark_const; + int qqMaxOrder; + + /// "low-x gluons" scattering + double lambda, m_c; + TComplex cgc_fac; + int cgcMaxOrder; + + /// integration variables + double precision, precision_t, upper_bound, upper_bound_t; + + /// diffraction amplitude + TComplex T_diff(double t) const; + TComplex GammaD(double b) const; + static TComplex GammaD_J0(double *b, double *t, const void *obj); + + /// core amplitude + TComplex T_core(double t) const; + double F_sq(double t) const; + + /// quark-quark amplitude + TComplex T_quark(double t) const; + double I_integral(double qt, double al) const; + static double F_cal_integ(double *x, double *qt, const void *obj); + double F_cal(int n, double qt, double om, double m0sq) const; + + /// quark-quark amplitude: hard-pomeron variant + static double T_hp_integ(double *, double *, const void *); + TComplex T_hp_n(int n, double t) const; + TComplex T_hp(double t) const; + + /// quark-quark amplitude: low-x gluons variant + static double T_lxg_integ(double *, double *, const void *); + TComplex T_lxg_n(int n, double t) const; + TComplex T_lxg(double t) const; + + /// profile funcion methods + static TComplex Amp_J0(double *t, double *b, const void *obj); +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/interface/JenkovszkyModel.h b/IOMC/Elegent/elegent/interface/JenkovszkyModel.h new file mode 100644 index 00000000000..3e022d13ae5 --- /dev/null +++ b/IOMC/Elegent/elegent/interface/JenkovszkyModel.h @@ -0,0 +1,53 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_jenkovszky_model_ +#define _elegent_jenkovszky_model_ + +#include "Model.h" + +namespace Elegent +{ + +/** + * \brief The model of Jenkovszky et al. + * References: + * [1] L. L. JENKOVSZKY, A. I. LENGYEL, and D. I. LONTKOVSKYI, Int. J. Mod. Phys. A 26 (2011) 4755. DOI: 10.1142/S0217751X11054760 + **/ +class JenkovszkyModel : public Model +{ + public: + JenkovszkyModel(); + + void Configure(); + virtual void Init(); + + virtual void Print() const; + + virtual TComplex Amp(double t) const; + virtual TComplex Prf(double b) const; + + protected: + /// pomeron parameters + double a_P, b_P, de_P, al1_P, ep_P, s_P; + + /// odderon parameters + double a_O, b_O, de_O, al1_O, s_O; + + /// omega parameters + double a_om, b_om, s_om, al0_om, al1_om; + + /// f parameters + double a_f, b_f, s_f, al0_f, al1_f; + + /// integration parameters for profile-funcion calculation + double precision_t, upper_bound_t; + + static TComplex Amp_J0(double *t, double *b, const void *obj); +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/interface/Math.h b/IOMC/Elegent/elegent/interface/Math.h new file mode 100644 index 00000000000..805e52b9996 --- /dev/null +++ b/IOMC/Elegent/elegent/interface/Math.h @@ -0,0 +1,40 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_math_ +#define _elegent_math_ + +#include + +namespace Elegent +{ + +// ================================== INTEGRATION ROUTINES ================================================= + +/** + *\brief Integrates real-valued function `fcn' between points `a' and `b'. + * `obj' is passed as the third parameter to `fcn' + * `params' is passed as the second parameter to `fcn' + * the integration variable is the first element of the array in the first parameter of `fcn' + * `epsilon' controls the precision of the integration + * + * The function has been adapted from ROOT's TF1::Integral. + **/ +double DoubleInt(const void *obj, double (*fcn)(double*, double*, const void*), double a, double b, double *params = NULL, double epsilon = 1E-9); + +/** + *\brief Integrates complex-valued function `fcn' between points `a' and `b'. + * `obj' is passed as the third parameter to `fcn' + * `params' is passed as the second parameter to `fcn' + * the integration variable is the first element of the array in the first parameter of `fcn' + * `epsilon' controls the precision of the integration + * + * The function has been adapted from ROOT's TF1::Integral. + **/ +TComplex CmplxInt(const void *obj, TComplex (*fcn)(double*, double*, const void *), double a, double b, double *params = NULL, double epsilon = 1E-9); + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/interface/Model.h b/IOMC/Elegent/elegent/interface/Model.h new file mode 100644 index 00000000000..beafdcd433b --- /dev/null +++ b/IOMC/Elegent/elegent/interface/Model.h @@ -0,0 +1,68 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_model_ +#define _elegent_model_ + +#include "TComplex.h" + +#include + +namespace Elegent +{ + +/** + * \brief The base class for hadronic models of (anti)proton-proton elastic scattering. + **/ +class Model +{ + public: + /// collection of strings that describe model instance + struct Label + { + std::string name, variant, version, mode; + }; + + /// full label (e.g. for figure legend) + Label fullLabel; + + /// short label (e.g. for object names in ROOT files) + Label shortLabel; + + /// compiles a human readable string from fullLabel + std::string CompileFullLabel() const; + + /// compiles a human readable string from shortLabel + std::string CompileShortLabel() const; + + Model() {} + + virtual ~Model() {} + + /// TODO + virtual void Init() =0; + + /// prints model info + virtual void Print() const =0; + + ///\brief amplitude, t in GeV^-2, t < 0 + /// Normalisation is such that + /// dsigma/dt = (\hbar c)^2 * \pi / (s p^2) * |Amp(t)|^2 + /// Differential cross-section can be obtained as + /// Constants::sig_fac * |Amp(t)|^2 + virtual TComplex Amp(double t) const =0; + + ///\brief profile function, b in fm + /// Normalisation is such that + /// Amp(t) = 2 p \sqrt{s} \int db b Prf() J_0(b \sqrt{-t}) + virtual TComplex Prf(double b) const =0; +}; + +/// current model +extern Model *model; + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/interface/ModelFactory.h b/IOMC/Elegent/elegent/interface/ModelFactory.h new file mode 100644 index 00000000000..dc8d6fd185f --- /dev/null +++ b/IOMC/Elegent/elegent/interface/ModelFactory.h @@ -0,0 +1,42 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_modelfactory_ +#define _elegent_modelfactory_ + +#include "IslamModel.h" +#include "PPPModel.h" +#include "BSWModel.h" +#include "BHModel.h" +#include "JenkovszkyModel.h" +#include "ExpModel.h" + +#include +#include + +namespace Elegent +{ + +/** + * \brief A class to give list of available models and to create an instance of a model specified by tag. + **/ +class ModelFactory +{ + protected: + /// map: tag --> model instance + std::map model_map; + + public: + ModelFactory(); + + void PrintList() const; + + Model* MakeInstance(const std::string &tag, bool callInit = true) const; +}; + + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/interface/PPPModel.h b/IOMC/Elegent/elegent/interface/PPPModel.h new file mode 100644 index 00000000000..4dd84cecbc3 --- /dev/null +++ b/IOMC/Elegent/elegent/interface/PPPModel.h @@ -0,0 +1,62 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_ppp_model_ +#define _elegent_ppp_model_ + +#include "Model.h" + +namespace Elegent +{ + +/** + * \brief Predazzi, Petrov and Prokudin model of p-p and p-anti p elastic scattering. + * References: + * [1] PETROV, V. A. and PROKUDIN, A. V., Eur. Phys. J. C23 (2002) 135–143 + **/ +class PPPModel : public Model +{ + public: + struct Trajectory + { + double D, c, ap, r2, rho2; + TComplex gamma; + }; + + /// available variant + enum VariantType + { + v2P, ///< with 2 Pomerons + v3P ///< with 3 Pomerons + } variant; + + PPPModel(); + + void Configure(VariantType v); + + virtual void Init(); + + virtual void Print() const; + + virtual TComplex Amp(double t) const; + virtual TComplex Prf(double b) const; ///< b in fm + + protected: + Trajectory pom1, pom2, pom3, oder, regf, rego; + double s0; + double precision, upper_bound; + + static void SetTrajectory(Trajectory &t, double D, double c, double ap, double r2, double s0); + + TComplex tr_eik(Trajectory, double s, double t) const; + + + virtual TComplex prf0(double b) const; ///< b in GeV^-1 + static TComplex prf_J0(double *b, double *t, const void *obj); +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/elegent/makefile b/IOMC/Elegent/elegent/makefile new file mode 100644 index 00000000000..d027898ee11 --- /dev/null +++ b/IOMC/Elegent/elegent/makefile @@ -0,0 +1,99 @@ +# PATHS TO BE ADJUSTED BY USER + +# path to ROOT installation +#ROOTDIR = /usr/local/root5 +ROOTDIR = /afs/cern.ch/cms/slc5_amd64_gcc434/lcg/root/5.27.06b-cms18 + +# path to HepMC installation +#HepMCDIR = /usr +HepMCDIR = /afs/cern.ch/cms/slc5_amd64_gcc434/external/hepmc/2.05.01-cms2 + +#---------------------------------------------------------------------------------------------------- +#---------------------------------------------------------------------------------------------------- + +INCS = `$(ROOTDIR)/bin/root-config --cflags` -I. +LIBS = `$(ROOTDIR)/bin/root-config --libs` + +INCS += -I$(HepMCDIR)/include +LIBS += -L$(HepMCDIR)/lib -lHepMC + +#---------------------------------------------------------------------------------------------------- + +GCC = g++ -Wall -O3 -fPIC +ROOTCINT = rootcint + +# modules for which dictionary shall be generated +dict_modules = Model IslamModel PPPModel BSWModel BHModel JenkovszkyModel ExpModel InterpolationModel CoulombInterference Constants + +# modules with no dictionaries +modules = Math Generator ModelFactory + +# executable files +exe_files = ElegentTest ElegentTDistributionSampler ElegentBDistributionSampler ElegentSDistributionSampler + +#---------------------------------------------------------------------------------------------------- + +# directories to create +dirsToCreate = obj lib bin #dict + +dict_modules_obj = $(addprefix obj/, $(addsuffix .o, $(dict_modules))) +dict_modules_dict_src = $(addprefix dict/, $(addsuffix _dict.cc, $(dict_modules))) +dict_modules_dict_obj = $(addprefix dict/, $(addsuffix _dict.o, $(dict_modules))) + +modules_obj = $(addprefix obj/, $(addsuffix .o, $(modules))) + +exe_files_bin = $(addprefix bin/, $(exe_files)) + +#---------------------------------------------------------------------------------------------------- + +.PHONY: all dirs dicts libs exe info clean + +all: libs exe + +libs: dirs dicts lib/libElegent.so + +exe: dirs libs $(exe_files_bin) + +dirs: $(dirsToCreate) + +$(dirsToCreate): + mkdir -p $@ + +#dicts: $(dict_modules_dict_obj) + +$(dict_modules_dict_obj) : dict/%_dict.o : dict/%_dict.cc + $(GCC) $(INCS) -c $< -o $@ + +$(modules_dict_src) : dict/%_dict.cc : interface/%.h + rm -f $@ + rm -f $(@:%.cc=%.h) + $(ROOTCINT) $@ -c $<+ + +lib/libElegent.so: $(dict_modules_obj) $(modules_obj) + @echo MAKING libElegent.so + @$(GCC) -shared -olib/libElegent.so obj/*.o #dict/*.o + +%.o : ../src/%.cc ../interface/%.h + @echo COMPILING $< + @$(GCC) $(INCS) -c $< -o $@ + +bin/% : src/%.cc lib/libElegent.so + @echo BUILDING $@ + $(GCC) $(INCS) $(LIBS) -Llib -lElegent $< -o $@ + +info: + echo $(dirsToCreate) + @echo + echo $(modules) + @echo + echo $(modules_obj) + @echo + echo $(modules_dict_src) + @echo + echo $(modules_dict_obj) + +clean: + rm -rf obj + rm -rf lib + #rm -rf dict + rm -rf bin diff --git a/IOMC/Elegent/elegent/plots/code.asy b/IOMC/Elegent/elegent/plots/code.asy new file mode 100644 index 00000000000..d5c34ee4ded --- /dev/null +++ b/IOMC/Elegent/elegent/plots/code.asy @@ -0,0 +1,419 @@ +import root; +import pad_layout; + +//---------------------------------------------------------------------------------------------------- + +xSizeDef = 10cm; +ySizeDef = 8cm; + +//---------------------------------------------------------------------------------------------------- + +string model_tags[]; +pen model_pens[]; + +void AddModel(string tag, pen p) +{ + model_tags.push(tag); + model_pens.push(p); +} + + +AddModel("block [06]", heavygreen); +AddModel("bourrely [03]", blue); +AddModel("islam (hp) [06,09]", black); +AddModel("islam (lxg) [06,09]", black+dashed); +AddModel("jenkovszky [11]", magenta); +AddModel("petrov (2p) [02]", red+dashed); +AddModel("petrov (3p) [02]", red); + +//---------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------- + +string html_file = ""; +string dist_dir = ""; + +file f_out; + +//---------------------------------------------------------------------------------------------------- + +void StartJob(string hf, string dd) +{ + html_file = hf; + dist_dir = dd; + f_out = output(hf); + + write(f_out, "", endl); + write(f_out, " ", endl); + write(f_out, " ", endl); + write(f_out, " ", endl); + write(f_out, "", endl); +} + +//---------------------------------------------------------------------------------------------------- + +void EndJob() +{ + write(f_out, "", endl); + write(f_out, "", endl); +} + +//---------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------- + +void DrawOptimized(real jump_tol, rObject obj, pen p, string label = "") +{ + int N = obj.iExec("GetN"); + guide g; + + real prev_y = 0; + bool firstPoint = true; + for (int i = 0; i < N; ++i) + { + real[] xa = {0}; + real[] ya = {0}; + obj.vExec("GetPoint", i, xa, ya); + + real x = xa[0]; + real y = ya[0]; + + if ((currentpicture.scale.x.scale.logarithmic && x <= 0)) + continue; + + if (x > TGraph_highLimit) + break; + + real de_y = y - prev_y; + + if (firstPoint || abs(de_y) < jump_tol) + { + g = g--Scale((x, y)); + } else { + draw(g, p, label); + label = ""; // not to multiply labels in legend + g = Scale((x, y)); + } + + firstPoint = false; + prev_y = y; + } + + draw(g, p, label); +} + +//---------------------------------------------------------------------------------------------------- + +frame legend_frame; + +void PlotAllModels(string input_file, string template, string legend_title, + bool optimize=false, real opt_jump=0) +{ + for (int mi : model_tags.keys) + { + string obj_path = replace(template, "", model_tags[mi]); + rObject obj = rGetObj(input_file, obj_path, search=false, error=false); + if (!obj.valid) + continue; + + string label = obj.sExec("GetTitle"); + + if (optimize) + DrawOptimized(opt_jump, obj, model_pens[mi], label); + else + draw(obj, "l", model_pens[mi], label); + } + + legend_frame = BuildLegend(legend_title); +} + +//---------------------------------------------------------------------------------------------------- + +void FinalizeFile(string name) +{ + // add grid + for (int pi : pad_collection.keys) + { + SetPad(pad_collection[pi]); + + currentpad.xTicks = NoTicks(); + xaxis(BottomTop, LeftTicks(format="%", extend=true, pTick=black+dotted, ptick=invisible)); + xaxis(Label(currentpad.xLabel, 1), BottomTop, LeftTicks()); + currentpad.xLabel = ""; + + currentpad.yTicks = NoTicks(); + yaxis(LeftRight, RightTicks(format="%", extend=true, pTick=black+dotted, ptick=invisible)); + yaxis(Label(currentpad.yLabel, 1), LeftRight, RightTicks()); + currentpad.yLabel = ""; + } + + NewPad(false); + add(legend_frame); + GShipout(name); +} +//---------------------------------------------------------------------------------------------------- + +typedef void PlotFcn(string dist_file, string option); + +struct PlotDesc +{ + PlotFcn plotFcn; + string fileName, htmlLabel; + bool doubleScale; +}; + +//---------------------------------------------------------------------------------------------------- + +PlotDesc plots[]; + +void RegisterPlot(string fn, string hl, bool doubleScale, PlotFcn pf) +{ + PlotDesc pd; + pd.plotFcn = pf; + pd.fileName = fn; + pd.htmlLabel = hl; + pd.doubleScale = doubleScale; + + plots.push(pd); +} + +//---------------------------------------------------------------------------------------------------- + +void ProcessOnePlot(int pi, string mode, string energies[], string tag, string file_suffix, string obj_prefix, int html_flag) +{ + write(f_out, " ", endl); + + if (html_flag == 1) + write(f_out, " "+plots[pi].htmlLabel+"", endl); + if (html_flag == 2) + write(f_out, " "+plots[pi].htmlLabel+"", endl); + + for (int ei : energies.keys) + { + string dist_file = dist_dir + "/" + tag + "," + mode + "," + energies[ei] + "GeV.root"; + + string out_file = mode+","+energies[ei]+"GeV/"+tag+","+plots[pi].fileName; + if (file_suffix != "") + out_file += "," + file_suffix; + + write(">> " + out_file); + + plots[pi].plotFcn(dist_file, obj_prefix); + FinalizeFile(out_file); + + string link_name = obj_prefix; + if (link_name == "") + link_name = "full range"; + + write(f_out, " "+link_name+"", endl); + } + + write(f_out, " ", endl); +} + +//---------------------------------------------------------------------------------------------------- + +void ProcessPlots(string mode, string energies[], string tag) +{ + string html_mode = mode; + if (html_mode == "app") + html_mode = "p̅p"; + write(f_out, "

"+html_mode+"

", endl); + + write(f_out, "", endl); + write(f_out, " ", endl); + write(f_out, " ", endl); + write(f_out, " ", endl); + + write(f_out, " ", endl); + write(f_out, " ", endl); + for (int ei : energies.keys) + { + write(f_out, " ", endl); + } + write(f_out, " ", endl); + + for (int pi : plots.keys) + { + if (plots[pi].doubleScale) + { + TGraph_highLimit = 10; + ProcessOnePlot(pi, mode, energies, tag, "full_range", "full range", 2); + TGraph_highLimit = +inf; + ProcessOnePlot(pi, mode, energies, tag, "low_t", "low |t|", 0); + } else { + ProcessOnePlot(pi, mode, energies, tag, "", "", 1); + } + } + + write(f_out, "
√s (GeV2)
"+energies[ei]+"
", endl); +} + +//---------------------------------------------------------------------------------------------------- + +void ProcessOneSPlot(int pi, string mode, string tag) +{ + write(f_out, " ", endl); + write(f_out, " "+plots[pi].htmlLabel+"", endl); + + string dist_file = dist_dir + "/" + tag + "," + mode + ".root"; + string out_file = mode+","+tag+","+plots[pi].fileName; + + write(">> " + out_file); + + plots[pi].plotFcn(dist_file, ""); + FinalizeFile(out_file); + + write(f_out, "
full range", endl); + + write(f_out, " ", endl); +} + +//---------------------------------------------------------------------------------------------------- + +void ProcessSPlots(string mode, string tag) +{ + string html_mode = mode; + if (html_mode == "app") + html_mode = "p̅p"; + write(f_out, "

"+html_mode+"

", endl); + + write(f_out, "", endl); + for (int pi : plots.keys) + { + ProcessOneSPlot(pi, mode, tag); + } + + write(f_out, "
", endl); +} + +//---------------------------------------------------------------------------------------------------- + +void MakeTPlots(string mode, string energies[]) +{ + plots.delete(); + + RegisterPlot("amp", "hadronic amplitude", doubleScale=true, new void (string input_file, string option) { + NewPad("$|t|\ung{GeV^2}$", "$\Re F^{\rm H}$"); + scale((option == "low |t|") ? Log : Linear, Linear(true)); + PlotAllModels(input_file, option+"//PH/amplitude_re", "hadronic amplitudes"); + + NewPad("$|t|\ung{GeV^2}$", "$\Im F^{\rm H}$"); + scale((option == "low |t|") ? Log : Linear, Linear(true)); + PlotAllModels(input_file, option+"//PH/amplitude_im", "hadronic amplitudes"); + }); + + RegisterPlot("diff_cs", "hadronic differential cross-section", doubleScale=true, new void (string input_file, string option) { + NewPad("$|t|\ung{GeV^2}$", "$\d\si / \d t \ung{mb/GeV^2}$"); + scale((option == "low |t|") ? Log : Linear, Log(true)); + PlotAllModels(input_file, "full range//PH/differential cross-section", "hadronic differential cross-section"); + }); + + RegisterPlot("B", "hadronic slope", doubleScale=true, new void (string input_file, string option) { + NewPad("$|t|\ung{GeV^2}$", "$B(t) \equiv {\d\over \d t} \log{\d\si\over\d t} \ung{GeV^{-2}}$"); + scale((option == "low |t|") ? Log : Linear, Linear(true)); + PlotAllModels(input_file, "full range//PH/B", "hadronic slope"); + }); + + RegisterPlot("phase", "hadronic phase", doubleScale=true, new void (string input_file, string option) { + NewPad("$|t|\ung{GeV^2}$", "$\arg F^{\rm H}(t)$"); + scale((option == "low |t|") ? Log : Linear, Linear); + PlotAllModels(input_file, "full range//PH/phase", "hadronic phase", true, 1); + ylimits(-3.141593, +3.141593, Crop); + }); + + RegisterPlot("rho", "hadronic rho", doubleScale=true, new void (string input_file, string option) { + NewPad("$|t|\ung{GeV^2}$", "$\rh(t) \equiv {\Re F^{\rm H}\over \Im F^{\rm H}}$"); + scale((option == "low |t|") ? Log : Linear, Linear(true)); + PlotAllModels(input_file, "full range//PH/rho", "rho parameter", true, 8); + ylimits(-10, 10, Crop); + }); + + RegisterPlot("C", "influence of Coulomb interaction", doubleScale=true, new void (string input_file, string option) { + NewPad("$|t|\ung{GeV^2}$", "$C(t) \equiv {|F^{\rm C+H}|^2 - |F^{\rm H}|^2 \over |F^{\rm H}|^2}$"); + scale((option == "low |t|") ? Log : Linear, Linear(true)); + PlotAllModels(input_file, "full range//C", "influence of Coulomb interaction"); + //ylimits(-10, 10, Crop); + }); + + RegisterPlot("Z", "importance of the interference term", doubleScale=true, new void (string input_file, string option) { + NewPad("$|t|\ung{GeV^2}$", "$Z(t) \equiv {|F^{\rm C+H}|^2 - |F^{\rm H}|^2 - |F^{\rm C}|^2 \over |F^{\rm C+H}|^2}$"); + scale((option == "low |t|") ? Log : Linear, Linear(true)); + PlotAllModels(input_file, "full range//Z", "importance of the interference term"); + //ylimits(-10, 10, Crop); + }); + + RegisterPlot("R", "difference between SWY and KL formulae", doubleScale=true, new void (string input_file, string option) { + NewPad("$|t|\ung{GeV^2}$", "$R(t) \equiv {|F^{\rm KL}|^2 - |F^{\rm WY}|^2 \over |F^{\rm KL}|^2}$"); + scale((option == "low |t|") ? Log : Linear, Linear(true)); + PlotAllModels(input_file, "full range//R", "difference between SWY and KL formulae"); + //ylimits(-10, 10, Crop); + }); + + ProcessPlots(mode, energies, "t-distributions"); +} + +//---------------------------------------------------------------------------------------------------- + +void MakeBPlots(string mode, string energies[]) +{ + plots.delete(); + + RegisterPlot("amp", "hadronic amplitude", doubleScale=false, new void (string input_file, string option) { + NewPad("$b\ung{fm}$", "$\Re A^{\rm H}$"); + scale(Linear, Linear(true)); + PlotAllModels(input_file, "/prf_re", "hadronic amplitudes"); + + NewPad("$b\ung{fm}$", "$\Im A^{\rm H}$"); + scale(Linear, Linear(true)); + PlotAllModels(input_file, "/prf_im", "hadronic amplitudes"); + }); + + ProcessPlots(mode, energies, "b-distributions"); +} + +//---------------------------------------------------------------------------------------------------- + +void MakeSPlots(string mode) +{ + + plots.delete(); + + RegisterPlot("si_tot", "hadronic total cross-section", doubleScale=true, new void (string input_file, string option) { + NewPad("$\sqrt s\ung{GeV}$", "$\si_{\rm tot}(s)\ung{mb}$"); + scale(Log, Linear(true)); + PlotAllModels(input_file, "/si_tot", "hadronic total cross-section"); + }); + + RegisterPlot("rho", "hadronic forward rho", doubleScale=true, new void (string input_file, string option) { + NewPad("$\sqrt s\ung{GeV}$", "$\rh(s, t = 0) \equiv \left. {\Re F^{\rm H}\over \Im F^{\rm H}} \right|_{t = 0}$"); + scale(Log, Linear(true)); + PlotAllModels(input_file, "/rho", "hadronic forward rho"); + }); + + RegisterPlot("B0", "hadronic forward slope", doubleScale=true, new void (string input_file, string option) { + NewPad("$\sqrt s\ung{GeV}$", "$B(s, t=0) \equiv \left . {\d \log |F^{\rm H}|^2\over\d t} \right|_{t = 0}\ung{GeV^{-2}}$"); + scale(Log, Linear(true)); + PlotAllModels(input_file, "/B0", "hadronic forward slope"); + }); + + ProcessSPlots(mode, "s-distributions"); +} + +//---------------------------------------------------------------------------------------------------- + +void MakePlots(string pp_energies_str, string app_energies_str) +{ + string pp_energies_a[] = split(pp_energies_str, " "); + string app_energies_a[] = split(app_energies_str, " "); + + write(f_out, "

t-distributions

", endl); + MakeTPlots("pp", pp_energies_a); + MakeTPlots("app", app_energies_a); + + write(f_out, "

b-distributions

", endl); + MakeBPlots("pp", pp_energies_a); + MakeBPlots("app", app_energies_a); + + write(f_out, "

s-distributions

", endl); + MakeSPlots("pp"); + MakeSPlots("app"); +} diff --git a/IOMC/Elegent/elegent/plots/generate_plots b/IOMC/Elegent/elegent/plots/generate_plots new file mode 100755 index 00000000000..e9810a7559a --- /dev/null +++ b/IOMC/Elegent/elegent/plots/generate_plots @@ -0,0 +1,31 @@ +#!/bin/bash + +html_file="index.html" +distribution_dir="../distributions" + +pp_energies="23 31 53 200 2760 7000 8000 13000 14000" +app_energies="31 53 546 630 1800" + +# make subdirectories +for E in $pp_energies +do + mkdir -p "pp,${E}GeV" +done + +for E in $app_energies +do + mkdir -p "app,${E}GeV" +done + +# prepare and run Asymptote job +( + echo "import code;" + echo "StartJob(\"$html_file\", \"$distribution_dir\");" + echo "MakePlots(\"$pp_energies\", \"$app_energies\");" + echo "EndJob();" +) > "job.asy" + +asy -globalwrite "job.asy" + +# clean up +rm "job.asy" diff --git a/IOMC/Elegent/elegent/scripts/make_release b/IOMC/Elegent/elegent/scripts/make_release new file mode 100755 index 00000000000..8d0079e1270 --- /dev/null +++ b/IOMC/Elegent/elegent/scripts/make_release @@ -0,0 +1,29 @@ +#!/bin/bash + +if [ "$1" = "" ] +then + echo "Please specify release number" + exit 1 +fi + +tarFile="elegent-$1.tar.gz" + +prefix="../" +if [ -d "interface" ] +then + prefix="./" +fi + +tar czf "$tarFile" \ + "$prefix/interface" \ + "$prefix/distributions/generate_t_distributions" \ + "$prefix/distributions/generate_b_distributions" \ + "$prefix/distributions/generate_s_distributions" \ + "$prefix/plots/code.asy" \ + "$prefix/plots/generate_plots" \ + "$prefix/src" \ + "$prefix/CHANGELOG" \ + "$prefix/Doxyfile" \ + "$prefix/README" \ + "$prefix/TODO" \ + "$prefix/makefile" \ diff --git a/IOMC/Elegent/elegent/src/BHModel.cc b/IOMC/Elegent/elegent/src/BHModel.cc new file mode 100644 index 00000000000..2035ecfb3b4 --- /dev/null +++ b/IOMC/Elegent/elegent/src/BHModel.cc @@ -0,0 +1,222 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/BHModel.h" +#include "interface/Math.h" +#include "interface/Constants.h" + +using namespace Elegent; + +//---------------------------------------------------------------------------------------------------- + +BHModel::BHModel() +{ + fullLabel.name = "Block et al."; shortLabel.name = "block"; +} + +//---------------------------------------------------------------------------------------------------- + +void BHModel::Configure() +{ + // set labels + fullLabel.variant = ""; shortLabel.variant = ""; + fullLabel.version = "Phys. Rept. 436 (2006) 71-215"; shortLabel.version = "06"; + fullLabel.mode = ""; shortLabel.mode = ""; +} + +//---------------------------------------------------------------------------------------------------- + +void BHModel::Init() +{ + // parameters from [2]: Table 5, N_g from above Eq. (463), a's and b's from A.1.2 + + // common parameters + m0 = 0.6; + s0 = 9.53; + al_s = 0.5; + Sigma_gg = 9. * cnts->pi * al_s*al_s / m0/m0; + + // sigma_gg + Cp_gg = 0.00103; + epsilon = 0.05; + + // TODO: which is correct? + // [1] : Ng = (6.-epsilon)*(5.-epsilon)*(4.-epsilon)*(3.-epsilon)*(2.-epsilon)*(1.-epsilon) /5./4./3./2. / 2.; // = 2.649 + // [2] : Ng = 3./2. * (5.-epsilon)*(4.-epsilon)*(3.-epsilon)*(2.-epsilon)*(1.-epsilon) /5./4./3./2.; // = 1.335 + // Value from [2] seems wrong + Ng = (6.-epsilon)*(5.-epsilon)*(4.-epsilon)*(3.-epsilon)*(2.-epsilon)*(1.-epsilon) /5./4./3./2. / 2.; + + a.push_back(-41.1); + a.push_back(-487.5); + a.push_back(-600.); + a.push_back(600.); + a.push_back(487.5); + a.push_back(41.1); + + b.push_back(-9.); + b.push_back(-225.); + b.push_back(-900.); + b.push_back(-900.); + b.push_back(-225.); + b.push_back(-9.); + + // sigma_qg + C_qg_log = 0.166; + + // sigma_qq + C = 5.36; + C_even_regge = 29.7; + + // sigma_odd + C_odd = 10.3; + + // mu's + mu_gg = 0.73; + mu_odd = 0.53; + mu_qq = 0.89; + + // integration settings + upper_bound = 50.; + precision = 1E-12; + + // precompute mu_qg + mu_qg = sqrt(mu_qq*mu_gg); + + // precompute sigma_gg, Eq. (B5) in [1]: below the Cp_gg stands for C'_gg + sigma_gg = Cp_gg * Sigma_gg * Ng*Ng * Sum(cnts->s); + + // precompute sigma_qq, Eq. (B9) in [1] + sigma_qq = Sigma_gg * (C + C_even_regge * m0/sqrt(cnts->s) * TComplex::Exp(i * cnts->pi / 4.)); + + // precompute sigma_qg, Eq. (B10) in [1] + sigma_qg = Sigma_gg * C_qg_log * TComplex(log(cnts->s/s0), -cnts->pi/2.); + + // precompute sigma_odd, Eq. (B12) in [1] - the factor in front of W(b, mu_odd) + // plus additional factor (-i) to match the normalization used in chi_without_i + sigma_odd = -i * C_odd * Sigma_gg * m0 / cnts->sqrt_s * TComplex::Exp(i * cnts->pi / 4.); +} + +//---------------------------------------------------------------------------------------------------- + +void BHModel::Print() const +{ + printf(">> BHModel::Print\n"); + printf("\t%s\n", CompileFullLabel().c_str()); + + printf("\tcommon:\n"); + printf("\t\ts0 = %E\n", s0); + printf("\t\tm0 = %E\n", m0); + printf("\t\tSigma_gg = %E\n", Sigma_gg); + + printf("\tsigma_gg:\n"); + printf("\t\tCp_gg = %E\n", Cp_gg); + printf("\t\tNg = %E\n", Ng); + printf("\t\tepsilon = %E\n", epsilon); + printf("\t\ta0 = %E, a1 = %E, a2 = %E, a3 = %E, a4 = %E, a5 = %E\n", a[0], a[1], a[2], a[3], a[4], a[5]); + printf("\t\tb0 = %E, b1 = %E, b2 = %E, b3 = %E, b4 = %E, b5 = %E\n", b[0], b[1], b[2], b[3], b[4], b[5]); + printf("\t\tsigma_gg: Re = %E, Im = %E\n", sigma_gg.Re(), sigma_gg.Im()); + + printf("\tsigma_qg:\n"); + printf("\t\tC_qg_log = %E\n", C_qg_log); + printf("\t\tsigma_qg: Re = %E, Im = %E\n", sigma_qg.Re(), sigma_qg.Im()); + + printf("\tsigma_qq:\n"); + printf("\t\tC = %E\n", C); + printf("\t\tC_even_regge = %E\n", C_even_regge); + printf("\t\tsigma_qq: Re = %E, Im = %E\n", sigma_qq.Re(), sigma_qq.Im()); + + printf("\tsigma_odd:\n"); + printf("\t\tC_odd = %E\n", C_odd); + printf("\t\tsigma_odd: Re = %E, Im = %E\n", sigma_odd.Re(), sigma_odd.Im()); + + printf("\tmu's:\n"); + printf("\t\tmu_gg = %E\n", mu_gg); + printf("\t\tmu_qq = %E\n", mu_qq); + printf("\t\tmu_qg = %E\n", mu_qg); + printf("\t\tmu_odd = %E\n", mu_odd); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BHModel::Sum(double s) const +{ + TComplex log_tau0 = log(m0*m0 / s) + i * cnts->pi / 2.; + + TComplex S = 0.; + + for (unsigned int ii = 0; ii <= 5; ii++) + { + double i = double(ii); + double ime = i - epsilon; + double f = b[ii] / ime; + double t1 = (a[i] - f) / ime; + TComplex v = t1 - TComplex::Exp(ime * log_tau0) * (t1 + f * log_tau0); + S += v; + } + + return S; +} + +//---------------------------------------------------------------------------------------------------- +double BHModel::W(double b, double mu) const +{ + // Eq. (B2) in [1] + double mub = mu * b; + + // evaluates v = (mu b)^3 K_3(mu b); directly or in continuous limit + double v = 0.; + if (mub < 1E-10) + v = 8.; + else + v = mub*mub*mub * TMath::BesselK(3, mub); + return mu*mu * v / 96. / cnts->pi; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BHModel::chi_without_i(double b) const +{ + // TODO: why the one half? + + // Eqs. (B1) without the leading i factor and Eq. (B12) in [1] + double odd_sign = (cnts->pMode == cnts->mAPP) ? +1. : -1.; + return ( + sigma_gg * W(b, mu_gg) + + sigma_qg * W(b, mu_qg) + + sigma_qq * W(b, mu_qq) + + odd_sign * sigma_odd * W(b, mu_odd) + ) / 2.; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BHModel::prf0(double b) const +{ + return (1. - TComplex::Exp(-chi_without_i(b))); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BHModel::Prf(double b) const +{ + return prf0(b / cnts->hbarc) * i / 2.; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BHModel::prf0_J0(double *b, double *q, const void *obj) +{ + return b[0] * TMath::BesselJ0(b[0]*q[0]) * ((BHModel *)obj)->prf0(b[0]); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BHModel::Amp(double t) const +{ + double q = sqrt(-t); + + // from Eqs. (A11) and (A12) + return i * cnts->p_cms * cnts->sqrt_s * CmplxInt(this, prf0_J0, 0., upper_bound, &q, precision); +} diff --git a/IOMC/Elegent/elegent/src/BSWModel.cc b/IOMC/Elegent/elegent/src/BSWModel.cc new file mode 100644 index 00000000000..a212a0c32ff --- /dev/null +++ b/IOMC/Elegent/elegent/src/BSWModel.cc @@ -0,0 +1,270 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/BSWModel.h" +#include "interface/Constants.h" +#include "interface/Math.h" + +using namespace std; +using namespace Elegent; + +//---------------------------------------------------------------------------------------------------- + +BSWModel::BSWModel() +{ + fullLabel.name = "Bourrely et al."; shortLabel.name = "bourrely"; + + highAccuracy = true; +} + +//---------------------------------------------------------------------------------------------------- + +void BSWModel::Configure(BSWModel::ModeType _mode, bool _presampled) +{ + mode = _mode; + presampled = _presampled; + + // set labels + fullLabel.variant = ""; shortLabel.variant = ""; + fullLabel.version = "Eur. Phys. J. C28 (2003) 97-105"; shortLabel.version = "03"; + if (mode == mPomReg) + { fullLabel.mode = "full"; shortLabel.mode = "full"; } + if (mode == mPom) + { fullLabel.mode = "Pomeron"; shortLabel.mode = "pom"; } + if (mode == mReg) + { fullLabel.mode = "Reggeon"; shortLabel.mode = "reg"; } +} + +//---------------------------------------------------------------------------------------------------- + +void BSWModel::Init() +{ + // Eq. (6) in [3] + c = 0.167; + cp = 0.748; + + // Table 1 in [3] + m1 = 0.577; m1sq = m1*m1; // 0.333 + m2 = 1.719; m2sq = m2*m2; // 2.955 + f = 6.971; + a = 1.858; asq = a*a; // 3.452 + + // Table 2 in [3], b's given in text of section 3 in [3] + A2.Init( -24.269, 0., 0.357, 1., +1); + omega.Init( -167.329, 0., 0.323, 0.795, -1); + rho.Init( 124.919, 8.54, 0.320, 1., -1); + + if (highAccuracy) + { + upper_bound_t = -500.; precision_t = 1E-15; + upper_bound_b = 50.; precision_b = 1E-12; + } else { + upper_bound_t = -200.; precision_t = 1E-5; + upper_bound_b = 30.; precision_b = 1E-5; + } + + regge_fac(1., 0.); + + // save value of S0(0) + S00 = S0(0.); + if (presampled) + BuildSample(25001); +} + +//---------------------------------------------------------------------------------------------------- + +void BSWModel::Print() const +{ + printf(">> BSWModel::Print\n"); + printf("\t%s\n", CompileFullLabel().c_str()); + printf("\tmode = %u\n", mode); + printf("\tc=%.3f, c'=%.3f, m1=%.3f, m2=%.3f, f=%.3f, a=%.3f\n", c, cp, m1, m2, f, a); + printf("\tA2 : C=%.3f, b=%.3f, alpha=%.3f, aplha'=%.3f\n", A2.C, A2.b, A2.a, A2.ap); + printf("\tomega: C=%.3f, b=%.3f, alpha=%.3f, aplha'=%.3f\n", omega.C, omega.b, omega.a, omega.ap); + printf("\trho : C=%.3f, b=%.3f, alpha=%.3f, aplha'=%.3f\n", rho.C, rho.b, rho.a, rho.ap); + + printf("\n"); + + printf("\tpresampled = %u\n", presampled); + if (presampled) + printf("\t\tsample size = %u, db = %.1E\n", data_N, data_db); + + printf("\n"); + + printf("\tintegration parameters:\n"); + printf("\t\tt: upper bound = %.1E, precision = %.1E\n", upper_bound_t, precision_t); + printf("\t\tb: upper bound = %.1E, precision = %.1E\n", upper_bound_b, precision_b); +} + +//---------------------------------------------------------------------------------------------------- + +double BSWModel::Ft(double t) const +{ + double G = 1. / (1. - t/m1sq) / (1. - t/m2sq); + return f*G*G* (asq + t) / (asq - t); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::Rt(Trajectory tr, double t) const +{ + /// s0 = 1 GeV^2 + + double alpha = tr.a + tr.ap * t; + return tr.C * exp(tr.b * t + cnts->ln_s * alpha) * (1. + tr.sig * TComplex::Exp(-i*cnts->pi*alpha)); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::R0t(double t) const +{ + return Rt(A2, t) + Rt(omega, t) + Rt(rho, t); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::S0(double t) const +{ + // the s term + TComplex term_s = pow(cnts->s, c) / pow(cnts->ln_s, cp); + + // the u term + double u = 4.*cnts->proton_mass*cnts->proton_mass - cnts->s - t; + TComplex Lnu = TComplex(log(fabs(u)), -cnts->pi); // ambiguity in the article: which sign in +-pi? + double Lnu_rho2 = Lnu.Rho2(); + double Lnu_theta = atan2(Lnu.Im(), Lnu.Re()); // atan2 results in (-pi, +pi) + TComplex LnLnu = TComplex(0.5*log(Lnu_rho2), Lnu_theta); + TComplex term_u = TComplex::Exp(c * Lnu) / TComplex::Exp(cp * LnLnu); + +#ifdef DEBUG + printf(">> BSWModel::S0\n"); + printf("\ts=%E, u=%E\n", cnts->s, u); + printf("\tLn u=%E +i%E\n", Lnu.Re(), Lnu.Im()); + printf("\tLn Ln u=%E +i%E\n", LnLnu.Re(), LnLnu.Im()); + printf("\tterm_s: %E + i%E\n", term_s.Re(), term_s.Im()); + printf("\tterm_u: %E + i%E\n", term_u.Re(), term_u.Im()); +#endif + + return term_s + term_u; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::Omega0t(double t) const +{ + // S00 = S0(0) instead of S0(t) is used here, valid for high s only !! + + switch (mode) { + case mPomReg: + return S00*Ft(t) + R0t(t) / cnts->s / regge_fac; + case mPom: + return S00*Ft(t); + case mReg: + return R0t(t); + } + + return TComplex(0, 0); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::Omega0t_J0(double *t, double *b, const void *obj) +{ + return ((BSWModel *)obj)->Omega0t(t[0]) * TMath::BesselJ0(b[0] * sqrt(-t[0])); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::Omega0b(double b) const +{ + // the 1/2 factor is consequence of dt integration (instead of q dq) + return 0.5 * CmplxInt(this, Omega0t_J0, upper_bound_t, 0., &b, precision_t); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::prf0(double b) const +{ + return 1. - TComplex::Exp( - Omega0b(b) ); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::Prf(double b) const +{ + return prf0(b / cnts->hbarc) * i / 2.; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::prf0_J0(double *b, double *q, const void *obj) +{ + BSWModel *m = (BSWModel *) obj; + + if (m->presampled) + return m->SampleEval(b[0]) * b[0] * TMath::BesselJ0(b[0] * q[0]); + else + return m->prf0(b[0]) * b[0] * TMath::BesselJ0(b[0] * q[0]); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::Amp(double t) const +{ + double q = sqrt(-t); + + return i * cnts->p_cms * cnts->sqrt_s * CmplxInt(this, prf0_J0, 0., upper_bound_b, &q, precision_b); +} + +//---------------------------------------------------------------------------------------------------- + +void BSWModel::BuildSample(unsigned int samples) +{ + printf(">> BSWModel::BuildSample > Building %u samples...\n", samples); + + data_re.clear(); + data_re.reserve(samples); + data_im.clear(); + data_im.reserve(samples); +#ifdef DEBUG + data_b.clear(); + data_b.reserve(samples); +#endif + + double db = upper_bound_b / (samples - 1); + data_db = db; + data_N = samples; + + double b = 0.; + for (unsigned int i = 0; i < samples; i++, b += db) + { + TComplex v = prf0(b); + +#ifdef DEBUG + //printf("v=%.5f: re=%E, im=%E\n", b, v.Re(), v.Im()); + data_b.push_back(b); +#endif + + data_re.push_back(v.Re()); + data_im.push_back(v.Im()); + } +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::SampleEval(double b) +{ + unsigned int idx = (int)(b / data_db); + + if (idx + 1 > data_N - 1) + return TComplex(0, 0); + + double f = b/data_db - idx; + + return TComplex( + (data_re[idx+1] - data_re[idx])*f + data_re[idx], + (data_im[idx+1] - data_im[idx])*f + data_im[idx] + ); +} diff --git a/IOMC/Elegent/elegent/src/Constants.cc b/IOMC/Elegent/elegent/src/Constants.cc new file mode 100644 index 00000000000..cc36b24e131 --- /dev/null +++ b/IOMC/Elegent/elegent/src/Constants.cc @@ -0,0 +1,74 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/Constants.h" + +namespace Elegent +{ + +//---------------------------------------------------------------------------------------------------- + +TComplex i(0, 1); +Constants *cnts = NULL; + +// physics constants +double Constants::alpha = 7.297E-3; +double Constants::proton_mass = 0.938271; +double Constants::neutron_mass = 0.939565; +double Constants::hbarc = 0.197326; +double Constants::sq_hbarc = 0.389379; +double Constants::M = proton_mass; +double Constants::M_sq= proton_mass * proton_mass; +double Constants::kappa = 1.793; + +// mathematical constants +double Constants::pi = M_PI; +double Constants::gamma = 0.577215; + +//---------------------------------------------------------------------------------------------------- + +void Constants::Configure(double W, Constants::ParticleMode mode) +{ + sqrt_s = W; + s = sqrt_s*sqrt_s; + ln_s = log(s); + p_cms = sqrt(s /4. - proton_mass * proton_mass); + sig_fac = sq_hbarc * pi / (s * p_cms * p_cms); + t_min = 4.*proton_mass * proton_mass - s; + + pMode = mode; +} + +//---------------------------------------------------------------------------------------------------- + +void Constants::Init(double W, Constants::ParticleMode mode) +{ + cnts = new Constants(W, mode); +} + +//---------------------------------------------------------------------------------------------------- + +void Constants::Print() +{ + printf(">> Constants::Print\n"); + printf(" alpha = %E\n", alpha); + printf(" proton_mass = %E\n", proton_mass); + printf(" neutron_mass = %E\n", neutron_mass); + printf(" hbarc = %E\n", hbarc); + printf(" sq_hbarc = %E\n", sq_hbarc); + printf(" M = %E\n", M); + printf(" M_sq = %E\n", M_sq); + printf(" pi = %E\n", pi); + printf(" gamma = %E\n", gamma); + printf(" sqrt_s = %E\n", sqrt_s); + printf(" s = %E\n", s); + printf(" ln_s = %E\n", ln_s); + printf(" p_cms = %E\n", p_cms); + printf(" sig_fac = %E\n", sig_fac); + printf(" t_min = %E\n", t_min); + printf(" pMode = %s\n", (pMode == mPP) ? "pp" : "app"); +} + +} // namespace diff --git a/IOMC/Elegent/elegent/src/CoulombInterference.cc b/IOMC/Elegent/elegent/src/CoulombInterference.cc new file mode 100644 index 00000000000..189dfc3fe0d --- /dev/null +++ b/IOMC/Elegent/elegent/src/CoulombInterference.cc @@ -0,0 +1,456 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/CoulombInterference.h" +#include "interface/Math.h" +#include "interface/Constants.h" + +using namespace std; +using namespace Elegent; + +namespace Elegent +{ + +//---------------------------------------------------------------------------------------------------- + +// a global instance +CoulombInterference *coulomb = new CoulombInterference(); + +//---------------------------------------------------------------------------------------------------- + +CoulombInterference::CoulombInterference() : mode(mPC), ffType(ffPuckett), + tau(1E-10), T(10.), precision(1E-4) +{ +} + +//---------------------------------------------------------------------------------------------------- + +void CoulombInterference::Print() const +{ + printf(">> CoulombInterference::print\n"); + printf("\tmode: %s\n", GetModeString().c_str()); + printf("\tform factor: %s\n", GetFFName().c_str()); + printf("\tT = %E\n", T); + printf("\ttau = %E\n", tau); + printf("\tprecision = %E\n", precision); +} + +//---------------------------------------------------------------------------------------------------- + +string CoulombInterference::GetModeString() const +{ + switch (mode) + { + case mPC: return "PC"; + case mPH: return "PH"; + case mWY: return "WY"; + case mSWY: return "SWY"; + case mKL: return "KL"; + default: return "unknown"; + } +} + +//--------------------------------------- FORM FACTORS --------------------------------------------- + +double di_la_sq = 0.71; + +double bor_E_msq[] = {0.13745, 0.58485, 1.7164, 6.0042}; +double bor_E_c[] = {0.0301, 0.8018, -1.0882, 0.2642}; + +double bor_M_msq[] = {0.339, 0.583, 1.711, 13.793}; +double bor_M_c[] = {0.269, 0.346, -0.672, 0.069}; + +double kel_E_a[] = {1., -0.24}; +double kel_E_b[] = {1., 10.98, 12.82, 21.97}; + +double kel_M_a[] = {1., 0.12}; +double kel_M_b[] = {1., 10.97, 18.86, 6.55}; + +double arr_E_a[] = {1., 3.439, -1.602, 0.068}; +double arr_E_b[] = {1., 15.055, 48.061, 99.304, 0.012, 8.650}; + +double arr_M_a[] = {1., -1.465, 1.260, 0.262}; +double arr_M_b[] = {1., 9.627, 0.000, 0.000, 11.179, 13.245}; + +double puc_E_a[] = {1., -0.299}; +double puc_E_b[] = {1., 11.11, 14.11, 15.7}; + +double puc_M_a[] = {1., 0.081}; +double puc_M_b[] = {1., 11.15, 18.45, 5.31}; + +double pol(double p[], unsigned int N, double tau) +{ + double s = 0.; + double f = 1.; + for (unsigned int i = 0; i < N; i++, f *= tau) { + s += p[i] * f; + } + + return s; +} + +//---------------------------------------------------------------------------------------------------- + +double CoulombInterference::FF_dipole(double t) const +{ + double f = (di_la_sq / (di_la_sq - t)); + return f*f; +} + +//---------------------------------------------------------------------------------------------------- + +double CoulombInterference::FF_e(double t) const +{ + /// t is negative + + double tau = -t/4./cnts->M_sq; + + switch (ffType) + { + case ffNone: + return 1.; + + case ffDipole: + return FF_dipole(t); + + case ffHofstadter: + return FF_dipole(t) * (1. - tau*cnts->kappa); + + case ffBorkowski: + return bor_E_c[0] / (bor_E_msq[0] - t) + + bor_E_c[1] / (bor_E_msq[1] - t) + + bor_E_c[2] / (bor_E_msq[2] - t) + + bor_E_c[3] / (bor_E_msq[3] - t); + + case ffKelly: + return pol(kel_E_a, 2, tau) / pol(kel_E_b, 4, tau); + + case ffArrington: + return pol(arr_E_a, 4, tau) / pol(arr_E_b, 6, tau); + + case ffPuckett: + return pol(puc_E_a, 2, tau) / pol(puc_E_b, 4, tau); + + case ffPuckettEl: + return pol(puc_E_a, 2, tau) / pol(puc_E_b, 4, tau); + + default: + return 0.; + } +} + +//---------------------------------------------------------------------------------------------------- + +double CoulombInterference::FF_m(double t) const +{ + /// t is negative + + double tau = -t/4./cnts->M_sq; + + switch (ffType) + { + case ffNone: + return 1.; + + case ffDipole: + return FF_dipole(t); + + case ffHofstadter: + return FF_dipole(t) * (1. + cnts->kappa); + + case ffBorkowski: + return (1. + cnts->kappa) * + (bor_M_c[0] / (bor_M_msq[0] - t) + + bor_M_c[1] / (bor_M_msq[1] - t) + + bor_M_c[2] / (bor_M_msq[2] - t) + + bor_M_c[3] / (bor_M_msq[3] - t)); + + case ffKelly: + return (1. + cnts->kappa) * pol(kel_M_a, 2, tau) / pol(kel_M_b, 4, tau); + + case ffArrington: + return (1. + cnts->kappa) * pol(arr_M_a, 4, tau) / pol(arr_M_b, 6, tau); + + case ffPuckett: + return (1. + cnts->kappa) * pol(puc_M_a, 2, tau) / pol(puc_M_b, 4, tau); + + case ffPuckettEl: + return 0.; + + default: + return 0.; + } +} + +//---------------------------------------------------------------------------------------------------- + +double CoulombInterference::FF_sq(double t) const +{ + double eff = FF_e(t); + + if (ffType == ffPuckettEl) + return eff*eff; + + double mff = FF_m(t); + double tau = -t/4./cnts->M_sq; + + return (eff*eff + tau*mff*mff) / (1. + tau); +} + +//---------------------------------------------------------------------------------------------------- + +string CoulombInterference::GetFFName() const +{ + switch (ffType) + { + case ffNone: return "none"; + case ffDipole: return "dipole"; + case ffHofstadter: return "Hofstadter"; + case ffBorkowski: return "Borkowski"; + case ffKelly: return "Kelly"; + case ffArrington: return "Arrington"; + case ffPuckett: return "Puckett"; + case ffPuckettEl: return "Puckett electric only"; + default: return "unknown"; + } +} + +//------------------------------------- COULOMB AMPLITUDE ------------------------------------------ + +TComplex CoulombInterference::Amp_pure(double t) const +{ + switch (cnts->pMode) + { + case Constants::mPP: + return + cnts->alpha * cnts->s * FF_sq(t) / t; + case Constants::mAPP: + return - cnts->alpha * cnts->s * FF_sq(t) / t; + default: + return 0.; + } +} + +//-------------------------------------------------------------------------------------------------- + +double CoulombInterference::A_integrand(double *tt, double *t, const void *obj) +{ + /// tt[0] ... t' + /// t[0] ... t + return log(tt[0] / t[0]) * ((CoulombInterference *)obj)->FF_sq_prime(tt[0]); +} + +//-------------------------------------------------------------------------------------------------- + +double CoulombInterference::A_term(double t) const +{ + //return DoubleInt(this, A_integrand, cnts->t_min, 0., &t); + return DoubleInt(this, A_integrand, t-T, 0., &t); +} + +//-------------------------------------------------------------------------------------------------- + +double CoulombInterference::I_integrand(double *phi, double *par, const void *obj) +{ + /// par[0] ... t' + /// par[1] ... t + + // t2 ... t'' + double t2 = par[0] + par[1] + 2. * sqrt(par[0] * par[1]) * cos(phi[0]); + return ((CoulombInterference *)obj)->FF_sq(t2) / t2; +} + +//-------------------------------------------------------------------------------------------------- + +double CoulombInterference::I_integral(double t, double tp) const +{ + double par[] = {tp, t}; + return DoubleInt(this, I_integrand, 0., 2.*cnts->pi, par); +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::B_integrand(double *tt, double *par, const void *obj) +{ + /// tt[0] ... t' + /// par[0] ... t + /// par[1] ... Re T_H(t) + /// par[2] ... IM T_H(t) + + TComplex T_hadron_t(par[1], par[2]); + double ppar[] = { tt[0], par[0] }; + + TComplex a = model->Amp(tt[0]) / T_hadron_t; + + const double &I = DoubleInt(obj, I_integrand, 0., 2.*cnts->pi, ppar); + + return (a - 1.) * I / 2. / cnts->pi; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::B_term(double t) const +{ + double par[3]; + par[0] = t; // t + TComplex amp_t = model->Amp(t); // T_H(t) + par[1] = amp_t.Re(); // RE T_H(t) + par[2] = amp_t.Im(); // IM T_H(t) + + /** + Function B_integrand(t', t) has problems at point t' = t. It is not defined there (left and right limits are different), + it is not continuous at the point. To avoid problems, we cut out a small interval (t-tau, t+tau), tau > 0 from the + the integration region (t_min, 0). The second note concerns exponential fall off of B_integrand as one goes with t' away + from t. Thus one can take (t-T, 0) instead of (t_min, 0). Of course, T must be suffciently large. + + In fact, one must be careful with lower bound t+tau, since it must be less than 0. Otherwise contribution from the + region (t+tau, 0) isn't present. + **/ + + TComplex ret = CmplxInt(this, B_integrand, t - T, t - tau, par, precision); + if (t+tau < 0.) + ret += CmplxInt(this, B_integrand, t + tau, 0., par, precision); + + return ret; +} + +//-------------------------------------------------------------------------------------------------- + +double CoulombInterference::C_term(double t) const +{ + return FF_sq(t-T) * log(t/(t-T)); + //return FF_sq(cnts->t_min) * log(t/cnts->t_min); +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Phi_WY(double t) const +{ + TComplex corr = (cnts->pMode == cnts->mPP) ? -cnts->alpha : +cnts->alpha; + corr *= + B_term(t) + C_term(t); + return corr; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Phi_SWY(double t) const +{ + // step for discrete derivative + double zero = -1E-7; + double ep = -1E-5; + + // diffractive slope (at t=0) + double B = log(model->Amp(zero+ep).Rho2() / model->Amp(zero).Rho2()) / ep; + + double phi = cnts->gamma + log(- B * t / 2.); + if (cnts->pMode == cnts->mPP) + phi = -phi; + + return cnts->alpha * phi; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Psi_KL(double t) const +{ + TComplex corr = (cnts->pMode == cnts->mPP) ? -cnts->alpha : +cnts->alpha; + corr *= A_term(t) - B_term(t) - C_term(t); + return corr; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Phase(double t) const +{ + switch (mode) + { + case mPC: return 0.; + case mPH: return 0.; + case mWY: return -Phi_WY(t); + case mSWY: return -Phi_SWY(t); + case mKL: return Psi_KL(t); + default: return 0.; + }; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Amp_WY(double t) const +{ + return Amp_pure(t) * TComplex::Exp(i*Phi_WY(t)) + model->Amp(t); +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Amp_SWY(double t) const +{ + return Amp_pure(t) * TComplex::Exp(i*Phi_SWY(t)) + model->Amp(t); +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Amp_KL(double t) const +{ + return Amp_pure(t) + model->Amp(t) * TComplex::Exp(i*Psi_KL(t)); +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Amp(double t) const +{ + switch (mode) + { + case mPC: + return Amp_pure(t); + case mPH: + return model->Amp(t); + case mWY: + return Amp_WY(t); + case mSWY: + return Amp_SWY(t); + case mKL: + return Amp_KL(t); + default: + return 0.; + }; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::R(double t) const +{ + double KL = Amp_KL(t).Rho2(); + double SWY = Amp_SWY(t).Rho2(); + return (KL - SWY) / KL; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::R_with_cutoff(double t, double cutoff) const +{ + double KL = Amp_KL(t).Rho2(); + double ref = (t > cutoff) ? Amp_WY(t).Rho2() : model->Amp(t).Rho2() ; + return (KL - ref) / KL; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Z(double t) const +{ + double KL = Amp_KL(t).Rho2(); + double PH = model->Amp(t).Rho2(); + double PC = Amp_pure(t).Rho2(); + return (KL - PH - PC) / KL; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::C(double t) const +{ + double KL = Amp_KL(t).Rho2(); + double PH = model->Amp(t).Rho2(); + return (KL - PH) / PH; +} + +} // namespace diff --git a/IOMC/Elegent/elegent/src/ElegentBDistributionSampler.cc b/IOMC/Elegent/elegent/src/ElegentBDistributionSampler.cc new file mode 100644 index 00000000000..30198804b61 --- /dev/null +++ b/IOMC/Elegent/elegent/src/ElegentBDistributionSampler.cc @@ -0,0 +1,253 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include +#include +#include + +#include "interface/Constants.h" +#include "interface/ModelFactory.h" + +#include "TFile.h" +#include "TGraph.h" + +using namespace Elegent; +using namespace std; + + +//---------------------------------------------------------------------------------------------------- + +void PrintUsage() +{ + printf("USAGE: ElegentBDistributionSampler [option] [option] ...\n"); + printf("OPTIONS:\n"); + printf("\t-h\t\t\tprint this help and exit\n"); + printf("\t-energy \t\tset collision energy (i.e. sqrt(s)), in GeV\n"); + printf("\t-pp\t\t\tselect proton-proton interactions\n"); + printf("\t-app\t\t\tselect antiproton-proton interactions\n"); + printf("\t-N \t\tnumber of sampling points\n"); + printf("\t-bmin \t\tlower bound of b (in fm) for sampling\n"); + printf("\t-bmax \t\tupper bound of b (in fm) for sampling\n"); + printf("\t-models \tsemicolon-separated list of model tags\n"); + printf("\t-l, -model-list\t\tprint list of available model tags and exit\n"); + printf("\t-output \toutput file name\n"); +} + +//---------------------------------------------------------------------------------------------------- + +void PrintModelList() +{ + Constants::Init(1., Constants::mPP); + ModelFactory mf; + mf.PrintList(); +} + +//---------------------------------------------------------------------------------------------------- + +int InitModels(const string& hadronicModelsString, vector &models) +{ + ModelFactory mf; + + size_t p_curr = 0; + while (true) + { + size_t p_next = hadronicModelsString.find(';', p_curr); + string tag = (p_next != string::npos) ? hadronicModelsString.substr(p_curr, p_next - p_curr) : hadronicModelsString.substr(p_curr); + + model = mf.MakeInstance(tag); + + if (model == NULL) + return 3; + + models.push_back(model); + + printf("\n>> model with tag `%s':\n", tag.c_str()); + model->Print(); + + if (p_next == string::npos) + break; + else + p_curr = p_next + 1; + } + + return 0; +} + +//---------------------------------------------------------------------------------------------------- + +int main(int argc, char **argv) +{ + // defaults + double W = 0.; + Constants::ParticleMode pMode = Constants::mPP; + + unsigned int N = 1001; + double b_min = 0., b_max = 10.; + + string hadronicModelsString = ""; + + string outputFileName = ""; + + // process command line + for (int i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-h") == 0) + { + PrintUsage(); + return 0; + } + + if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "-model-list") == 0) + { + PrintModelList(); + return 0; + } + + if (strcmp(argv[i], "-energy") == 0) + { + if (argc-1 > i) + W = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-pp") == 0) + { + pMode = Constants::mPP; + continue; + } + + if (strcmp(argv[i], "-app") == 0) + { + pMode = Constants::mAPP; + continue; + } + + if (strcmp(argv[i], "-N") == 0) + { + if (argc-1 > i) + N = atoi(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-bmax") == 0) + { + if (argc-1 > i) + b_max = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-bmin") == 0) + { + if (argc-1 > i) + b_min = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-models") == 0) + { + if (argc-1 > i) + hadronicModelsString = argv[++i]; + continue; + } + + + if (strcmp(argv[i], "-output") == 0) + { + if (argc-1 > i) + outputFileName = argv[++i]; + continue; + } + + printf("ERROR: unrecognised parameter `%s'.\n", argv[i]); + PrintUsage(); + return 10; + } + + // test input + bool stop = false; + if (W == 0.) + { + printf("ERROR: collision energy not specified.\n"); + stop = true; + } + + if (outputFileName.empty()) + { + printf("ERROR: output not specified.\n"); + stop = true; + } + + if (N < 2) + { + printf("ERROR: N (%u) < 2\n", N); + stop = true; + } + + if (b_max <= b_min) + { + printf("ERROR: b_max (%.3E) <= b_min (%.3E)\n", b_max, b_min); + stop = true; + } + + if (stop) + { + PrintUsage(); + return 1; + } + + // print input + printf(">> ElegentBDistributionSampler > input:\n"); + printf("\tsqrt s = %E\n", W); + printf("\tparticle mode %u\n", pMode); + + printf("\tsamples = %u, b_min, = %.2E, b_max = %.2E\n", N, b_min, b_max); + + printf("\tmodels = %s\n", hadronicModelsString.c_str()); + printf("\toutput = %s\n", outputFileName.c_str()); + + // initialise constants etc. + Constants::Init(W, pMode); + cnts->Print(); + + // inialise models + vector models; + if (InitModels(hadronicModelsString, models) != 0) + return 3; + + // prepare output + TFile *outF = new TFile(outputFileName.c_str(), "recreate"); + + // a trick to save E, since of->WriteObject(&E, "cmsEnergy") doesn't work + TGraph *data = new TGraph(); + data->SetName("data"); + data->SetPoint(0, 0., W/2.); + data->Write(); + + // build the profile-function plots + for (unsigned int mi = 0; mi < models.size(); mi++) + { + model = models[mi]; + + gDirectory = outF->mkdir(model->CompileShortLabel().c_str()); + + TGraph *g_prf_re = new TGraph(); g_prf_re->SetName("prf_re"); g_prf_re->SetTitle(model->CompileFullLabel().c_str()); + TGraph *g_prf_im = new TGraph(); g_prf_im->SetName("prf_im"); g_prf_im->SetTitle(model->CompileFullLabel().c_str()); + + double db = (b_max - b_min) / (N - 1); + double b = b_min; + for (unsigned int pi = 0; pi < N; pi++, b += db) + { + TComplex prf = model->Prf(b); + g_prf_re->SetPoint(pi, b, prf.Re()); + g_prf_im->SetPoint(pi, b, prf.Im()); + } + + g_prf_re->Write(); + g_prf_im->Write(); + } + + delete outF; + return 0; +} diff --git a/IOMC/Elegent/elegent/src/ElegentSDistributionSampler.cc b/IOMC/Elegent/elegent/src/ElegentSDistributionSampler.cc new file mode 100644 index 00000000000..8a79cb23743 --- /dev/null +++ b/IOMC/Elegent/elegent/src/ElegentSDistributionSampler.cc @@ -0,0 +1,255 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include +#include +#include + +#include "interface/Constants.h" +#include "interface/ModelFactory.h" + +#include "TFile.h" +#include "TGraph.h" + +using namespace Elegent; +using namespace std; + + +//---------------------------------------------------------------------------------------------------- + +void PrintUsage() +{ + printf("USAGE: ElegentSDistributionSampler [option] [option] ...\n"); + printf("OPTIONS:\n"); + printf("\t-h\t\t\tprint this help and exit\n"); + printf("\t-pp\t\t\tselect proton-proton interactions\n"); + printf("\t-app\t\t\tselect antiproton-proton interactions\n"); + printf("\t-N \t\tnumber of sampling points\n"); + printf("\t-Wmin \t\tlower bound of sqrt(s) (in GeV) for sampling\n"); + printf("\t-Wmax \t\tupper bound of sqrt(s) (in GeV) for sampling\n"); + printf("\t-models \tsemicolon-separated list of model tags\n"); + printf("\t-l, -model-list\t\tprint list of available model tags and exit\n"); + printf("\t-output \toutput file name\n"); +} + +//---------------------------------------------------------------------------------------------------- + +void PrintModelList() +{ + Constants::Init(1., Constants::mPP); + ModelFactory mf; + mf.PrintList(); +} + +//---------------------------------------------------------------------------------------------------- + +int InitModels(const string& hadronicModelsString, vector &models) +{ + + ModelFactory mf; + + size_t p_curr = 0; + while (true) + { + size_t p_next = hadronicModelsString.find(';', p_curr); + string tag = (p_next != string::npos) ? hadronicModelsString.substr(p_curr, p_next - p_curr) : hadronicModelsString.substr(p_curr); + + model = mf.MakeInstance(tag, false); + + if (model == NULL) + return 3; + + // force no presampling for model of Bourrely et al. + if (model->shortLabel.name.compare("bourrely") == 0) + { + BSWModel *bswm = (BSWModel *) model; + bswm->presampled = false; + bswm->highAccuracy = false; + } + + models.push_back(model); + + printf("\n>> model with tag `%s':\n", tag.c_str()); + + if (p_next == string::npos) + break; + else + p_curr = p_next + 1; + } + + return 0; +} + +//---------------------------------------------------------------------------------------------------- + +int main(int argc, char **argv) +{ + // defaults + Constants::ParticleMode pMode = Constants::mPP; + + unsigned int N = 1001; + double W_min = 5E0, W_max = 1E5; + + string hadronicModelsString = ""; + + string outputFileName = ""; + + // process command line + for (int i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-h") == 0) + { + PrintUsage(); + return 0; + } + + if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "-model-list") == 0) + { + PrintModelList(); + return 0; + } + + if (strcmp(argv[i], "-pp") == 0) + { + pMode = Constants::mPP; + continue; + } + + if (strcmp(argv[i], "-app") == 0) + { + pMode = Constants::mAPP; + continue; + } + + if (strcmp(argv[i], "-N") == 0) + { + if (argc-1 > i) + N = atoi(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-Wmax") == 0) + { + if (argc-1 > i) + W_max = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-Wmin") == 0) + { + if (argc-1 > i) + W_min = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-models") == 0) + { + if (argc-1 > i) + hadronicModelsString = argv[++i]; + continue; + } + + if (strcmp(argv[i], "-output") == 0) + { + if (argc-1 > i) + outputFileName = argv[++i]; + continue; + } + + printf("ERROR: unrecognised parameter `%s'.\n", argv[i]); + PrintUsage(); + return 10; + } + + // test input + bool stop = false; + if (outputFileName.empty()) + { + printf("ERROR: output not specified.\n"); + stop = true; + } + + if (N < 2) + { + printf("ERROR: N (%u) < 2\n", N); + stop = true; + } + + if (W_max <= W_min) + { + printf("ERROR: W_max (%.3E) <= W_min (%.3E)\n", W_max, W_min); + stop = true; + } + + if (stop) + { + PrintUsage(); + return 1; + } + + // print input + printf(">> ElegentSDistributionSampler > input:\n"); + printf("\tparticle mode %u\n", pMode); + + printf("\tsamples = %u, W_min, = %.2E, W_max = %.2E\n", N, W_min, W_max); + + printf("\tmodels = %s\n", hadronicModelsString.c_str()); + printf("\toutput = %s\n", outputFileName.c_str()); + + // initialise constants instance with dummy values + Constants::Init(1., pMode); + + // inialise models + vector models; + if (InitModels(hadronicModelsString, models) != 0) + return 3; + + // prepare output + TFile *outF = new TFile(outputFileName.c_str(), "recreate"); + + // build the s-distributions + for (unsigned int mi = 0; mi < models.size(); mi++) + { + model = models[mi]; + + string fullLabel = model->CompileFullLabel(); + //printf(">> %s\n", fullLabel.c_str()); + + gDirectory = outF->mkdir(model->CompileShortLabel().c_str()); + + TGraph *g_si_tot = new TGraph(); g_si_tot->SetName("si_tot"); g_si_tot->SetTitle(fullLabel.c_str()); + TGraph *g_rho = new TGraph(); g_rho->SetName("rho"); g_rho->SetTitle(fullLabel.c_str()); + TGraph *g_B0 = new TGraph(); g_B0->SetName("B0"); g_B0->SetTitle(fullLabel.c_str()); + + double f = exp( log(W_max / W_min) / (N - 1) ); + double W = W_min; + for (unsigned int pi = 0; pi < N; pi++, W *= f) + { + cnts->Configure(W, pMode); + + model->Init(); + + double ep = 1E-5; + TComplex amp0 = model->Amp(0.); + TComplex amp_ep = model->Amp(-ep); + + double si_tot = 4.*cnts->pi*cnts->sq_hbarc/cnts->p_cms/cnts->sqrt_s * amp0.Im(); + double rho = (amp0.Im() != 0.) ? amp0.Re() / amp0.Im() : 0.; + double B0 = ( log(amp0.Rho2()) - log(amp_ep.Rho2()) ) / ep; + + // fill graphs + g_si_tot->SetPoint(pi, W, si_tot); + g_rho->SetPoint(pi, W, rho); + g_B0->SetPoint(pi, W, B0); + } + + g_si_tot->Write(); + g_rho->Write(); + g_B0->Write(); + } + + delete outF; + return 0; +} diff --git a/IOMC/Elegent/elegent/src/ElegentTDistributionSampler.cc b/IOMC/Elegent/elegent/src/ElegentTDistributionSampler.cc new file mode 100644 index 00000000000..84d237bf1f1 --- /dev/null +++ b/IOMC/Elegent/elegent/src/ElegentTDistributionSampler.cc @@ -0,0 +1,513 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include +#include +#include + +#include "interface/Constants.h" +#include "interface/ModelFactory.h" +#include "interface/InterpolationModel.h" +#include "interface/CoulombInterference.h" + +#include "TFile.h" +#include "TGraph.h" + +using namespace Elegent; +using namespace std; + +//---------------------------------------------------------------------------------------------------- + +struct AmplitudeGraph +{ + TGraph *re, *im; +}; + +//---------------------------------------------------------------------------------------------------- + +void PrintUsage() +{ + printf("USAGE: ElegentTDistributionSampler [option] [option] ...\n"); + printf("OPTIONS:\n"); + printf("\t-h\t\t\tprint this help and exit\n"); + printf("\t-energy \t\tset collision energy (i.e. sqrt(s)), in GeV\n"); + printf("\t-pp\t\t\tselect proton-proton interactions\n"); + printf("\t-app\t\t\tselect antiproton-proton interactions\n"); + printf("\t-models \tsemicolon-separated list of model tags\n"); + printf("\t-l, -model-list\t\tprint list of available model tags and exit\n"); + printf("\t-output \toutput file name\n"); + printf("\n"); + printf("OPTIONS for hadronic-model sampling:\n"); + printf("\t-model-N \tnumber of sampling points\n"); + printf("\t-model-tmax \tmaximum |t| value (in GeV^2)\n"); + printf("\n"); + printf("OPTIONS for `full-range' graphs (sampling with linear steps in |t|):\n"); + printf("\t-full-N \tnumber of sampling points\n"); + printf("\t-full-tmax \tmaximum |t| value (in GeV^2)\n"); + printf("\n"); + printf("OPTIONS for `low-t' graphs (sampling with linear steps in log |t|):\n"); + printf("\t-lowt-N \tnumber of sampling points\n"); + printf("\t-lowt-tmax \tmaximum |t| value (in GeV^2)\n"); +} + +//---------------------------------------------------------------------------------------------------- + +void PrintModelList() +{ + Constants::Init(1., Constants::mPP); + ModelFactory mf; + mf.PrintList(); +} + +//---------------------------------------------------------------------------------------------------- + +int InitModels(const string& hadronicModelsString, vector &models) +{ + ModelFactory mf; + + size_t p_curr = 0; + while (true) + { + size_t p_next = hadronicModelsString.find(';', p_curr); + string tag = (p_next != string::npos) ? hadronicModelsString.substr(p_curr, p_next - p_curr) : hadronicModelsString.substr(p_curr); + + model = mf.MakeInstance(tag); + + if (model == NULL) + return 3; + + models.push_back(model); + + printf("\n>> model with tag `%s':\n", tag.c_str()); + model->Print(); + + if (p_next == string::npos) + break; + else + p_curr = p_next + 1; + } + + return 0; +} + +//---------------------------------------------------------------------------------------------------- + +void SampleModels(const vector &models, double t_max, unsigned int N, vector &models_sampled) +{ + for (unsigned int mi = 0; mi < models.size(); mi++) + { + model = models[mi]; + + InterpolationModel *ms = new InterpolationModel(N, -t_max, 0.); + ms->fullLabel.name = ms->fullLabel.name + ":interpolated"; + ms->shortLabel.name = ms->shortLabel.name + ":interpolated"; + + for (unsigned int pi = 0; pi < N; pi++) + { + double t = ms->GetT(pi); + TComplex a = model->Amp(t); + ms->SetPoint(pi, a); + } + + models_sampled.push_back(ms); + } +} + +//---------------------------------------------------------------------------------------------------- + +void SampleAmplitude(bool logarithmic, unsigned int N, double t_min, double t_max, double t_min_coulomb, + AmplitudeGraph &a, bool full) +{ + double dt = (t_max - t_min) / (N - 1); + double xi = pow(t_min/t_max, 1./(N - 1)); + + a.re = new TGraph(); a.re->SetName("re"); + a.im = new TGraph(); a.im->SetName("im"); + + unsigned int idx = 0; + for (unsigned int pi = 0; pi < N; pi++) + { + double t = (logarithmic) ? t_max * pow(xi, pi) : t_max - dt * pi; + + if (!full) + { + if (fabs(t) < 1E-6) + continue; + + if (t < t_min_coulomb) + continue; + } + + TComplex v = coulomb->Amp(t); + a.re->SetPoint(idx, -t, v.Re()); + a.im->SetPoint(idx, -t, v.Im()); + idx++; + } +} + +//---------------------------------------------------------------------------------------------------- + +void BuildAmplitudes(const vector &models_sampled, + bool logarithmic, unsigned int N, double t_min, double t_max, + const vector &litudeModes, + double t_min_coulomb, + AmplitudeGraph &litude_pc, vector< map > &litudes) +{ + // PC amplitude + coulomb->mode = CoulombInterference::mPC; + SampleAmplitude(logarithmic, N, t_min, t_max, t_min_coulomb, amplitude_pc, false); + + // other amplitudes + amplitudes.clear(); + amplitudes.resize(models_sampled.size()); + for (unsigned int mi = 0; mi < models_sampled.size(); mi++) + { + model = models_sampled[mi]; + + map &as = amplitudes[mi]; + + for (unsigned int cii = 0; cii < amplitudeModes.size(); cii++) + { + coulomb->mode = amplitudeModes[cii]; + + AmplitudeGraph &a = as[amplitudeModes[cii]]; + SampleAmplitude(logarithmic, N, t_min, t_max, t_min_coulomb, a, (amplitudeModes[cii] == CoulombInterference::mPH)); + } + } +} + +//---------------------------------------------------------------------------------------------------- + +void WriteOneAmplitudeGraphs(const AmplitudeGraph &a, const string &label) +{ + a.re->SetTitle(label.c_str()); + a.re->Write("amplitude_re"); + a.im->SetTitle(label.c_str()); + a.im->Write("amplitude_im"); + + // build differential and cumulative cross-sections + TGraph *phase = new TGraph(); phase->SetName("phase"); phase->SetTitle(label.c_str()); + TGraph *rho = new TGraph(); rho->SetName("rho"); rho->SetTitle(label.c_str()); + TGraph *B = new TGraph(); B->SetName("B"); B->SetTitle(label.c_str()); + TGraph *dif = new TGraph(); dif->SetName("differential cross-section"); dif->SetTitle(label.c_str()); + TGraph *cum = new TGraph(); cum->SetName("cumulative cross-section"); cum->SetTitle(label.c_str()); + + double *at = a.re->GetX(); + double *ar = a.re->GetY(); + double *ai = a.im->GetY(); + + double S=0., prev_t=0., prev_cs=0.; + for (int i = 0; i < a.re->GetN(); i++) + { + TComplex A(ar[i], ai[i]); + double cs = cnts->sig_fac * A.Rho2(); + + dif->SetPoint(i, at[i], cs); + phase->SetPoint(i, at[i], A.Theta()); + rho->SetPoint(i, at[i], 1./tan(A.Theta())); + + if (i > 0) + B->SetPoint(i-1, (at[i] + prev_t)/2., (log(prev_cs) - log(cs)) / (at[i] - prev_t)); + + if (i > 0) + S += (cs + prev_cs) * (at[i] - prev_t) / 2.; + + cum->SetPoint(i, at[i], S); + + prev_cs = cs; + prev_t = at[i]; + } + + phase->Write(); + rho->Write(); + B->Write(); + dif->Write(); + cum->Write(); +} + +//---------------------------------------------------------------------------------------------------- + +void WriteCRZGraphs(const AmplitudeGraph &_pc, const AmplitudeGraph &_ph, + const AmplitudeGraph &_kl, const AmplitudeGraph &_swy, const string &label) +{ + TGraph *C = new TGraph(); C->SetName("C"); C->SetTitle(label.c_str()); + TGraph *R = new TGraph(); R->SetName("R"); R->SetTitle(label.c_str()); + TGraph *Z = new TGraph(); Z->SetName("Z"); Z->SetTitle(label.c_str()); + + for (int i = 0; i < amp_kl.re->GetN(); i++) + { + double t, pcR, pcI, phR, phI, klR, klI, swyR, swyI; + amp_kl.re->GetPoint(i, t, klR); + amp_kl.im->GetPoint(i, t, klI); + + pcR = amp_pc.re->Eval(t); + pcI = amp_pc.im->Eval(t); + phR = amp_ph.re->Eval(t); + phI = amp_ph.im->Eval(t); + swyR = amp_swy.re->Eval(t); + swyI = amp_swy.im->Eval(t); + + TComplex ph(phR, phI), pc(pcR, pcI), swy(swyR, swyI), kl(klR, klI); + + double vC = (kl.Rho2() - ph.Rho2()) / ph.Rho2(); + double vZ = (kl.Rho2() - ph.Rho2() - pc.Rho2()) / kl.Rho2(); + double vR = (kl.Rho2() - swy.Rho2()) / kl.Rho2(); + + Z->SetPoint(i, t, vZ); + C->SetPoint(i, t, vC); + R->SetPoint(i, t, vR); + } + + C->Write(); + R->Write(); + Z->Write(); +} + +//---------------------------------------------------------------------------------------------------- + +void WriteGraphs(const vector &models, const AmplitudeGraph &litude_pc, + const vector< map > &litudes) +{ + TDirectory *topDir = gDirectory; + + // coulomb graphs + gDirectory = topDir->mkdir("PC"); + WriteOneAmplitudeGraphs(amplitude_pc, "Coulomb"); + + for (unsigned int mi = 0; mi < amplitudes.size(); mi++) + { + string shortLabel = models[mi]->CompileShortLabel(); + string fullLabel = models[mi]->CompileFullLabel(); + + TDirectory *modelDir = topDir->mkdir(shortLabel.c_str()); + + for (map::const_iterator mit = amplitudes[mi].begin(); mit != amplitudes[mi].end(); ++mit) + { + coulomb->mode = mit->first; + gDirectory = modelDir->mkdir(coulomb->GetModeString().c_str()); + + WriteOneAmplitudeGraphs(mit->second, fullLabel); + } + + gDirectory = modelDir; + const map &m = amplitudes[mi]; + map::const_iterator it_ph = m.find(CoulombInterference::mPH); + map::const_iterator it_kl = m.find(CoulombInterference::mKL); + map::const_iterator it_swy = m.find(CoulombInterference::mSWY); + + if (it_ph == m.end() || it_kl == m.end() || it_swy == m.end()) + { + printf("ERROR: some of the PH, KL, SWY amplitudes are missing for model `%s'.\n", shortLabel.c_str()); + continue; + } + + WriteCRZGraphs(amplitude_pc, it_ph->second, it_kl->second, it_swy->second, fullLabel); + } +} + +//---------------------------------------------------------------------------------------------------- + +int main(int argc, char **argv) +{ + // defaults + double W = 0.; + Constants::ParticleMode pMode = Constants::mPP; + + unsigned int model_N = 10001, fullRange_N = 5001, lowt_N = 501; + double model_t_max = 20., fullRange_t_max = 20., lowt_t_max = 1.; + + string hadronicModelsString = ""; + + string outputFileName = ""; + + // process command line + for (int i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-h") == 0) + { + PrintUsage(); + return 0; + } + + if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "-model-list") == 0) + { + PrintModelList(); + return 0; + } + + if (strcmp(argv[i], "-energy") == 0) + { + if (argc-1 > i) + W = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-pp") == 0) + { + pMode = Constants::mPP; + continue; + } + + if (strcmp(argv[i], "-app") == 0) + { + pMode = Constants::mAPP; + continue; + } + + if (strcmp(argv[i], "-model-N") == 0) + { + if (argc-1 > i) + model_N = atoi(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-model-tmax") == 0) + { + if (argc-1 > i) + model_t_max = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-full-N") == 0) + { + if (argc-1 > i) + fullRange_N = atoi(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-full-tmax") == 0) + { + if (argc-1 > i) + fullRange_t_max = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-lowt-N") == 0) + { + if (argc-1 > i) + lowt_N = atoi(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-lowt-tmax") == 0) + { + if (argc-1 > i) + lowt_t_max = atof(argv[++i]); + continue; + } + + if (strcmp(argv[i], "-models") == 0) + { + if (argc-1 > i) + hadronicModelsString = argv[++i]; + continue; + } + + + if (strcmp(argv[i], "-output") == 0) + { + if (argc-1 > i) + outputFileName = argv[++i]; + continue; + } + + printf("ERROR: unrecognised parameter `%s'.\n", argv[i]); + PrintUsage(); + return 10; + } + + // test input + bool stop = false; + if (W == 0.) + { + printf("ERROR: collision energy not specified.\n"); + stop = true; + } + + if (outputFileName.empty()) + { + printf("ERROR: output not specified.\n"); + stop = true; + } + + if (stop) + { + PrintUsage(); + return 1; + } + + // print input + printf(">> ElegentTDistributionSampler > input:\n"); + printf("\tsqrt(s) = %E\n", W); + printf("\tparticle mode %u\n", pMode); + + printf("\tmodel sampling: samples = %u, t_max = %.2E\n", model_N, model_t_max); + printf("\tfull-range plots: samples = %u, t_max = %.2E\n", fullRange_N, fullRange_t_max); + printf("\tlow-|t| plots: samples = %u, t_max = %.2E\n", lowt_N, lowt_t_max); + + printf("\tmodels = %s\n", hadronicModelsString.c_str()); + printf("\toutput = %s\n", outputFileName.c_str()); + + // initialise constants etc. + Constants::Init(W, pMode); + cnts->Print(); + coulomb->Print(); + + // is model_t_max high enough + if (model_t_max < coulomb->T) + { + printf("ERROR: model_t_max = %.2E is lower than CoulombInterference::T = %.2E\n", model_t_max, coulomb->T); + return 2; + } + double t_min_coulomb = -(model_t_max - coulomb->T); + + // inialise models + vector models; + if (InitModels(hadronicModelsString, models) != 0) + return 3; + + // prepare output + TFile *outF = new TFile(outputFileName.c_str(), "recreate"); + + // a trick to save E, since of->WriteObject(&E, "cmsEnergy") doesn't work + TGraph *data = new TGraph(); + data->SetName("data"); + data->SetPoint(0, 0., W/2.); + data->Write(); + + // sample the models + vector models_sampled; + SampleModels(models, model_t_max, model_N, models_sampled); + + // select amplitudes to be generated + vector amplitudeModes; + amplitudeModes.push_back(CoulombInterference::mPH); + //amplitudeModes.push_back(CoulombInterference::mWY); + amplitudeModes.push_back(CoulombInterference::mSWY); + amplitudeModes.push_back(CoulombInterference::mKL); + + // build full-range amplitudes + AmplitudeGraph amplitude_pc_full; + vector< map > amplitudes_full; + BuildAmplitudes(models_sampled, false, fullRange_N, -fullRange_t_max, 0., amplitudeModes, + t_min_coulomb, amplitude_pc_full, amplitudes_full); + + // write full-range graphs + gDirectory = outF->mkdir("full range"); + WriteGraphs(models, amplitude_pc_full, amplitudes_full); + + // build low-|t| amplitudes + AmplitudeGraph amplitude_pc_lowt; + vector< map > amplitudes_lowt; + BuildAmplitudes(models_sampled, true, lowt_N, -lowt_t_max, -1E-5, amplitudeModes, + t_min_coulomb, amplitude_pc_lowt, amplitudes_lowt); + + // build low-|t| graphs + gDirectory = outF->mkdir("low |t|"); + WriteGraphs(models, amplitude_pc_lowt, amplitudes_lowt); + + delete outF; + return 0; +} diff --git a/IOMC/Elegent/elegent/src/ElegentTest.cc b/IOMC/Elegent/elegent/src/ElegentTest.cc new file mode 100644 index 00000000000..6de167e00aa --- /dev/null +++ b/IOMC/Elegent/elegent/src/ElegentTest.cc @@ -0,0 +1,49 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include +#include + +#include "interface/Generator.h" + +#include "HepMC/GenEvent.h" + +using namespace Elegent; +using namespace std; +using namespace HepMC; + +//---------------------------------------------------------------------------------------------------- + +void PrintUsage() +{ + printf("USAGE: ElegentTest \n"); +} + +//---------------------------------------------------------------------------------------------------- + +int main(int argc, char **argv) +{ + if (argc != 6) + { + PrintUsage(); + return 1; + } + + Generator generator(argv[1], argv[2], atof(argv[3]), atof(argv[4])); + if (generator.Init() != 0) + return 2; + + unsigned int N = atoi(argv[5]); + for (unsigned int i = 0; i < N; i++) + { + GenEvent* gEv = new GenEvent(); + gEv->set_event_number(i); + generator.Generate(gEv); + gEv->print(); + delete gEv; + } + + return 0; +} diff --git a/IOMC/Elegent/elegent/src/ExpModel.cc b/IOMC/Elegent/elegent/src/ExpModel.cc new file mode 100644 index 00000000000..9550afcf6aa --- /dev/null +++ b/IOMC/Elegent/elegent/src/ExpModel.cc @@ -0,0 +1,62 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/ExpModel.h" +#include "interface/Constants.h" + +using namespace Elegent; + +//---------------------------------------------------------------------------------------------------- + +ExpModel::ExpModel() +{ + fullLabel.name = "exponential"; shortLabel.name = "exp"; +} + +//---------------------------------------------------------------------------------------------------- + +void ExpModel::Configure() +{ + fullLabel.variant = ""; shortLabel.variant = ""; + fullLabel.version = ""; shortLabel.version = ""; + fullLabel.mode = ""; shortLabel.mode = ""; +} + +//---------------------------------------------------------------------------------------------------- + +void ExpModel::Init() +{ + a = 2E9; + b1 = 10.; + b2 = 0.; + p0 = M_PI/2.; + p1 = 0.; +} + +//---------------------------------------------------------------------------------------------------- + +void ExpModel::Print() const +{ + printf(">> ExpModel::Print\n"); + printf("\ta=%E\n", a); + printf("\tb1=%E, b2=%E\n", b1, b2); + printf("\tp0=%E, p1=%E\n", p0, p1); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex ExpModel::Prf(double ) const +{ + // this function is not planned to be used + printf(">> ExpModel::Prf > not implemented.\n"); + return 0.; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex ExpModel::Amp(double t) const +{ + return a * TComplex::Exp( b1*t + b2*t*t + i*(p0 + p1*t) ); +} diff --git a/IOMC/Elegent/elegent/src/Generator.cc b/IOMC/Elegent/elegent/src/Generator.cc new file mode 100644 index 00000000000..60c0184d59c --- /dev/null +++ b/IOMC/Elegent/elegent/src/Generator.cc @@ -0,0 +1,165 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/Generator.h" + +#include "HepMC/GenEvent.h" + +#include + +#include "TGraph.h" +#include "TFile.h" +#include "TClass.h" +#include "TRandom2.h" + + +using namespace std; +using namespace HepMC; +using namespace Elegent; + +//---------------------------------------------------------------------------------------------------- + +Generator::Generator(const string &_file, const string &_path, double _t_min, double _t_max, unsigned int _verbosity) : + fileName(_file), modelPath(_path), t_min(_t_min), t_max(_t_max), verbosity(_verbosity) +{ +} + +//---------------------------------------------------------------------------------------------------- + +unsigned int Generator::Init() +{ + // try to open the file + TFile file(fileName.c_str()); + if (file.IsZombie()) + { + printf("ERROR in Elegent::Generator::Init > File `%s' can not be loaded.\n", fileName.c_str()); + return 1; + } + + // get cms energy + TGraph *data = (TGraph *) file.Get("data"); + if (!data) + { + printf("ERROR in Elegent::Generator::Init > File `%s' does not contain `data' object.\n", fileName.c_str()); + return 2; + } + double dummy; + data->GetPoint(0, dummy, E_cms); + + // try to load sigma_int graph + TObject *o = file.Get(modelPath.c_str()); + if (!o || !o->IsA()->InheritsFrom("TGraph")) + { + file.ls(); + printf("ERROR in Elegent::Generator::Init > Model `%s' not found.\n", modelPath.c_str()); + return 3; + } + TGraph *sigma_int = (TGraph*) o; + + // prepare normalized inverse c.d.f + int i_min = 0, i_max = sigma_int->GetN() - 1; // default index range + for (int i = 0; i < sigma_int->GetN(); i++) + { + double x, y; + sigma_int->GetPoint(i, x, y); + if (x < t_min) + i_min = i; + if (x > t_max) + { + i_max = i; + break; + } + } + + double p_min = 0., p_max = 0.; + double t_min_real = 0., t_max_real = 0.; + sigma_int->GetPoint(i_min, t_min_real, p_min); + sigma_int->GetPoint(i_max, t_max_real, p_max); + + if (verbosity > 0) + { + printf(">> Elegent::Generator > inverse cdf:\n\tfile: %s\n\tmodel: %s\n", fileName.c_str(), modelPath.c_str()); + printf("\trequested |t| range: %.2E to %.2E GeV^2\n", t_min, t_max); + printf("\tpoints loaded: %i\n", i_max - i_min + 1); + printf("\t\tfirst point: idx = %i, |t| = %.2E GeV^2, p = %.2E mb\n", i_min, t_min_real, p_min); + printf("\t\tlast point: idx = %i, |t| = %.2E GeV^2, p = %.2E mb\n", i_max, t_max_real, p_max); + printf("\t|t| range: %.2E to %.2E GeV^2\n", t_min_real, t_max_real); + printf("\tcorresponding cross-section: %.2E mb\n", p_max - p_min); + } + + if (i_min >= i_max) + { + printf("ERROR in Elegent::Generator::Init > Wrong (t_min, t_max) region (%.2E, %.2E) or empty intersection with CDF domain.\n", t_min, t_max); + return 4; + } + + icdf = new TGraph(); + for (int i = i_min; i <= i_max; i++) + { + double x, y; + sigma_int->GetPoint(i, x, y); + icdf->SetPoint(icdf->GetN(), (y - p_min) / (p_max - p_min), x); + } + + // precompute kinematics + double m = 0.938; // GeV + p_cms = sqrt(E_cms*E_cms - m*m); + if (verbosity > 0) + { + printf("\n>> Elegent::Generator > proton kinematics in CM frame (in GeV)\n"); + printf("\tE = %.3f\n", E_cms); + printf("\tp = %.3f\n", p_cms); + printf("\tm = %.3f\n", m); + } + + return 0; +} + +//---------------------------------------------------------------------------------------------------- + +void Generator::GenerateBase(double rn1, double rn2, GenEvent* gEv) +{ + gEv->set_signal_process_id(Generator::ElasticScattering); + + // create vertex at t = 0, position 0; + GenVertex* gVx = new GenVertex(FourVector(0., 0., 0., 0.)); + gEv->add_vertex(gVx); + + // generation + double p = 0., t = 0., phi = 0., theta = 0.; + p = rn1; + t = icdf->Eval(p); // |t| + phi = rn2 * 2. * M_PI; + + theta = sqrt(t) / p_cms; + + // kinematics collison in CM frame + double p_x = p_cms * sin(theta) * cos(phi); + double p_y = p_cms * sin(theta) * sin(phi); + double p_z = p_cms * cos(theta); + + if (verbosity > 5) + { + if (verbosity > 6) + printf("prob = %.3f\n", p); + printf("|t| = %.2E GeV^2, theta = %.2E\n", t, theta); + printf("phi = %.2E, theta_x = %.2E, theta_y = %.2E\n", phi, theta*cos(phi), theta*sin(phi)); + printf("px = %.2E, py = %.2E, pz = %.2E\n", p_x, p_y, p_z); + } + + // add initial and final particles to the vertex + GenParticle* gPe; + gPe = new GenParticle(HepMC::FourVector(0., 0., p_cms, E_cms), PID, NullState); gPe->suggest_barcode(1); gVx->add_particle_in(gPe); + gPe = new GenParticle(HepMC::FourVector(0., 0., -p_cms, E_cms), PID, NullState); gPe->suggest_barcode(2); gVx->add_particle_in(gPe); + gPe = new GenParticle(HepMC::FourVector(p_x, p_y, p_z, E_cms), PID, FinalState); gPe->suggest_barcode(3); gVx->add_particle_out(gPe); + gPe = new GenParticle(HepMC::FourVector(-p_x, -p_y, -p_z, E_cms), PID, FinalState); gPe->suggest_barcode(4); gVx->add_particle_out(gPe); +} + +//---------------------------------------------------------------------------------------------------- + +void Generator::Generate(GenEvent* gEv) +{ + GenerateBase(gRandom->Rndm(), gRandom->Rndm(), gEv); +} diff --git a/IOMC/Elegent/elegent/src/InterpolationModel.cc b/IOMC/Elegent/elegent/src/InterpolationModel.cc new file mode 100644 index 00000000000..0414ec4cdfe --- /dev/null +++ b/IOMC/Elegent/elegent/src/InterpolationModel.cc @@ -0,0 +1,53 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/InterpolationModel.h" + +#include "TGraph.h" + +namespace Elegent +{ + +//#define DEBUG 1 + +//---------------------------------------------------------------------------------------------------- + +InterpolationModel::InterpolationModel(unsigned int _N, double _t_min, double _t_max) : + N(_N), t_min(_t_min), t_max(_t_max), dt( (t_max - t_min) / (N-1) ), amp_data(N) +{ + fullLabel.name = "Interpolation"; shortLabel.name = "itpl"; +} + +//---------------------------------------------------------------------------------------------------- + +void InterpolationModel::Configure() +{ +} + +//---------------------------------------------------------------------------------------------------- + +InterpolationModel::~InterpolationModel() +{ +} + +//---------------------------------------------------------------------------------------------------- + +void InterpolationModel::Print() const +{ + printf(">> InterpolationModel::Print\n"); + printf("\tN = %u, t_min = %.3E, t_max = %.3E\n", N, t_min, t_max); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex InterpolationModel::Prf(double) const +{ + // this function is not planned to be used + printf(">> InterpolationModel::Prf > not implemented.\n"); + return 0.; +} + + +} // namespace diff --git a/IOMC/Elegent/elegent/src/IslamModel.cc b/IOMC/Elegent/elegent/src/IslamModel.cc new file mode 100644 index 00000000000..a0aba0ec084 --- /dev/null +++ b/IOMC/Elegent/elegent/src/IslamModel.cc @@ -0,0 +1,453 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/IslamModel.h" +#include "interface/Math.h" +#include "interface/Constants.h" + +using namespace std; +using namespace Elegent; + +//#define DEBUG 1 + +//---------------------------------------------------------------------------------------------------- + +IslamModel::IslamModel() +{ + fullLabel.name = "Islam et al."; shortLabel.name = "islam"; +} + +//---------------------------------------------------------------------------------------------------- + +void IslamModel::Configure(IslamModel::VariantType _v, IslamModel::ModeType _m) +{ + variant = _v; + mode = _m; + + if (variant == vHP) + { + fullLabel.variant = "HP"; shortLabel.variant = "hp"; + } + + // low-x gluons variant + if (variant == vLxG) + { + fullLabel.variant = "LxG"; shortLabel.variant = "lxg"; + } + + // set labels + fullLabel.version = "Int. J. Mod. Phys. A21 (2006) 1-42, Mod. Phys. Lett. A24 (2009) 485-496"; shortLabel.version = "06,09"; + + if (mode == mDiff) + { fullLabel.mode = "diffraction"; shortLabel.mode = "diff"; } + if (mode == mCore) + { fullLabel.mode = "core"; shortLabel.mode = "core"; } + if (mode == mQuark) + { fullLabel.mode = "quark-quark"; shortLabel.mode = "quark"; } + if (mode == mDiffCore) + { fullLabel.mode = "diffraction+core"; shortLabel.mode = "diff+core"; } + if (mode == mFull) + { fullLabel.mode = "full"; shortLabel.mode = "full"; } +} + +//---------------------------------------------------------------------------------------------------- + +void IslamModel::Init() +{ + // ---------- diffraction amplitude ---------- + // parameters from page 23 of [4] + double R0 = 2.77; + double R1 = 0.0491; + double a0 = 0.245; + double a1 = 0.126; + R = TComplex(R0 + R1*cnts->ln_s, -R1*cnts->pi/2); + a = TComplex(a0 + a1*cnts->ln_s, -a1*cnts->pi/2); + + double et0 = 0.0844; + double c0 = 0.0; + double si = 2.7; + + // function g(s) according to Eq. (4.2) in [4] + TComplex g_s = (1. - CEF(et0, c0, si)) * (1. + TComplex::Exp(-R/a)) / (1. - TComplex::Exp(-R/a)); + Diff_fac = i * cnts->sqrt_s * cnts->p_cms * g_s; + Diff_fac_profile = g_s * i/2.; + + // ---------- absorbtion factor due to diffraction ---------- + + // parameters from page 23 of [4] + double la0 = 0.727; + double d0 = 13.; + double al = 0.246; + double hga0 = 1.53; + double hga1 = 0.; + double hsi = 1.46; + + if (cnts->pMode == cnts->mPP) + Abs_fac = cnts->s * CEF(hga0, hga1, hsi) * ( CEF(et0, c0, si) + i*CEF(la0, -d0, al) ); + + if (cnts->pMode == cnts->mAPP) + Abs_fac = cnts->s * CEF(hga0, hga1, hsi) * ( CEF(et0, c0, si) - i*CEF(la0, -d0, al) ); + + // ---------- core amplitude ---------- + // parameters from page 23 of [4] + beta = 3.075; + double m_omega = 0.801; + m_omega_sq = m_omega * m_omega; + + if (cnts->pMode == cnts->mPP) + Core_fac = -1; + + if (cnts->pMode == cnts->mAPP) + Core_fac = +1; + + // ---------- quark-quark amplitude ---------- + + // parameter from page 25 of [4] + m0sq = 12.; + + // hard pomeron variant + if (variant == vHP) + { + // parameters from page 25 of [4] + double tgaqq = 0.03; + omega = 0.15; + r0 = 2.; + + // the factor (without s) multiplying the 2nd term in the 2nd brackets in Eq. (6.3) in [4] + Quark_fac = i * tgaqq * TComplex::Power(-i * cnts->s, omega); + + Quark_const = -2. * tgaqq * TComplex::Power(-i * cnts->s, omega); + + // Born term only by default + qqMaxOrder = 1; + } + + // low-x gluons variant + if (variant == vLxG) + { + double tgagg = 0.0056; // TODO: no reference found! + + // parameters from page 8 of [5] + lambda = 0.29; + m_c = 1.67; + + // the factor (without is) multiplying the fraction in Eq. (32) in [5] + cgc_fac = tgagg * TComplex::Power(-i * cnts->s, lambda); + + // Born term only by default + cgcMaxOrder = 1; + } + + // integration parameters + precision = 1E-11; + precision_t = 1E-4; + upper_bound = 50.; + upper_bound_t = -15.; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::CEF(double a, double b, double c) +{ + // crossing-even function: + // a + b / (s exp(-i pi/2))^c + // = a + b / (-i s)^c = a + b (-i s)^(-c) + return a + b * TComplex::Power(-i * cnts->s, -c); +} + +//---------------------------------------------------------------------------------------------------- + +void IslamModel::Print() const +{ + printf(">> IslamModel::Print\n"); + printf("\t%s\n", CompileFullLabel().c_str()); + printf("\tdiffraction variables\n"); + double v1 = R.Im(); v1 = -v1 * 2 / cnts->pi; + double v0 = R.Re(); v0 -= v1 * cnts->ln_s; + printf("\t\tR0=%f, R1=%f\n", v0, v1); + v1 = a.Im(); v1 = -v1 * 2 / cnts->pi; + v0 = a.Re(); v0 -= v1 * cnts->ln_s; + printf("\t\ta0=%f, a1=%f\n", v0, v1); + printf("\t\tR: Re=%E, Im=%E\n", R.Re(), R.Im()); + printf("\t\ta: Re=%E, Im=%E\n", a.Re(), a.Im()); + printf("\t\tDiff_fac_profile: Re=%E, Im=%E\n", Diff_fac_profile.Re(), Diff_fac_profile.Im()); + printf("\t\tDiff_fac: Re=%E, Im=%E\n", Diff_fac.Re(), Diff_fac.Im()); + printf("\t\tAbs_fac: Re=%E, Im=%E\n", Abs_fac.Re(), Abs_fac.Im()); + + printf("\tcore scattering variables\n"); + printf("\t\tbeta = %E\n", beta); + printf("\t\tm_omega_sq = %E\n", m_omega_sq); + printf("\t\tCore_fac = %E\n", Core_fac); + + printf("\tquark-quard scattering variables\n"); + printf("\t\tm0sq = %E\n", m0sq); + printf("\t\tr0 = %E\n", r0); + printf("\t\tomega = %E\n", omega); + printf("\t\tQuark_fac: Re=%E, Im=%E\n", Quark_fac.Re(), Quark_fac.Im()); + printf("\t\tQuark_const: Re=%E, Im=%E\n", Quark_const.Re(), Quark_const.Im()); + printf("\t\tqqMaxOrder = %i\n", qqMaxOrder); + printf("\t\tlambda = %E\n", lambda); + printf("\t\tm_c = %E\n", m_c); + printf("\t\tcgc_fac: Re=%E, Im=%E\n", cgc_fac.Re(), cgc_fac.Im()); + printf("\t\tcgcMaxOrder = %i\n", cgcMaxOrder); + + printf("\tintegration variables\n"); + printf("\t\tprecision = %E\n", precision); + printf("\t\tprecision_t = %E\n", precision_t); + printf("\t\tupper_bound = %E\n", upper_bound); + printf("\t\tupper_bound_t = %E\n", upper_bound_t); +} + +//-------------------------------------- DIFFRACTION AMPLITUDE ------------------------------------ + +TComplex IslamModel::GammaD(double b) const +{ + /// b-dependent part of profile function Gamma_D^+ in Eq. (2.7) in [4] + /// b... impact parameter in fm + return 1. / (1. + TComplex::Exp((b - R) / a)) + 1. / (1. + TComplex::Exp((-b - R) / a)) - 1.; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::GammaD_J0(double *b, double *t, const void *obj) +{ + /// b[0] ... impact parameter in fm + /// t[0] ... t in GeV^2 + return ((IslamModel *)obj)->GammaD(b[0]) * b[0] * TMath::BesselJ0(b[0]*sqrt(-t[0])); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_diff(double t) const +{ +#ifdef DEBUG + printf(">> IslamModel::T_diff\n"); +#endif + + /// t < 0 + return Diff_fac * CmplxInt(this, GammaD_J0, 0, upper_bound, &t, precision); +} + +//----------------------------------------- CORE AMPLITUDE ---------------------------------------- + +double IslamModel::F_sq(double t) const +{ + /// formfactor, t < 0 + return beta * sqrt(m_omega_sq - t) * TMath::BesselK1(beta * sqrt(m_omega_sq - t)); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_core(double t) const +{ +#ifdef DEBUG + printf(">> IslamModel::T_core\n"); +#endif + + /// t < 0 + return Core_fac * Abs_fac * F_sq(t) / (m_omega_sq - t); +} + + +//---------------------------------------- QUARK AMPLITUDE ---------------------------------------- + +double IslamModel::I_integral(double qt, double al) const +{ + double ap = qt/2./al; + double a = sqrt(ap * ap + 1.); + double ival; + + // for small qt values just substitute limit value 16/3 + if (qt > 1E-10) + ival = ( 2./a/a + 1./ap/ap - 3.*ap*ap/a/a/a/a ) / a/ap * log(a + ap) - 1./a/a/ap/ap + 3./a/a/a/a; + else ival = 16./3.; + + return 1./8. /al/al/al/al * ival; +} + +//---------------------------------------------------------------------------------------------------- + +double IslamModel::F_cal_integ(double *x, double *par, const void *obj) +{ + double &qt = par[0]; + double &n = par[1]; + double &omega = par[2]; + double &m0sq = par[3]; + double al_sq = m0sq/4. + cnts->M_sq * x[0] * x[0]; + double al = sqrt(al_sq); + return exp((1. + n * omega) * log(x[0])) / al_sq * ((IslamModel *)obj)->I_integral(qt, al); +} + +//---------------------------------------------------------------------------------------------------- + +double IslamModel::F_cal(int n, double qt, double omega, double m0sq) const +{ + double par[4]; + par[0] = qt; + par[1] = n; + par[2] = omega; + par[3] = m0sq; + return cnts->M * exp(2.5 * log(m0sq)) / 8. / cnts->pi * DoubleInt(this, F_cal_integ, 0., 1., par, 1E-9); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_quark(double t) const +{ + switch (variant) + { + case vHP: return T_hp(t); + case vLxG: return T_lxg(t); + default: + printf("ERROR in IslamModel::T_quark > unknown variant %i\n", variant); + return 0.; + } +} + +//---------------------------------------------------------------------------------------------------- + +double IslamModel::T_hp_integ(double *bArr, double *par, const void *obj) +{ + double &b = bArr[0]; + double &q = par[0]; // par[0] ... q + double &n = par[1]; // par[1] ... n + return b * TMath::BesselJ0(b * q) * pow( TMath::BesselK0(b / ((IslamModel *)obj)->r0) , n); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_hp_n(int n, double t) const +{ + double q = sqrt(fabs(t)); + + if (n == 1) + return Quark_fac / (-t + 1./r0/r0); + + if (n == 2) + { + if (q < 1E-2) + return i * Quark_fac*Quark_fac * r0*r0*r0/4.; // limit + else + return i * Quark_fac*Quark_fac * 2. * asinh(q * r0 / 2.) / q / sqrt( fabs(t) + 4./r0/r0 ); + } + + // general formula + double par[2]; + par[0] = q; + par[1] = n; + + // correct -i + return -i / 2. / TMath::Factorial(n) * TComplex::Power(Quark_const, n) * DoubleInt(this, T_hp_integ, 0., 30., par, 1E-9); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_hp(double t) const +{ +#ifdef DEBUG + printf(">> IslamModel::T_hp\n"); +#endif + + /// t < 0 + double qt = sqrt(-t * (-t / cnts->t_min + 1.)); + + TComplex sum = 0.; + for (int j = 1; j <= qqMaxOrder; j++) + { + double F = F_cal(j, qt, omega, m0sq); + sum += F*F * T_hp_n(j, t); + } + + return Abs_fac * sum; +} + +//------------------------------------ CGC AMPLITUDE ------------------------------------------------- + +double IslamModel::T_lxg_integ(double *bArr, double *par, const void *obj) +{ + double &b = bArr[0]; + double &q = par[0]; // par[0] ... q + double &n = par[1]; // par[1] ... n + double &m_c = ((IslamModel *)obj)->m_c; + return b * TMath::BesselJ0(b * q) * pow(exp(-b * m_c) * m_c*m_c * (1. + b*m_c) / 3., n); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_lxg_n(int n, double t) const +{ + double q = sqrt(fabs(t)); + + if (n == 1) + return i * cgc_fac / pow(1. - t/m_c/m_c, 2.5); + + // general formula + double par[2]; + par[0] = q; + par[1] = n; + return i * pow(-2., n - 1) / TMath::Factorial(n) * TComplex::Power(cgc_fac, n) * DoubleInt(this, T_lxg_integ, 0., 30., par, 1E-9); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_lxg(double t) const +{ +#ifdef DEBUG + printf(">> IslamModel::T_lxg\n"); +#endif + + /// t < 0 + double qt = sqrt(-t * (-t / cnts->t_min + 1.)); + + TComplex sum = 0.; + for (int j = 1; j <= cgcMaxOrder; j++) + { + double F = F_cal(j, qt, lambda, m0sq); + sum += F*F * T_lxg_n(j, t); + } + + return Abs_fac * sum; +} + +//---------------------------------------------------------------------------------------------------- +//----------------------------------------- FULL AMPLITUDE ---------------------------------------- + +TComplex IslamModel::Amp(double t) const +{ +#ifdef DEBUG + printf(">> IslamModel::amp, mode = %i\n", mode); +#endif + + switch (mode) + { + case mDiff: return T_diff(t); + case mCore: return T_core(t); + case mQuark: return T_quark(t); + case mDiffCore: return T_diff(t) + T_core(t); + case mFull: return T_diff(t) + T_core(t) + T_quark(t); + default: + printf("ERROR in IslamModel::Amp > unknown mode %i\n", mode); + return 0.; + } +} + + +//---------------------------------------------------------------------------------------------------- +//---------------------------------------- PROFILE FUNCTIONS -------------------------------------- + +TComplex IslamModel::Amp_J0(double *t, double *b, const void *obj) +{ + /// b[0] ... impact parameter in fm + /// t[0] ... t in GeV^2 + return ((IslamModel *)obj)->Amp(t[0]) * TMath::BesselJ0(b[0]*sqrt(-t[0])); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::Prf(double b_fm) const +{ + double b = b_fm / cnts->hbarc; // b in GeV^-1 + return CmplxInt(this, Amp_J0, upper_bound_t, 0., &b, precision_t) / 4. / cnts->p_cms / cnts->sqrt_s; +} diff --git a/IOMC/Elegent/elegent/src/JenkovszkyModel.cc b/IOMC/Elegent/elegent/src/JenkovszkyModel.cc new file mode 100644 index 00000000000..6640e806283 --- /dev/null +++ b/IOMC/Elegent/elegent/src/JenkovszkyModel.cc @@ -0,0 +1,137 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/JenkovszkyModel.h" +#include "interface/Constants.h" +#include "interface/Math.h" + +using namespace Elegent; + +JenkovszkyModel::JenkovszkyModel() +{ + fullLabel.name = "Jenkovszky et al."; shortLabel.name = "jenkovszky"; +} + +//---------------------------------------------------------------------------------------------------- + +void JenkovszkyModel::Configure() +{ + // set labels + fullLabel.variant = ""; shortLabel.variant = ""; + fullLabel.version = "Int. J. Mod. Phys. A 26 (2011) 4755"; shortLabel.version = "11"; + fullLabel.mode = ""; shortLabel.mode = ""; +} + +//---------------------------------------------------------------------------------------------------- + +void JenkovszkyModel::Init() +{ + // fit parameters from Table 3 (corresponding to trajectory (8)), + // reggeon trajectories given under Eq. (4) in [1] + + a_P = 261.966; + b_P = 8.40969; // GeV^-2 + de_P = 0.0504675; + al1_P = 0.436108; + ep_P = 0.0152887; + s_P = 100.; // GeV^2 + + a_O = 0.0875234; + b_O = 14.226; + de_O = 0.172615; + al1_O = 0.0434551; + s_O = 100.; // GeV^2 + + a_om = 8.21009; + b_om = 23.81201; // GeV^-2 + s_om = 1.; // GeV^2 + al0_om = 0.43; + al1_om = 0.93; + + a_f = -12.6303; + b_f = 4.35673; // GeV^-2 + s_f = 1.; // GeV^2 + al0_f = 0.70; + al1_f = 0.84; + + precision_t = 1E-4; + upper_bound_t = -50.; +} + +//---------------------------------------------------------------------------------------------------- + +void JenkovszkyModel::Print() const +{ + printf(">> JenkovszkyModel::Print\n"); + printf("\t%s\n", CompileFullLabel().c_str()); + printf("\tpomeron:\n\t\ta_P=%.3E, b_P=%.3E, de_P=%.3E, al1_P=%.3E, ep_P=%.3E, s_P=%.3E\n", a_P, b_P, de_P, al1_P, ep_P, s_P); + printf("\todderon:\n\t\ta_O=%.3E, b_O=%.3E, de_O=%.3E, al1_O=%.3E, s_O=%.3E\n", a_O, b_O, de_O, al1_O, s_O); + printf("\tomega:\n\t\ta_om=%.3E, b_om=%.3E, s_om=%.3E, al0_om=%.3E, al1_om=%.3E\n", a_om, b_om, s_om, al0_om, al1_om); + printf("\tf:\n\t\ta_f=%.3E, b_f=%.3E, s_f=%.3E, al0_f=%.3E, al1_f=%.3E\n", a_f, b_f, s_f, al0_f, al1_f); + printf("\tupper_bound_t=%.3E, precision_t=%.3E\n", upper_bound_t, precision_t); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex JenkovszkyModel::Amp(double t) const +{ + double s_eff = 0.; + + // pomeron + s_eff = cnts->s / s_P; + double al_P = 1. + de_P + al1_P*t; // TR.1 + TComplex r_1_sq = b_P + log(s_eff) - i*M_PI/2.; + TComplex r_2_sq = log(s_eff) - i*M_PI/2.; + TComplex A_P = i * a_P/b_P * s_eff * ( + r_1_sq * TComplex::Exp(r_1_sq * (al_P - 1.)) + - ep_P * r_2_sq * TComplex::Exp(r_2_sq * (al_P - 1.)) + ); + + // odderon + s_eff = cnts->s / s_O; + double al_O = 1. + de_O + al1_O*t; // TR.1 + TComplex rO_1_sq = b_O + log(s_eff) - i*M_PI/2.; + // NB: wrong sign in Eq (8) in arXiv: 1105.1202v1 + TComplex A_O = - a_O/b_O * s_eff * ( + rO_1_sq * TComplex::Exp(rO_1_sq * (al_O - 1.)) + ); + + if (cnts->pMode == cnts->mPP) + A_O = -A_O; + + // omega + s_eff = cnts->s / s_om; + double al_om = al0_om + al1_om*t; + TComplex A_om = a_om * TComplex::Exp(-i*M_PI/2. * al_om + b_om*t) * pow(s_eff, al_om); + + if (cnts->pMode == cnts->mPP) + A_om = -A_om; + + // f + s_eff = cnts->s / s_f; + double al_f = al0_f + al1_f*t; + TComplex A_f = a_f * TComplex::Exp(-i*M_PI/2. * al_f + b_f*t) * pow(s_eff, al_f); + + //printf("%E | %E, %E | %E, %E\n", t, A_P.Re(), A_P.Im(), A_O.Re(), A_O.Im()); + + return cnts->p_cms/cnts->sqrt_s * (A_P + A_O + A_om + A_f); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex JenkovszkyModel::Amp_J0(double *t, double *b, const void *obj) +{ + /// t[0] ... t in GeV^2 + /// b[0] ... impact parameter in fm + return ((JenkovszkyModel *)obj)->Amp(t[0]) * TMath::BesselJ0(b[0] * sqrt(-t[0])); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex JenkovszkyModel::Prf(double b_fm) const +{ + double b = b_fm / cnts->hbarc; // b in GeV^-1 + return CmplxInt(this, Amp_J0, upper_bound_t, 0., &b, precision_t) / 4. / cnts->p_cms / cnts->sqrt_s; +} diff --git a/IOMC/Elegent/elegent/src/Math.cc b/IOMC/Elegent/elegent/src/Math.cc new file mode 100644 index 00000000000..be829d8590f --- /dev/null +++ b/IOMC/Elegent/elegent/src/Math.cc @@ -0,0 +1,212 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/Math.h" + +namespace Elegent +{ + +double DoubleInt(const void *obj, double (*fcn)(double*, double*, const void*), double a, double b, double *params, double epsilon) +{ + const double Z1 = 1; + const double HF = Z1/2; + const double CST = 5*Z1/1000; + + double x[12] = { 0.96028985649753623, 0.79666647741362674, + 0.52553240991632899, 0.18343464249564980, + 0.98940093499164993, 0.94457502307323258, + 0.86563120238783174, 0.75540440835500303, + 0.61787624440264375, 0.45801677765722739, + 0.28160355077925891, 0.09501250983763744}; + + double w[12] = { 0.10122853629037626, 0.22238103445337447, + 0.31370664587788729, 0.36268378337836198, + 0.02715245941175409, 0.06225352393864789, + 0.09515851168249278, 0.12462897125553387, + 0.14959598881657673, 0.16915651939500254, + 0.18260341504492359, 0.18945061045506850}; + + double h, aconst, bb, aa, c1, c2, u, s8, s16, f1, f2; + double xx[1]; + int i; + + h = 0; + if (b == a) return h; + + aconst = CST/TMath::Abs(b-a); + bb = a; + + CASE1: + aa = bb; + bb = b; + + CASE2: + c1 = HF*(bb+aa); + c2 = HF*(bb-aa); + + s8 = 0; + for (i=0; i<4; i++) { + u = c2*x[i]; + xx[0] = c1+u; + f1 = (*fcn)(xx, params, obj); + xx[0] = c1-u; + f2 = (*fcn)(xx, params, obj); + s8 += w[i]*(f1 + f2); + } + + s16 = 0; + for (i=4; i<12; i++) { + u = c2*x[i]; + xx[0] = c1+u; + f1 = (*fcn)(xx, params, obj); + xx[0] = c1-u; + f2 = (*fcn)(xx, params, obj); + s16 += w[i]*(f1 + f2); + } + + s16 = c2*s16; + + if (TMath::Abs(s16-c2*s8) <= epsilon*(1. + TMath::Abs(s16))) { + h += s16; + if(bb != b) goto CASE1; + } else { + bb = c1; + if(1. + aconst*TMath::Abs(c2) != 1) goto CASE2; + h = s8; //this is a crude approximation (cernlib function returned 0 !) + printf("WARNING in DoubleInt > Crude approximation.\n"); + } + + return h; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex CmplxInt(const void *obj, TComplex (*fcn)(double*, double*, const void *), double a, double b, double *params, double epsilon) +{ + TComplex C; + + const double Z1 = 1; + const double HF = Z1/2; + const double CST = 5*Z1/1000; + + double x[12] = { 0.96028985649753623, 0.79666647741362674, + 0.52553240991632899, 0.18343464249564980, + 0.98940093499164993, 0.94457502307323258, + 0.86563120238783174, 0.75540440835500303, + 0.61787624440264375, 0.45801677765722739, + 0.28160355077925891, 0.09501250983763744}; + + double w[12] = { 0.10122853629037626, 0.22238103445337447, + 0.31370664587788729, 0.36268378337836198, + 0.02715245941175409, 0.06225352393864789, + 0.09515851168249278, 0.12462897125553387, + 0.14959598881657673, 0.16915651939500254, + 0.18260341504492359, 0.18945061045506850}; + + double aconst, bb, aa, c1, c2, u; + double xx[1]; + int i; + + if (b == a) return TComplex(0., 0.); + + // REAL + double Rh, Rs8, Rs16, Rf1, Rf2; + + Rh = 0; + aconst = CST/TMath::Abs(b-a); + bb = a; + + CASE1: + aa = bb; + bb = b; + + CASE2: + c1 = HF*(bb+aa); + c2 = HF*(bb-aa); + + Rs8 = 0; + for (i=0; i<4; i++) { + u = c2 * x[i]; + xx[0] = c1 + u; + C = (*fcn)(xx, params, obj); Rf1 = C.Re(); + xx[0] = c1 - u; + C = (*fcn)(xx, params, obj); Rf2 = C.Re(); + Rs8 += w[i]*(Rf1 + Rf2); + } + + Rs16 = 0; + for (i=4; i<12; i++) { + u = c2 * x[i]; + xx[0] = c1 + u; + C = (*fcn)(xx, params, obj); Rf1 = C.Re(); + xx[0] = c1 - u; + C = (*fcn)(xx, params, obj); Rf2 = C.Re(); + Rs16 += w[i]*(Rf1 + Rf2); + } + + Rs16 = c2*Rs16; + + if (TMath::Abs(Rs16 - c2*Rs8) <= epsilon*(1. + TMath::Abs(Rs16))) { + Rh += Rs16; + if(bb != b) goto CASE1; + } else { + bb = c1; + if (1. + aconst*TMath::Abs(c2) != 1) goto CASE2; + Rh = Rs8; // this is a crude approximation (cernlib function returned 0 !) + printf("WARNING in CmplxInt (real part) > Crude approximation.\n"); + } + + // IMAGINARY + double Ih, Is8, Is16, If1, If2; + + Ih = 0; + aconst = CST/TMath::Abs(b-a); + bb = a; + + CASE1I: + aa = bb; + bb = b; + + CASE2I: + c1 = HF*(bb+aa); + c2 = HF*(bb-aa); + + Is8 = 0; + for (i=0; i<4; i++) { + u = c2 * x[i]; + xx[0] = c1 + u; + C = (*fcn)(xx, params, obj); If1 = C.Im(); + xx[0] = c1 - u; + C = (*fcn)(xx, params, obj); If2 = C.Im(); + Is8 += w[i]*(If1 + If2); + } + + Is16 = 0; + for (i=4; i<12; i++) { + u = c2 * x[i]; + xx[0] = c1 + u; + C = (*fcn)(xx, params, obj); If1 = C.Im(); + xx[0] = c1 - u; + C = (*fcn)(xx, params, obj); If2 = C.Im(); + Is16 += w[i]*(If1 + If2); + } + + Is16 = c2*Is16; + + if (TMath::Abs(Is16 - c2*Is8) <= epsilon*(1. + TMath::Abs(Is16))) { + Ih += Is16; + if(bb != b) goto CASE1I; + } else { + bb = c1; + if (1. + aconst*TMath::Abs(c2) != 1) goto CASE2I; + Ih = Is8; + printf("WARNING in CmplxInt (imaginary part) > Crude approximation.\n"); + } + + // put it together + return TComplex(Rh, Ih); +} + +} // namespace diff --git a/IOMC/Elegent/elegent/src/Model.cc b/IOMC/Elegent/elegent/src/Model.cc new file mode 100644 index 00000000000..853cb756e80 --- /dev/null +++ b/IOMC/Elegent/elegent/src/Model.cc @@ -0,0 +1,49 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/Model.h" + +using namespace std; + +namespace Elegent +{ + +string Model::CompileShortLabel() const +{ + string out = shortLabel.name; + + if (!shortLabel.mode.empty() && shortLabel.mode.compare("full")) + out += ":" + shortLabel.mode; + + if (!shortLabel.variant.empty()) + out += " (" + shortLabel.variant + ")"; + + out += " [" + shortLabel.version + "]"; + + return out; +} + +//---------------------------------------------------------------------------------------------------- + +string Model::CompileFullLabel() const +{ + string out = fullLabel.name; + + if (!fullLabel.mode.empty() && fullLabel.mode.compare("full")) + out += ":" + fullLabel.mode; + + if (!fullLabel.variant.empty()) + out += " (" + fullLabel.variant + ")"; + + out += " [" + fullLabel.version + "]"; + + return out; +} + +//---------------------------------------------------------------------------------------------------- + +Model *model = NULL; + +} diff --git a/IOMC/Elegent/elegent/src/ModelFactory.cc b/IOMC/Elegent/elegent/src/ModelFactory.cc new file mode 100644 index 00000000000..1c8e91c6e70 --- /dev/null +++ b/IOMC/Elegent/elegent/src/ModelFactory.cc @@ -0,0 +1,79 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/ModelFactory.h" + +using namespace std; + +namespace Elegent +{ + +ModelFactory::ModelFactory() +{ + IslamModel *islam_hp = new IslamModel(); + islam_hp->Configure(IslamModel::vHP, IslamModel::mFull); + model_map[islam_hp->CompileShortLabel()] = islam_hp; + + IslamModel *islam_lxg = new IslamModel(); + islam_lxg->Configure(IslamModel::vLxG, IslamModel::mFull); + model_map[islam_lxg->CompileShortLabel()] = islam_lxg; + + PPPModel *ppp2 = new PPPModel(); + ppp2->Configure(PPPModel::v2P); + model_map[ppp2->CompileShortLabel()] = ppp2; + + PPPModel *ppp3 = new PPPModel(); + ppp3->Configure(PPPModel::v3P); + model_map[ppp3->CompileShortLabel()] = ppp3; + + BSWModel *bsw = new BSWModel(); + bsw->Configure(BSWModel::mPomReg); + model_map[bsw->CompileShortLabel()] = bsw; + + BHModel *bh = new BHModel(); + bh->Configure(); + model_map[bh->CompileShortLabel()] = bh; + + JenkovszkyModel *jenkovszky = new JenkovszkyModel(); + jenkovszky->Configure(); + model_map[jenkovszky->CompileShortLabel()] = jenkovszky; +} + +//---------------------------------------------------------------------------------------------------- + +void ModelFactory::PrintList() const +{ + printf(">> ModelFactory::PrintList > available models:\n"); + + for (map::const_iterator it = model_map.begin(); it != model_map.end(); ++it) + { + printf("\t%s : %s\n", it->first.c_str(), it->second->CompileFullLabel().c_str()); + } +} + +//---------------------------------------------------------------------------------------------------- + +Model* ModelFactory::MakeInstance(const std::string &tag, bool callInit) const +{ + // look for tag in model map + map::const_iterator it = model_map.find(tag); + Model* model = (it == model_map.end()) ? NULL : it->second; + + // if not found print all possibilities + if (model == NULL) + { + printf("ERROR in ModelFactory::MakeInstance: model tag `%s' not available\n", tag.c_str()); + PrintList(); + return NULL; + } + + // initialise model + if (callInit) + model->Init(); + + return model; +} + +} // namespace diff --git a/IOMC/Elegent/elegent/src/PPPModel.cc b/IOMC/Elegent/elegent/src/PPPModel.cc new file mode 100644 index 00000000000..939b53b622c --- /dev/null +++ b/IOMC/Elegent/elegent/src/PPPModel.cc @@ -0,0 +1,154 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/PPPModel.h" +#include "interface/Math.h" +#include "interface/Constants.h" + +using namespace std; +using namespace Elegent; + +//---------------------------------------------------------------------------------------------------- + +PPPModel::PPPModel() +{ + fullLabel.name = "Petrov et al."; shortLabel.name = "petrov"; +} + +//---------------------------------------------------------------------------------------------------- + +void PPPModel::Configure(PPPModel::VariantType _v) +{ + variant = _v; + + if (variant == v2P) + { + fullLabel.variant = "2P"; shortLabel.variant = "2p"; + } + + if (variant == v3P) + { + fullLabel.variant = "3P"; shortLabel.variant = "3p"; + } + + if (variant != v2P && variant != v3P) + printf("ERROR in PPPModel::Init > Unknown variant %u.\n", variant); + + // set labels + fullLabel.version = "Eur. Phys. J. C23 (2002) 135-143"; shortLabel.version = "02"; + fullLabel.mode = ""; shortLabel.mode = ""; +} + +//---------------------------------------------------------------------------------------------------- + +void PPPModel::SetTrajectory(Trajectory &t, double D, double c, double ap, double r2, double s0) +{ + t.D = D; t.c = c; t.ap = ap; t.r2 = r2; + + // now pre-compute rho2 and gamma factor + // physics must be already intialized !!! + t.rho2 = 4. * t.ap * log(cnts->s/s0) + t.r2; + t.gamma = t.c / s0 * TComplex::Power(-i * cnts->s/s0, t.D); +} + +//---------------------------------------------------------------------------------------------------- + +void PPPModel::Init() +{ + // physics parameters + s0 = 1.; // in GeV^2 + + // Delta c a' r^2 + // 1 1 GeV^2 GeV^2 + if (variant == v2P) + { + // two pomerons + SetTrajectory(pom1, 0.08590, 53.18, 0.360, 9.595, s0); + SetTrajectory(pom2, 0.14437, 6.87, 0.082, 4.765, s0); + SetTrajectory(oder, -0.2707, 1.8134, 0.029, 1.159, s0); + SetTrajectory(regf, -0.3100, 188.51, 0.84, 41.424, s0); + SetTrajectory(rego, -0.5300, -171.36, 0.93, 2.621, s0); + } + + if (variant == v3P) + { + // three pomerons + SetTrajectory(pom1, 0.0578, 53.007, 0.5596, 6.3096, s0); + SetTrajectory(pom2, 0.1669, 9.6762, 0.2733, 3.1097, s0); + SetTrajectory(pom3, 0.2032, 1.6654, 0.0937, 2.4771, s0); + SetTrajectory(oder, 0.1920, 0.0166, 0.048, 0.1398, s0); + SetTrajectory(regf, -0.31, 191.69, 0.84, 31.593, s0); + SetTrajectory(rego, -0.53, -174.18, 0.93, 7.467, s0); + } + + // integration parameters + precision = 1E-14; + upper_bound = 60.; +} + +//---------------------------------------------------------------------------------------------------- + +void PPPModel::Print() const +{ + printf(">> PPPModel::Print\n"); + printf("\t%s\n", CompileFullLabel().c_str()); + printf("\tvariant: %u\n", variant); + + printf("\tpom1: delta=%.4f, c=%.4f, a'=%.4f, r^2=%.4f\n", pom1.D, pom1.c, pom1.ap, pom1.r2); + printf("\tpom2: delta=%.4f, c=%.4f, a'=%.4f, r^2=%.4f\n", pom2.D, pom2.c, pom2.ap, pom2.r2); + if (variant == v3P) + printf("\tpom3: delta=%.4f, c=%.4f, a'=%.4f, r^2=%.4f\n", pom3.D, pom3.c, pom3.ap, pom3.r2); + printf("\toder: delta=%.4f, c=%.4f, a'=%.4f, r^2=%.4f\n", oder.D, oder.c, oder.ap, oder.r2); + printf("\tregf: delta=%.4f, c=%.4f, a'=%.4f, r^2=%.4f\n", regf.D, regf.c, regf.ap, regf.r2); + printf("\trego: delta=%.4f, c=%.4f, a'=%.4f, r^2=%.4f\n", rego.D, rego.c, rego.ap, rego.r2); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex PPPModel::tr_eik(Trajectory t, double , double b) const +{ + // delta+-(s, b) ... eq (11), (12) without the leading i + // the s-dependence is now computed during initialization + // therefore any cnts->s change after init() won't have any affect + return t.gamma * exp(- b * b / t.rho2) / (4. * cnts->pi * t.rho2); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex PPPModel::prf0(double b) const +{ + TComplex delta = i*tr_eik(pom1, cnts->s, b) + i*tr_eik(pom2, cnts->s, b) + i*tr_eik(regf, cnts->s, b); + + if (cnts->pMode == cnts->mPP) + delta += tr_eik(oder, cnts->s, b) + tr_eik(rego, cnts->s, b); + else + delta -= tr_eik(oder, cnts->s, b) + tr_eik(rego, cnts->s, b); + + if (variant == v3P) + delta += i*tr_eik(pom3, cnts->s, b); + + return (TComplex::Exp(2.*i*delta) - 1.) / 2. / i; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex PPPModel::Prf(double b) const +{ + return prf0(b / cnts->hbarc); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex PPPModel::prf_J0(double *b, double *t, const void *obj) +{ + return ((PPPModel *)obj)->prf0(b[0]) * b[0] * TMath::BesselJ0(b[0] * sqrt(-t[0])); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex PPPModel::Amp(double t) const +{ + return 2.*cnts->p_cms*cnts->sqrt_s * CmplxInt(this, prf_J0, 0, upper_bound, &t, precision); +} diff --git a/IOMC/Elegent/elegent/test/package_test b/IOMC/Elegent/elegent/test/package_test new file mode 100755 index 00000000000..f5a9b4da14f --- /dev/null +++ b/IOMC/Elegent/elegent/test/package_test @@ -0,0 +1,42 @@ +#!/bin/bash + +# ----------------------- print available models ----------------------- + +# works with B and S-DistributionSampler as well +../bin/ElegentTDistributionSampler -model-list + + + +# -------------------- test t-distribution sampling -------------------- + +../bin/ElegentTDistributionSampler -h +../bin/ElegentTDistributionSampler\ + -energy 7000 -pp -models "petrov (3p) [02]" -output "t-distribution_test.root"\ + -model-N 100 -model-tmax 20\ + -full-N 50 -full-tmax 10\ + -lowt-N 50 -lowt-tmax 1 + + + +# -------------------- test b-distribution sampling -------------------- + +../bin/ElegentBDistributionSampler -h +../bin/ElegentBDistributionSampler\ + -energy 7000 -pp -models "petrov (3p) [02]" -output "b-distribution_test.root"\ + -N 100 -bmin 0 -bmax 10 + + + +# -------------------- test s-distribution sampling -------------------- + +../bin/ElegentSDistributionSampler -h +../bin/ElegentSDistributionSampler\ + -pp -models "petrov (3p) [02]" -output "s-distribution_test.root"\ + -N 100 -Wmin 2 -Wmax "1E5" + + + +# ------------------ test Monte-Carlo event generator ------------------ + +../bin/ElegentTest -h +../bin/ElegentTest "t-distribution_test.root" "full range/petrov (3p) [02]/PH/cumulative cross-section" 0 10 3 diff --git a/IOMC/Elegent/interface/BHModel.h b/IOMC/Elegent/interface/BHModel.h new file mode 100644 index 00000000000..4afd7d38234 --- /dev/null +++ b/IOMC/Elegent/interface/BHModel.h @@ -0,0 +1,72 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_bh_model_ +#define _elegent_bh_model_ + +#include "Model.h" + +namespace Elegent +{ + +/** + * \brief Block-Halzen model of p-p and p-anti p elastic scattering. + * References: + * [1] BLOCK, M. M., GREGORES, E. M., HALZEN, F. and PANCHERI, G., Phys. Rev. D60 (1999) 054024 + * [2] BLOCK, M. M., Phys. Rept. 436 (2006) 71-215 + **/ +class BHModel : public Model +{ + public: + BHModel(); + + void Configure(); + virtual void Init(); + virtual void Print() const; + virtual TComplex Amp(double t) const; + virtual TComplex Prf(double b) const; + + protected: + /// common parameters + double m0, s0, al_s, Sigma_gg; + + /// parameters for sigma_gg + double Cp_gg, epsilon, Ng; + std::vector a, b; + + /// parameters for sigma_gg + double C_qg_log; + + /// parameters for sigma_qg + double C, C_even_regge; + + /// parameters for sigma_qq + double C_odd; + + /// effective areas + double mu_gg, mu_qg, mu_qq, mu_odd; + + /// the integral cross-sections + TComplex sigma_gg, sigma_qq, sigma_qg, sigma_odd; + + /// integration parameters + double precision, upper_bound; + + /// profile defined by Eq. (B2) in [1] + double W(double b, double mi) const; + + /// sum in Eq. (B5) in [1] + TComplex Sum(double s) const; + + /// the full eikonal: Eq. (1) without the leading factor i and Eq. (12) + TComplex chi_without_i(double b) const; + + TComplex prf0(double b) const; + static TComplex prf0_J0(double *y, double *t, const void *obj); +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/interface/BSWModel.h b/IOMC/Elegent/interface/BSWModel.h new file mode 100644 index 00000000000..386f3152707 --- /dev/null +++ b/IOMC/Elegent/interface/BSWModel.h @@ -0,0 +1,128 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_bsw_model_ +#define _elegent_bsw_model_ + +#include "Model.h" + +#include + +//#define DEBUG + +namespace Elegent +{ + +/** + * \brief Bourelly, Soffer and Wu model of p-p and p-anti p elastic scattering. + * References: + * [1] BOURRELY C., SOFFER, J. and WU, T. T., Phys. Rev. D19 (1979) 3249 + * [2] BOURRELY C., SOFFER, J. and WU, T. T., Nucl. Phys. B247 (1984) 15 + * [3] BOURRELY C., SOFFER, J. and WU, T. T., Eur. Phys. J. C28 (2003) 97-105 + * [4] BOURRELY C., SOFFER, J. and WU, T. T., Eur. Phys. J. C71 (2011) 1601 + **/ +class BSWModel : public Model +{ + public: + /// a Regge trajectory + struct Trajectory + { + double C, b, a, ap, sig; + void Init(double _C, double _b, double _a, double _ap, double _sig) + { C=_C; b=_b; a=_a; ap=_ap; sig = _sig; } + }; + + /// available modes + enum ModeType + { + mPomReg, ///< both Pomeron and Reggeon contributions + mPom, ///< only Pomeron contribution + mReg ///< only Reggeon contribution + } mode; + + BSWModel(); + + ~BSWModel() {} + + /// the Pom+Reg mode still broken + void Configure(ModeType _mode = mPomReg, bool _presampled = true); + + virtual void Init(); + + virtual void Print() const; + + virtual TComplex Amp(double t) const; + virtual TComplex Prf(double b) const; + + public: + /// flag whether the presampled mode is on + bool presampled; + + /// accuracy level (use true for differential cross-section, false is sufficient for total cross-section) + bool highAccuracy; + + /// the pomeron exchange parameters + double c, cp, a, f, m1, m2, asq, m1sq, m2sq; + + /// the 3 Regge trajectories + Trajectory A2, rho, omega; + + /// temporary constants: Omega0 = S0*F + R0 / s / regge_fac; + TComplex regge_fac; + + double upper_bound_t, precision_t; + double upper_bound_b, precision_b; + + /// \tilde F(t), Eq. (4) + double Ft(double t) const; + + /// generic Regge trajectory amplitude, Eq. (7) + TComplex Rt(Trajectory tr, double t) const; + + /// the sum of allowed Regge trajctories (A2, rho, omega) + TComplex R0t(double t) const; + + /// S_0(s), Eq(3) + TComplex S0(double t) const; + + /// S_0(0) + TComplex S00; + + /// the Bessel transform of \Omega_0(s, b) in Eq. (2) + TComplex Omega0t(double t) const; + + static TComplex Omega0t_J0(double *t, double *b, const void *obj); + + /// \Omega_0(s, b) + TComplex Omega0b(double b) const; + + /// the profile function with b in GeV^-1 + TComplex prf0(double b) const; + + static TComplex prf0_J0(double *b, double *q, const void *obj); + + /// the sampling-step size + double data_db; + + /// the number of sampled points + unsigned int data_N; + + /// the sampled real and imaginary values of prf0(b) + std::vector data_re, data_im; + +#ifdef DEBUG + std::vector data_b; +#endif + + /// samples the prf0 function + void BuildSample(unsigned int samples); + + /// interpolates (linearly) the sample at point b + TComplex SampleEval(double b); +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/interface/Constants.h b/IOMC/Elegent/interface/Constants.h new file mode 100644 index 00000000000..8703f7f40a3 --- /dev/null +++ b/IOMC/Elegent/interface/Constants.h @@ -0,0 +1,66 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_constants_ +#define _elegent_constants_ + +#include "TComplex.h" + +namespace Elegent +{ + +/** + *\brief Set of constants used in Elegent calculations. + **/ +struct Constants +{ + // physics constants + static double alpha; ///< fine structure constant + static double proton_mass; ///< GeV + static double neutron_mass; ///< GeV + static double hbarc; ///< GeV * fm + static double sq_hbarc; ///< GeV^2 * mbarn + ///< sigma/mbarn = sigma/GeV^-2 * sq_hbarc + static double M; ///< abbreviation for proton mass in GeV + static double M_sq; ///< proton mass squared, GeV^2 + static double kappa; ///< the anomalous magnetic moment of proton + + // mathematics constants + static double pi; ///< pi + static double gamma; ///< Euler's constant + + // physics data + double sqrt_s; ///< sqrt_s / GeV + double s; ///< s / GeV^2 + double ln_s; ///< ln(s / GeV^2) + double p_cms; ///< particle CMS impuls + double sig_fac; ///< d sig/dt = sig_fac * |A|^2 + double t_min; ///< negative + + enum ParticleMode {mPP, mAPP} pMode; ///< particle mode + + /// \param W = sqrt(s) + Constants(double W = 0., ParticleMode mode = mPP) + { + Configure(W, mode); + } + + void Configure(double W, ParticleMode mode); + + /// \brief initilize new instance of Constants and save its pointer to the `cnts' global variable + /// \param W = sqrt(s) + static void Init(double W, ParticleMode mode); + + /// print the actual values + void Print(); +}; + + +extern TComplex i; +extern Constants *cnts; + +} // namespace + +#endif diff --git a/IOMC/Elegent/interface/CoulombInterference.h b/IOMC/Elegent/interface/CoulombInterference.h new file mode 100644 index 00000000000..5ba4d2bb398 --- /dev/null +++ b/IOMC/Elegent/interface/CoulombInterference.h @@ -0,0 +1,173 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_coulomb_ +#define _elegent_coulomb_ + +#include "Model.h" + +namespace Elegent +{ + +/** + * \brief Coulomb hadron interference for elastic scattering. + **/ +class CoulombInterference +{ + public: + /// the mode of coulomb interference + enum CIMode + { + mPC, ///< pure electromagnetic amplitude (Born/OPE approximation) [default] + mPH, ///< pure hadronic amplitude + mWY, ///< WY formula + mSWY, ///< simplified WY formula + mKL ///< (corrected) KL formula (includes the one of Cahn) + } mode; + + std::string GetModeString() const; + + /// form factor type + enum FFType + { + ffNone, ///< form factor = 1 + ffDipole, ///< dipole form factor, in G_eff, G_E and G_M (G_M(0) = 1) + ffHofstadter, ///< Hofstader et al.: Rev. Mod. Phys. 30 (1958) + ffBorkowski, ///< Borkowski et al.: Nucl. Phys. B93 (1975) + ffKelly, ///< Kelly: Phys. Rev. C70 (2004) + ffArrington, ///< Arrington et al.: Phys. Rev C76 (2007) + ffPuckett, ///< Puckett et al.: arXiv 1008.0855v1 [default] + ffPuckettEl ///< only electric form-factor of Puckett et al. + } ffType; + + CoulombInterference(); + + double GetT() + { return T; } + + /// the size of the region around t=t' which is cut off from integration, see B_term method + double tau; + + /// the upper bound of the integration in A_term and B_term is |t|+T + double T; + + /// precision of the integration + double precision; + + /// print the parameters + void Print() const; + + protected: + /// the integrand of I(t, t') integral + static double I_integrand(double *phi, double *par, const void *obj); + + /// the integrand of the A term + static double A_integrand(double *tt, double *t, const void *obj); + + /// the integrand of the B term + static TComplex B_integrand(double *tt, double *par, const void *obj); + + public: + /// A: $\int_{t_{min}}^0 \log(t'/t) * d/dt(FF^2(t'))$ + /// \par t in GeV^2, negative + double A_term(double t) const; + + double I_integral(double t, double tp) const; + + /// B: ${1 / 2\pi} \int_{t_{min}}^0 [ F^N(t') / F^N(t) - 1] I(t, t')$ + /// \par t in GeV^2, negative + TComplex B_term(double t) const; + + /// C: the correction for non-vanishing form factors at t_min + /// $FF^2(t_{min} \log(t/t_{min}))$ + /// \par t in GeV^2, negative + double C_term(double t) const; + + //-------------------- form factors -------------------- + + public: + std::string GetFFName() const; + + /// dipole form factor + double FF_dipole(double t) const; + + /// eletric form factor + /// normalized such FF_e(0) = 1, t negative + double FF_e(double t) const; + + /// magnetic form factor + /// normalized such FF_m(0) = 1, t negative + double FF_m(double t) const; + + /// square of the effective form factor + /// \par t in GeV^2, negative + double FF_sq(double t) const; + + /// d/dt of the effective form factor square + /// \par t in GeV^2, negative + double FF_sq_prime(double t) const + { + double ep = 1E-5; + return (FF_sq(t + ep) - FF_sq(t)) / ep; + } + + //-------------------- interference phases -------------------- + + /// full West-Yennie phase (with alpha factor) + /// that is the $\alpha\Phi$ in the decomposition $F^{C+H} = F^C e^{i \alpha \Phi} + F^H$ + /// \par t in GeV^2, negative + TComplex Phi_WY(double t) const; + + /// simplified West-Yennie phase + TComplex Phi_SWY(double t) const; + + /// Kundrat-Lokajicek phase (with alpha factor) + /// that is the $\alpha\Phi$ in the decomposition $F^{C+H} = F^C + F^H * e^{i \alpha \Psi}$ + /// \par t in GeV^2, negative + TComplex Psi_KL(double t) const; + + ///\brief the interference phase WITH the alpha factor + /// returns either $-\Phi$ or $\Psi$ + /// \par t in GeV^2, negative + TComplex Phase(double t) const; + + //-------------------- amplitudes -------------------- + + /// pure Coulomb amplitude (PC) + /// \par t in GeV^2, negative + TComplex Amp_pure(double t) const; + + TComplex Amp_WY(double t) const; + TComplex Amp_SWY(double t) const; + TComplex Amp_KL(double t) const; + + /// total Amplitude according to the choice in `mode' + TComplex Amp(double t) const; + + //-------------------- standard quantities -------------------- + + /// ratio (|KL|^2 - |WY|^2) / |KL|^2 + /// \par t in GeV^2, negative + TComplex R(double t) const; + + /// for |t| < |cutoff|: (|KL|^2 - |WY|^2) / |KL|^2, otherwise (|KL|^2 - |PH|^2) / |KL|^2 + /// \par t in GeV^2, negative + /// \par cutoff in GeV^2, negative + TComplex R_with_cutoff(double t, double cutoff) const; + + /// ratio (|KL|^2 - |PH|^2 - |PC|^2) / |KL|^2 + /// \par t in GeV^2, negative + TComplex Z(double t) const; + + /// ratio (|KL|^2 - |PH|^2) / |PH|^2 + /// \par t in GeV^2, negative + TComplex C(double t) const; +}; + +extern CoulombInterference *coulomb; + +} // namespace + +#endif diff --git a/IOMC/Elegent/interface/ExpModel.h b/IOMC/Elegent/interface/ExpModel.h new file mode 100644 index 00000000000..baaa7b6ea2b --- /dev/null +++ b/IOMC/Elegent/interface/ExpModel.h @@ -0,0 +1,36 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_exp_model_ +#define _elegent_exp_model_ + +#include "Model.h" + +namespace Elegent +{ + +/** + * \brief Exponential model of p-p and p-anti p elastic scattering. + * amplitude(t) = a * exp( b1*t + b2*t*t + i*(p0 + p1*t) ) + * For reference pourposes only. + **/ +class ExpModel : public Model +{ + public: + ExpModel(); + + void Configure(); + virtual void Init(); + virtual void Print() const; + virtual TComplex Amp(double t) const; + virtual TComplex Prf(double b) const; + + public: + double a, b1, b2, p0, p1; +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/interface/Generator.h b/IOMC/Elegent/interface/Generator.h new file mode 100644 index 00000000000..62a924c0bed --- /dev/null +++ b/IOMC/Elegent/interface/Generator.h @@ -0,0 +1,69 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_elegent_ +#define _elegent_elegent_ + +#include + +class TGraph; + +namespace HepMC { + class GenEvent; +} + +namespace Elegent +{ + +/** + * \brief MC generator of proton-proton elastic scattering events. + * All internal quantities are in GeV or in mm. + **/ +class Generator +{ + public: + Generator(const std::string &_file, const std::string &_path, double _t_min, double _t_max, unsigned int _verbosity=1); + ~Generator() {} + + unsigned int Init(); + + static const int PID = 2212; + static const int ElasticScattering = 91; + static const int FinalState = 1; + static const int NullState = 0; + + protected: + /// name of file containing the cumulative distribution function (CDF) + std::string fileName; + + /// path of the (CDF) within the file + std::string modelPath; + + /// |t| values in GeV^2, bounds for CDF + double t_min, t_max; + + /// verbosity level (0 = no, 1 = normal, 2 = debug) + unsigned int verbosity; + + /// [GeV] cms (one) proton energy + double E_cms; + + /// [GeV] cms proton momentum + double p_cms; + + /// graph with inverse c.d.f. + TGraph *icdf; + + public: + /// generates one event provided two random numbers with uniform distribution on (0, 1) + void GenerateBase(double rn1, double rn2, HepMC::GenEvent* gE); + + /// generates one event, using ROOT random number generator TRandom2 + void Generate(HepMC::GenEvent* gE); +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/interface/InterpolationModel.h b/IOMC/Elegent/interface/InterpolationModel.h new file mode 100644 index 00000000000..23372f831d4 --- /dev/null +++ b/IOMC/Elegent/interface/InterpolationModel.h @@ -0,0 +1,84 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_interpolation_model_ +#define _elegent_interpolation_model_ + +#include "Model.h" + +#include + +class TGraph; + +namespace Elegent +{ + +/** + * \brief Model that interpolates stored amplitude points. + **/ +class InterpolationModel : public Model +{ + public: + /// number of points (samples) + unsigned int N; + + /// the lower boundary + double t_min; + + /// the upper boundary + double t_max; + + /// the t interval between two adjacent (equidistant) points + double dt; + + /// amplitude samples + std::vector amp_data; + + public: + InterpolationModel(unsigned int _N, double _t_min, double _t_max); + + virtual ~InterpolationModel(); + + void Configure(); + + virtual void Init() {} + + virtual void Print() const; + + /// amplitude, t in GeV^-2, t < 0 + virtual TComplex Amp(double t) const + { + double f = (t - t_min) / dt; + unsigned int idx = (unsigned int) f; + + if (idx + 1 > N - 1) + { + if (fabs(t - t_max) < 1E-10) + return amp_data[N-1]; + return TComplex(0, 0); + } + + f -= idx; + + return amp_data[idx] + (amp_data[idx+1] - amp_data[idx]) * f; + } + + virtual TComplex Prf(double b) const; + + /// returns the value of t corresponding to the point with index `idx' (between 0 and N-1 inclusively) + inline double GetT(unsigned int idx) const + { + return t_min + dt * idx; + } + + inline void SetPoint(unsigned int idx, const TComplex &v) + { + amp_data[idx] = v; + } +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/interface/IslamModel.h b/IOMC/Elegent/interface/IslamModel.h new file mode 100644 index 00000000000..8af3f91b32f --- /dev/null +++ b/IOMC/Elegent/interface/IslamModel.h @@ -0,0 +1,121 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_islam_model_ +#define _elegent_islam_model_ + +#include "Model.h" + +namespace Elegent +{ + + +/** + * \brief Islam model of p-p and p-anti p elastic scattering. + * References: + * [1] ISLAM, M. M., FEARNLEY, T. and GUILLAUD, J. P., Nuovo Cim. A81 (1984) 737 + * [2] ISLAM, M. M., INNOCENTE V., FEARNLEY T. and SANGUIETTI, G., Europhys. Lett. 4 (1987) 189-196 + * [3] ISLAM, M. M., LUDDY, R. J. and PROKUDIN, A. V., Phys. Lett. B605 (2005) 115-122 + * [4] ISLAM, M. M., LUDDY, R. J. and PROKUDIN, A. V., Int. J. Mod. Phys. A21 (2006) 1-42 + * [5] ISLAM, M. M., KASPAR, J. and LUDDY, R. J., Mod. Phys. Lett. A24 (2009) 485-496 + **/ +class IslamModel : public Model +{ + public: + /// variant of the model + enum VariantType + { + vHP, ///< hard Pomeron + vLxG ///< low-x gluons + } variant; + + /// mode of the model + enum ModeType + { + mDiff, ///< diffraction amplitude + mCore, ///< core amplitude + mQuark, ///< quark-quark amplitude + mDiffCore, ///< diffraction and core amplitude + mFull ///< diffraction, core and quark-quark amplitude + } mode; + + IslamModel(); + + void Configure(VariantType _v, ModeType _m); + + virtual void Init(); + + static TComplex CEF(double a, double b, double c); + + void SetUnitarizationOrders(int qq, int cgc) + { + qqMaxOrder = qq; + cgcMaxOrder = cgc; + } + + virtual void Print() const; + + virtual TComplex Amp(double t) const; + virtual TComplex Prf(double b) const; + + protected: + /// diffraction variables + TComplex R, a, Diff_fac_profile, Diff_fac; + + /// hard scattering variables + TComplex Abs_fac; + + /// core scattering variables + double beta, m_omega_sq, Core_fac; + + /// quark confinement parameters + double m0sq; + + /// "hard pomeron" scattering variables + double r0, omega; + TComplex Quark_fac; + TComplex Quark_const; + int qqMaxOrder; + + /// "low-x gluons" scattering + double lambda, m_c; + TComplex cgc_fac; + int cgcMaxOrder; + + /// integration variables + double precision, precision_t, upper_bound, upper_bound_t; + + /// diffraction amplitude + TComplex T_diff(double t) const; + TComplex GammaD(double b) const; + static TComplex GammaD_J0(double *b, double *t, const void *obj); + + /// core amplitude + TComplex T_core(double t) const; + double F_sq(double t) const; + + /// quark-quark amplitude + TComplex T_quark(double t) const; + double I_integral(double qt, double al) const; + static double F_cal_integ(double *x, double *qt, const void *obj); + double F_cal(int n, double qt, double om, double m0sq) const; + + /// quark-quark amplitude: hard-pomeron variant + static double T_hp_integ(double *, double *, const void *); + TComplex T_hp_n(int n, double t) const; + TComplex T_hp(double t) const; + + /// quark-quark amplitude: low-x gluons variant + static double T_lxg_integ(double *, double *, const void *); + TComplex T_lxg_n(int n, double t) const; + TComplex T_lxg(double t) const; + + /// profile funcion methods + static TComplex Amp_J0(double *t, double *b, const void *obj); +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/interface/JenkovszkyModel.h b/IOMC/Elegent/interface/JenkovszkyModel.h new file mode 100644 index 00000000000..3e022d13ae5 --- /dev/null +++ b/IOMC/Elegent/interface/JenkovszkyModel.h @@ -0,0 +1,53 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_jenkovszky_model_ +#define _elegent_jenkovszky_model_ + +#include "Model.h" + +namespace Elegent +{ + +/** + * \brief The model of Jenkovszky et al. + * References: + * [1] L. L. JENKOVSZKY, A. I. LENGYEL, and D. I. LONTKOVSKYI, Int. J. Mod. Phys. A 26 (2011) 4755. DOI: 10.1142/S0217751X11054760 + **/ +class JenkovszkyModel : public Model +{ + public: + JenkovszkyModel(); + + void Configure(); + virtual void Init(); + + virtual void Print() const; + + virtual TComplex Amp(double t) const; + virtual TComplex Prf(double b) const; + + protected: + /// pomeron parameters + double a_P, b_P, de_P, al1_P, ep_P, s_P; + + /// odderon parameters + double a_O, b_O, de_O, al1_O, s_O; + + /// omega parameters + double a_om, b_om, s_om, al0_om, al1_om; + + /// f parameters + double a_f, b_f, s_f, al0_f, al1_f; + + /// integration parameters for profile-funcion calculation + double precision_t, upper_bound_t; + + static TComplex Amp_J0(double *t, double *b, const void *obj); +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/interface/Math.h b/IOMC/Elegent/interface/Math.h new file mode 100644 index 00000000000..805e52b9996 --- /dev/null +++ b/IOMC/Elegent/interface/Math.h @@ -0,0 +1,40 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_math_ +#define _elegent_math_ + +#include + +namespace Elegent +{ + +// ================================== INTEGRATION ROUTINES ================================================= + +/** + *\brief Integrates real-valued function `fcn' between points `a' and `b'. + * `obj' is passed as the third parameter to `fcn' + * `params' is passed as the second parameter to `fcn' + * the integration variable is the first element of the array in the first parameter of `fcn' + * `epsilon' controls the precision of the integration + * + * The function has been adapted from ROOT's TF1::Integral. + **/ +double DoubleInt(const void *obj, double (*fcn)(double*, double*, const void*), double a, double b, double *params = NULL, double epsilon = 1E-9); + +/** + *\brief Integrates complex-valued function `fcn' between points `a' and `b'. + * `obj' is passed as the third parameter to `fcn' + * `params' is passed as the second parameter to `fcn' + * the integration variable is the first element of the array in the first parameter of `fcn' + * `epsilon' controls the precision of the integration + * + * The function has been adapted from ROOT's TF1::Integral. + **/ +TComplex CmplxInt(const void *obj, TComplex (*fcn)(double*, double*, const void *), double a, double b, double *params = NULL, double epsilon = 1E-9); + +} // namespace + +#endif diff --git a/IOMC/Elegent/interface/Model.h b/IOMC/Elegent/interface/Model.h new file mode 100644 index 00000000000..beafdcd433b --- /dev/null +++ b/IOMC/Elegent/interface/Model.h @@ -0,0 +1,68 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_model_ +#define _elegent_model_ + +#include "TComplex.h" + +#include + +namespace Elegent +{ + +/** + * \brief The base class for hadronic models of (anti)proton-proton elastic scattering. + **/ +class Model +{ + public: + /// collection of strings that describe model instance + struct Label + { + std::string name, variant, version, mode; + }; + + /// full label (e.g. for figure legend) + Label fullLabel; + + /// short label (e.g. for object names in ROOT files) + Label shortLabel; + + /// compiles a human readable string from fullLabel + std::string CompileFullLabel() const; + + /// compiles a human readable string from shortLabel + std::string CompileShortLabel() const; + + Model() {} + + virtual ~Model() {} + + /// TODO + virtual void Init() =0; + + /// prints model info + virtual void Print() const =0; + + ///\brief amplitude, t in GeV^-2, t < 0 + /// Normalisation is such that + /// dsigma/dt = (\hbar c)^2 * \pi / (s p^2) * |Amp(t)|^2 + /// Differential cross-section can be obtained as + /// Constants::sig_fac * |Amp(t)|^2 + virtual TComplex Amp(double t) const =0; + + ///\brief profile function, b in fm + /// Normalisation is such that + /// Amp(t) = 2 p \sqrt{s} \int db b Prf() J_0(b \sqrt{-t}) + virtual TComplex Prf(double b) const =0; +}; + +/// current model +extern Model *model; + +} // namespace + +#endif diff --git a/IOMC/Elegent/interface/ModelFactory.h b/IOMC/Elegent/interface/ModelFactory.h new file mode 100644 index 00000000000..dc8d6fd185f --- /dev/null +++ b/IOMC/Elegent/interface/ModelFactory.h @@ -0,0 +1,42 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_modelfactory_ +#define _elegent_modelfactory_ + +#include "IslamModel.h" +#include "PPPModel.h" +#include "BSWModel.h" +#include "BHModel.h" +#include "JenkovszkyModel.h" +#include "ExpModel.h" + +#include +#include + +namespace Elegent +{ + +/** + * \brief A class to give list of available models and to create an instance of a model specified by tag. + **/ +class ModelFactory +{ + protected: + /// map: tag --> model instance + std::map model_map; + + public: + ModelFactory(); + + void PrintList() const; + + Model* MakeInstance(const std::string &tag, bool callInit = true) const; +}; + + +} // namespace + +#endif diff --git a/IOMC/Elegent/interface/PPPModel.h b/IOMC/Elegent/interface/PPPModel.h new file mode 100644 index 00000000000..4dd84cecbc3 --- /dev/null +++ b/IOMC/Elegent/interface/PPPModel.h @@ -0,0 +1,62 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#ifndef _elegent_ppp_model_ +#define _elegent_ppp_model_ + +#include "Model.h" + +namespace Elegent +{ + +/** + * \brief Predazzi, Petrov and Prokudin model of p-p and p-anti p elastic scattering. + * References: + * [1] PETROV, V. A. and PROKUDIN, A. V., Eur. Phys. J. C23 (2002) 135–143 + **/ +class PPPModel : public Model +{ + public: + struct Trajectory + { + double D, c, ap, r2, rho2; + TComplex gamma; + }; + + /// available variant + enum VariantType + { + v2P, ///< with 2 Pomerons + v3P ///< with 3 Pomerons + } variant; + + PPPModel(); + + void Configure(VariantType v); + + virtual void Init(); + + virtual void Print() const; + + virtual TComplex Amp(double t) const; + virtual TComplex Prf(double b) const; ///< b in fm + + protected: + Trajectory pom1, pom2, pom3, oder, regf, rego; + double s0; + double precision, upper_bound; + + static void SetTrajectory(Trajectory &t, double D, double c, double ap, double r2, double s0); + + TComplex tr_eik(Trajectory, double s, double t) const; + + + virtual TComplex prf0(double b) const; ///< b in GeV^-1 + static TComplex prf_J0(double *b, double *t, const void *obj); +}; + +} // namespace + +#endif diff --git a/IOMC/Elegent/plugins/BuildFile.xml b/IOMC/Elegent/plugins/BuildFile.xml new file mode 100644 index 00000000000..391b6b4e383 --- /dev/null +++ b/IOMC/Elegent/plugins/BuildFile.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/IOMC/Elegent/plugins/ElegentSource.cc b/IOMC/Elegent/plugins/ElegentSource.cc new file mode 100644 index 00000000000..61f612eb767 --- /dev/null +++ b/IOMC/Elegent/plugins/ElegentSource.cc @@ -0,0 +1,117 @@ +/**************************************************************************** +* +* This is a part of TOTEM offline software. +* Authors: +* Jan Kašpar (jan.kaspar@gmail.com) +* +****************************************************************************/ + +#include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/EDProducer.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/Utilities/interface/RandomNumberGenerator.h" +#include "CLHEP/Random/RandomEngine.h" + +#include "IOMC/Elegent/interface/Generator.h" + +#include "TRandom2.h" + +/** + *\brief Monte-Carlo generator of (anti)proton-pron elastic collisions + * A CMSSW wrapper for Elegent::Generator, for details see + * http://elegent.hepforge.org/ + **/ +class ElegentSource : public edm::EDProducer +{ + public: + ElegentSource(const edm::ParameterSet &); + virtual ~ElegentSource(); + virtual void beginJob(); + + protected: + unsigned int verbosity; + + Elegent::Generator* generator; + + virtual void produce(edm::Event&, const edm::EventSetup&); + private: + const UInt_t DEFAULT_SEED = 65539; +}; + + + +using namespace HepMC; +using namespace std; +using namespace edm; + +//---------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------- + +ElegentSource::ElegentSource(const ParameterSet& pSet) : + verbosity(pSet.getUntrackedParameter("verbosity", 1)) +{ + string fileName = pSet.getParameter("fileName"); + if (fileName[0] != '/' && fileName[0] != '.') + { + char *cmsswPath = getenv("CMSSW_BASE"); + if (cmsswPath) + fileName = string(cmsswPath) + string("/src/") + fileName; + } + + generator = new Elegent::Generator( + fileName, + pSet.getParameter("model") + "/cumulative cross-section", + pSet.getParameter("t_min"), + pSet.getParameter("t_max"), + verbosity + ); + + produces(); +} + +//---------------------------------------------------------------------------------------------------- + +ElegentSource::~ElegentSource() +{ + delete generator; +} + +//---------------------------------------------------------------------------------------------------- + +void ElegentSource::beginJob() +{ + if (generator->Init() != 0) + throw cms::Exception("ElegentSource::beginJob") << "Can not initialise Elegent::Generator."; +} + +//---------------------------------------------------------------------------------------------------- + +void ElegentSource::produce(edm::Event &e, const edm::EventSetup &es) +{ + // initialize random seed + if(gRandom->GetSeed() == DEFAULT_SEED) { + Service rng; + CLHEP::HepRandomEngine &rndEng = rng->getEngine(e.streamID()); + unsigned int seed = rndEng.getSeed(); + gRandom->SetSeed(seed); + if (verbosity > 0) + printf(">> ElegentSource > seed = %u\n", seed); + } + + // create event structure + GenEvent* gEv = new GenEvent(); + gEv->set_event_number(e.id().event()); + + // run generator + generator->Generate(gEv); + + // store generator event to the FW event + auto_ptr output(new HepMCProduct()); + output->addHepMCData(gEv); + e.put(output); +} + +DEFINE_FWK_MODULE(ElegentSource); diff --git a/IOMC/Elegent/python/ElegentSource_cfi.py b/IOMC/Elegent/python/ElegentSource_cfi.py new file mode 100644 index 00000000000..a20d923f444 --- /dev/null +++ b/IOMC/Elegent/python/ElegentSource_cfi.py @@ -0,0 +1,41 @@ +import FWCore.ParameterSet.Config as cms + +# returns the default file name for the given energy +def ElegentDefaultFileName(energy): + if energy == '7000': + return 'IOMC/Elegent/data/t-distributions,pp,14000GeV.root' + if energy == '6500': + return 'IOMC/Elegent/data/t-distributions,pp,13000GeV.root' + if energy == '4000': + return 'IOMC/Elegent/data/t-distributions,pp,8000GeV.root' + if energy == '3500': + return 'IOMC/Elegent/data/t-distributions,pp,7000GeV.root' + if energy == '1380': + return 'IOMC/Elegent/data/t-distributions,pp,2760GeV.root' + raise Exception('Energy ' + energy + ' is not supported.') + + +generator = cms.EDProducer("ElegentSource", + verbosity = cms.untracked.uint32(1), + + # the name of ROOT file with CDFs + fileName = cms.string(''), + + # choice of interaction model (for details see http://elegent.hepforge.org/) + # the naming scheme is + # // + # available ranges are + # 'full range': samples linear in |t| + # 'low |t|': samples linear in log |t| + # available hadronic-model tags can be obtained by running: + # ElegentTDistributionSampler -model-list + # available coulomb-interaction tags: + # PH = pure hadron, i.e. no Coulomb effects included + # WY = Coulomb effects included via West-Yennie formula + # KL = Coulomb effects included via Kundrat-Lokajicek formula + model = cms.string('full range/petrov (3p) [02]/KL'), + + # |t| range restrictions, in GeV^2 + t_min = cms.double(0.0), + t_max = cms.double(10.0), +) diff --git a/IOMC/Elegent/src/BHModel.cc b/IOMC/Elegent/src/BHModel.cc new file mode 100644 index 00000000000..2035ecfb3b4 --- /dev/null +++ b/IOMC/Elegent/src/BHModel.cc @@ -0,0 +1,222 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/BHModel.h" +#include "interface/Math.h" +#include "interface/Constants.h" + +using namespace Elegent; + +//---------------------------------------------------------------------------------------------------- + +BHModel::BHModel() +{ + fullLabel.name = "Block et al."; shortLabel.name = "block"; +} + +//---------------------------------------------------------------------------------------------------- + +void BHModel::Configure() +{ + // set labels + fullLabel.variant = ""; shortLabel.variant = ""; + fullLabel.version = "Phys. Rept. 436 (2006) 71-215"; shortLabel.version = "06"; + fullLabel.mode = ""; shortLabel.mode = ""; +} + +//---------------------------------------------------------------------------------------------------- + +void BHModel::Init() +{ + // parameters from [2]: Table 5, N_g from above Eq. (463), a's and b's from A.1.2 + + // common parameters + m0 = 0.6; + s0 = 9.53; + al_s = 0.5; + Sigma_gg = 9. * cnts->pi * al_s*al_s / m0/m0; + + // sigma_gg + Cp_gg = 0.00103; + epsilon = 0.05; + + // TODO: which is correct? + // [1] : Ng = (6.-epsilon)*(5.-epsilon)*(4.-epsilon)*(3.-epsilon)*(2.-epsilon)*(1.-epsilon) /5./4./3./2. / 2.; // = 2.649 + // [2] : Ng = 3./2. * (5.-epsilon)*(4.-epsilon)*(3.-epsilon)*(2.-epsilon)*(1.-epsilon) /5./4./3./2.; // = 1.335 + // Value from [2] seems wrong + Ng = (6.-epsilon)*(5.-epsilon)*(4.-epsilon)*(3.-epsilon)*(2.-epsilon)*(1.-epsilon) /5./4./3./2. / 2.; + + a.push_back(-41.1); + a.push_back(-487.5); + a.push_back(-600.); + a.push_back(600.); + a.push_back(487.5); + a.push_back(41.1); + + b.push_back(-9.); + b.push_back(-225.); + b.push_back(-900.); + b.push_back(-900.); + b.push_back(-225.); + b.push_back(-9.); + + // sigma_qg + C_qg_log = 0.166; + + // sigma_qq + C = 5.36; + C_even_regge = 29.7; + + // sigma_odd + C_odd = 10.3; + + // mu's + mu_gg = 0.73; + mu_odd = 0.53; + mu_qq = 0.89; + + // integration settings + upper_bound = 50.; + precision = 1E-12; + + // precompute mu_qg + mu_qg = sqrt(mu_qq*mu_gg); + + // precompute sigma_gg, Eq. (B5) in [1]: below the Cp_gg stands for C'_gg + sigma_gg = Cp_gg * Sigma_gg * Ng*Ng * Sum(cnts->s); + + // precompute sigma_qq, Eq. (B9) in [1] + sigma_qq = Sigma_gg * (C + C_even_regge * m0/sqrt(cnts->s) * TComplex::Exp(i * cnts->pi / 4.)); + + // precompute sigma_qg, Eq. (B10) in [1] + sigma_qg = Sigma_gg * C_qg_log * TComplex(log(cnts->s/s0), -cnts->pi/2.); + + // precompute sigma_odd, Eq. (B12) in [1] - the factor in front of W(b, mu_odd) + // plus additional factor (-i) to match the normalization used in chi_without_i + sigma_odd = -i * C_odd * Sigma_gg * m0 / cnts->sqrt_s * TComplex::Exp(i * cnts->pi / 4.); +} + +//---------------------------------------------------------------------------------------------------- + +void BHModel::Print() const +{ + printf(">> BHModel::Print\n"); + printf("\t%s\n", CompileFullLabel().c_str()); + + printf("\tcommon:\n"); + printf("\t\ts0 = %E\n", s0); + printf("\t\tm0 = %E\n", m0); + printf("\t\tSigma_gg = %E\n", Sigma_gg); + + printf("\tsigma_gg:\n"); + printf("\t\tCp_gg = %E\n", Cp_gg); + printf("\t\tNg = %E\n", Ng); + printf("\t\tepsilon = %E\n", epsilon); + printf("\t\ta0 = %E, a1 = %E, a2 = %E, a3 = %E, a4 = %E, a5 = %E\n", a[0], a[1], a[2], a[3], a[4], a[5]); + printf("\t\tb0 = %E, b1 = %E, b2 = %E, b3 = %E, b4 = %E, b5 = %E\n", b[0], b[1], b[2], b[3], b[4], b[5]); + printf("\t\tsigma_gg: Re = %E, Im = %E\n", sigma_gg.Re(), sigma_gg.Im()); + + printf("\tsigma_qg:\n"); + printf("\t\tC_qg_log = %E\n", C_qg_log); + printf("\t\tsigma_qg: Re = %E, Im = %E\n", sigma_qg.Re(), sigma_qg.Im()); + + printf("\tsigma_qq:\n"); + printf("\t\tC = %E\n", C); + printf("\t\tC_even_regge = %E\n", C_even_regge); + printf("\t\tsigma_qq: Re = %E, Im = %E\n", sigma_qq.Re(), sigma_qq.Im()); + + printf("\tsigma_odd:\n"); + printf("\t\tC_odd = %E\n", C_odd); + printf("\t\tsigma_odd: Re = %E, Im = %E\n", sigma_odd.Re(), sigma_odd.Im()); + + printf("\tmu's:\n"); + printf("\t\tmu_gg = %E\n", mu_gg); + printf("\t\tmu_qq = %E\n", mu_qq); + printf("\t\tmu_qg = %E\n", mu_qg); + printf("\t\tmu_odd = %E\n", mu_odd); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BHModel::Sum(double s) const +{ + TComplex log_tau0 = log(m0*m0 / s) + i * cnts->pi / 2.; + + TComplex S = 0.; + + for (unsigned int ii = 0; ii <= 5; ii++) + { + double i = double(ii); + double ime = i - epsilon; + double f = b[ii] / ime; + double t1 = (a[i] - f) / ime; + TComplex v = t1 - TComplex::Exp(ime * log_tau0) * (t1 + f * log_tau0); + S += v; + } + + return S; +} + +//---------------------------------------------------------------------------------------------------- +double BHModel::W(double b, double mu) const +{ + // Eq. (B2) in [1] + double mub = mu * b; + + // evaluates v = (mu b)^3 K_3(mu b); directly or in continuous limit + double v = 0.; + if (mub < 1E-10) + v = 8.; + else + v = mub*mub*mub * TMath::BesselK(3, mub); + return mu*mu * v / 96. / cnts->pi; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BHModel::chi_without_i(double b) const +{ + // TODO: why the one half? + + // Eqs. (B1) without the leading i factor and Eq. (B12) in [1] + double odd_sign = (cnts->pMode == cnts->mAPP) ? +1. : -1.; + return ( + sigma_gg * W(b, mu_gg) + + sigma_qg * W(b, mu_qg) + + sigma_qq * W(b, mu_qq) + + odd_sign * sigma_odd * W(b, mu_odd) + ) / 2.; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BHModel::prf0(double b) const +{ + return (1. - TComplex::Exp(-chi_without_i(b))); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BHModel::Prf(double b) const +{ + return prf0(b / cnts->hbarc) * i / 2.; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BHModel::prf0_J0(double *b, double *q, const void *obj) +{ + return b[0] * TMath::BesselJ0(b[0]*q[0]) * ((BHModel *)obj)->prf0(b[0]); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BHModel::Amp(double t) const +{ + double q = sqrt(-t); + + // from Eqs. (A11) and (A12) + return i * cnts->p_cms * cnts->sqrt_s * CmplxInt(this, prf0_J0, 0., upper_bound, &q, precision); +} diff --git a/IOMC/Elegent/src/BSWModel.cc b/IOMC/Elegent/src/BSWModel.cc new file mode 100644 index 00000000000..a212a0c32ff --- /dev/null +++ b/IOMC/Elegent/src/BSWModel.cc @@ -0,0 +1,270 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/BSWModel.h" +#include "interface/Constants.h" +#include "interface/Math.h" + +using namespace std; +using namespace Elegent; + +//---------------------------------------------------------------------------------------------------- + +BSWModel::BSWModel() +{ + fullLabel.name = "Bourrely et al."; shortLabel.name = "bourrely"; + + highAccuracy = true; +} + +//---------------------------------------------------------------------------------------------------- + +void BSWModel::Configure(BSWModel::ModeType _mode, bool _presampled) +{ + mode = _mode; + presampled = _presampled; + + // set labels + fullLabel.variant = ""; shortLabel.variant = ""; + fullLabel.version = "Eur. Phys. J. C28 (2003) 97-105"; shortLabel.version = "03"; + if (mode == mPomReg) + { fullLabel.mode = "full"; shortLabel.mode = "full"; } + if (mode == mPom) + { fullLabel.mode = "Pomeron"; shortLabel.mode = "pom"; } + if (mode == mReg) + { fullLabel.mode = "Reggeon"; shortLabel.mode = "reg"; } +} + +//---------------------------------------------------------------------------------------------------- + +void BSWModel::Init() +{ + // Eq. (6) in [3] + c = 0.167; + cp = 0.748; + + // Table 1 in [3] + m1 = 0.577; m1sq = m1*m1; // 0.333 + m2 = 1.719; m2sq = m2*m2; // 2.955 + f = 6.971; + a = 1.858; asq = a*a; // 3.452 + + // Table 2 in [3], b's given in text of section 3 in [3] + A2.Init( -24.269, 0., 0.357, 1., +1); + omega.Init( -167.329, 0., 0.323, 0.795, -1); + rho.Init( 124.919, 8.54, 0.320, 1., -1); + + if (highAccuracy) + { + upper_bound_t = -500.; precision_t = 1E-15; + upper_bound_b = 50.; precision_b = 1E-12; + } else { + upper_bound_t = -200.; precision_t = 1E-5; + upper_bound_b = 30.; precision_b = 1E-5; + } + + regge_fac(1., 0.); + + // save value of S0(0) + S00 = S0(0.); + if (presampled) + BuildSample(25001); +} + +//---------------------------------------------------------------------------------------------------- + +void BSWModel::Print() const +{ + printf(">> BSWModel::Print\n"); + printf("\t%s\n", CompileFullLabel().c_str()); + printf("\tmode = %u\n", mode); + printf("\tc=%.3f, c'=%.3f, m1=%.3f, m2=%.3f, f=%.3f, a=%.3f\n", c, cp, m1, m2, f, a); + printf("\tA2 : C=%.3f, b=%.3f, alpha=%.3f, aplha'=%.3f\n", A2.C, A2.b, A2.a, A2.ap); + printf("\tomega: C=%.3f, b=%.3f, alpha=%.3f, aplha'=%.3f\n", omega.C, omega.b, omega.a, omega.ap); + printf("\trho : C=%.3f, b=%.3f, alpha=%.3f, aplha'=%.3f\n", rho.C, rho.b, rho.a, rho.ap); + + printf("\n"); + + printf("\tpresampled = %u\n", presampled); + if (presampled) + printf("\t\tsample size = %u, db = %.1E\n", data_N, data_db); + + printf("\n"); + + printf("\tintegration parameters:\n"); + printf("\t\tt: upper bound = %.1E, precision = %.1E\n", upper_bound_t, precision_t); + printf("\t\tb: upper bound = %.1E, precision = %.1E\n", upper_bound_b, precision_b); +} + +//---------------------------------------------------------------------------------------------------- + +double BSWModel::Ft(double t) const +{ + double G = 1. / (1. - t/m1sq) / (1. - t/m2sq); + return f*G*G* (asq + t) / (asq - t); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::Rt(Trajectory tr, double t) const +{ + /// s0 = 1 GeV^2 + + double alpha = tr.a + tr.ap * t; + return tr.C * exp(tr.b * t + cnts->ln_s * alpha) * (1. + tr.sig * TComplex::Exp(-i*cnts->pi*alpha)); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::R0t(double t) const +{ + return Rt(A2, t) + Rt(omega, t) + Rt(rho, t); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::S0(double t) const +{ + // the s term + TComplex term_s = pow(cnts->s, c) / pow(cnts->ln_s, cp); + + // the u term + double u = 4.*cnts->proton_mass*cnts->proton_mass - cnts->s - t; + TComplex Lnu = TComplex(log(fabs(u)), -cnts->pi); // ambiguity in the article: which sign in +-pi? + double Lnu_rho2 = Lnu.Rho2(); + double Lnu_theta = atan2(Lnu.Im(), Lnu.Re()); // atan2 results in (-pi, +pi) + TComplex LnLnu = TComplex(0.5*log(Lnu_rho2), Lnu_theta); + TComplex term_u = TComplex::Exp(c * Lnu) / TComplex::Exp(cp * LnLnu); + +#ifdef DEBUG + printf(">> BSWModel::S0\n"); + printf("\ts=%E, u=%E\n", cnts->s, u); + printf("\tLn u=%E +i%E\n", Lnu.Re(), Lnu.Im()); + printf("\tLn Ln u=%E +i%E\n", LnLnu.Re(), LnLnu.Im()); + printf("\tterm_s: %E + i%E\n", term_s.Re(), term_s.Im()); + printf("\tterm_u: %E + i%E\n", term_u.Re(), term_u.Im()); +#endif + + return term_s + term_u; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::Omega0t(double t) const +{ + // S00 = S0(0) instead of S0(t) is used here, valid for high s only !! + + switch (mode) { + case mPomReg: + return S00*Ft(t) + R0t(t) / cnts->s / regge_fac; + case mPom: + return S00*Ft(t); + case mReg: + return R0t(t); + } + + return TComplex(0, 0); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::Omega0t_J0(double *t, double *b, const void *obj) +{ + return ((BSWModel *)obj)->Omega0t(t[0]) * TMath::BesselJ0(b[0] * sqrt(-t[0])); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::Omega0b(double b) const +{ + // the 1/2 factor is consequence of dt integration (instead of q dq) + return 0.5 * CmplxInt(this, Omega0t_J0, upper_bound_t, 0., &b, precision_t); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::prf0(double b) const +{ + return 1. - TComplex::Exp( - Omega0b(b) ); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::Prf(double b) const +{ + return prf0(b / cnts->hbarc) * i / 2.; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::prf0_J0(double *b, double *q, const void *obj) +{ + BSWModel *m = (BSWModel *) obj; + + if (m->presampled) + return m->SampleEval(b[0]) * b[0] * TMath::BesselJ0(b[0] * q[0]); + else + return m->prf0(b[0]) * b[0] * TMath::BesselJ0(b[0] * q[0]); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::Amp(double t) const +{ + double q = sqrt(-t); + + return i * cnts->p_cms * cnts->sqrt_s * CmplxInt(this, prf0_J0, 0., upper_bound_b, &q, precision_b); +} + +//---------------------------------------------------------------------------------------------------- + +void BSWModel::BuildSample(unsigned int samples) +{ + printf(">> BSWModel::BuildSample > Building %u samples...\n", samples); + + data_re.clear(); + data_re.reserve(samples); + data_im.clear(); + data_im.reserve(samples); +#ifdef DEBUG + data_b.clear(); + data_b.reserve(samples); +#endif + + double db = upper_bound_b / (samples - 1); + data_db = db; + data_N = samples; + + double b = 0.; + for (unsigned int i = 0; i < samples; i++, b += db) + { + TComplex v = prf0(b); + +#ifdef DEBUG + //printf("v=%.5f: re=%E, im=%E\n", b, v.Re(), v.Im()); + data_b.push_back(b); +#endif + + data_re.push_back(v.Re()); + data_im.push_back(v.Im()); + } +} + +//---------------------------------------------------------------------------------------------------- + +TComplex BSWModel::SampleEval(double b) +{ + unsigned int idx = (int)(b / data_db); + + if (idx + 1 > data_N - 1) + return TComplex(0, 0); + + double f = b/data_db - idx; + + return TComplex( + (data_re[idx+1] - data_re[idx])*f + data_re[idx], + (data_im[idx+1] - data_im[idx])*f + data_im[idx] + ); +} diff --git a/IOMC/Elegent/src/Constants.cc b/IOMC/Elegent/src/Constants.cc new file mode 100644 index 00000000000..cc36b24e131 --- /dev/null +++ b/IOMC/Elegent/src/Constants.cc @@ -0,0 +1,74 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/Constants.h" + +namespace Elegent +{ + +//---------------------------------------------------------------------------------------------------- + +TComplex i(0, 1); +Constants *cnts = NULL; + +// physics constants +double Constants::alpha = 7.297E-3; +double Constants::proton_mass = 0.938271; +double Constants::neutron_mass = 0.939565; +double Constants::hbarc = 0.197326; +double Constants::sq_hbarc = 0.389379; +double Constants::M = proton_mass; +double Constants::M_sq= proton_mass * proton_mass; +double Constants::kappa = 1.793; + +// mathematical constants +double Constants::pi = M_PI; +double Constants::gamma = 0.577215; + +//---------------------------------------------------------------------------------------------------- + +void Constants::Configure(double W, Constants::ParticleMode mode) +{ + sqrt_s = W; + s = sqrt_s*sqrt_s; + ln_s = log(s); + p_cms = sqrt(s /4. - proton_mass * proton_mass); + sig_fac = sq_hbarc * pi / (s * p_cms * p_cms); + t_min = 4.*proton_mass * proton_mass - s; + + pMode = mode; +} + +//---------------------------------------------------------------------------------------------------- + +void Constants::Init(double W, Constants::ParticleMode mode) +{ + cnts = new Constants(W, mode); +} + +//---------------------------------------------------------------------------------------------------- + +void Constants::Print() +{ + printf(">> Constants::Print\n"); + printf(" alpha = %E\n", alpha); + printf(" proton_mass = %E\n", proton_mass); + printf(" neutron_mass = %E\n", neutron_mass); + printf(" hbarc = %E\n", hbarc); + printf(" sq_hbarc = %E\n", sq_hbarc); + printf(" M = %E\n", M); + printf(" M_sq = %E\n", M_sq); + printf(" pi = %E\n", pi); + printf(" gamma = %E\n", gamma); + printf(" sqrt_s = %E\n", sqrt_s); + printf(" s = %E\n", s); + printf(" ln_s = %E\n", ln_s); + printf(" p_cms = %E\n", p_cms); + printf(" sig_fac = %E\n", sig_fac); + printf(" t_min = %E\n", t_min); + printf(" pMode = %s\n", (pMode == mPP) ? "pp" : "app"); +} + +} // namespace diff --git a/IOMC/Elegent/src/CoulombInterference.cc b/IOMC/Elegent/src/CoulombInterference.cc new file mode 100644 index 00000000000..189dfc3fe0d --- /dev/null +++ b/IOMC/Elegent/src/CoulombInterference.cc @@ -0,0 +1,456 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/CoulombInterference.h" +#include "interface/Math.h" +#include "interface/Constants.h" + +using namespace std; +using namespace Elegent; + +namespace Elegent +{ + +//---------------------------------------------------------------------------------------------------- + +// a global instance +CoulombInterference *coulomb = new CoulombInterference(); + +//---------------------------------------------------------------------------------------------------- + +CoulombInterference::CoulombInterference() : mode(mPC), ffType(ffPuckett), + tau(1E-10), T(10.), precision(1E-4) +{ +} + +//---------------------------------------------------------------------------------------------------- + +void CoulombInterference::Print() const +{ + printf(">> CoulombInterference::print\n"); + printf("\tmode: %s\n", GetModeString().c_str()); + printf("\tform factor: %s\n", GetFFName().c_str()); + printf("\tT = %E\n", T); + printf("\ttau = %E\n", tau); + printf("\tprecision = %E\n", precision); +} + +//---------------------------------------------------------------------------------------------------- + +string CoulombInterference::GetModeString() const +{ + switch (mode) + { + case mPC: return "PC"; + case mPH: return "PH"; + case mWY: return "WY"; + case mSWY: return "SWY"; + case mKL: return "KL"; + default: return "unknown"; + } +} + +//--------------------------------------- FORM FACTORS --------------------------------------------- + +double di_la_sq = 0.71; + +double bor_E_msq[] = {0.13745, 0.58485, 1.7164, 6.0042}; +double bor_E_c[] = {0.0301, 0.8018, -1.0882, 0.2642}; + +double bor_M_msq[] = {0.339, 0.583, 1.711, 13.793}; +double bor_M_c[] = {0.269, 0.346, -0.672, 0.069}; + +double kel_E_a[] = {1., -0.24}; +double kel_E_b[] = {1., 10.98, 12.82, 21.97}; + +double kel_M_a[] = {1., 0.12}; +double kel_M_b[] = {1., 10.97, 18.86, 6.55}; + +double arr_E_a[] = {1., 3.439, -1.602, 0.068}; +double arr_E_b[] = {1., 15.055, 48.061, 99.304, 0.012, 8.650}; + +double arr_M_a[] = {1., -1.465, 1.260, 0.262}; +double arr_M_b[] = {1., 9.627, 0.000, 0.000, 11.179, 13.245}; + +double puc_E_a[] = {1., -0.299}; +double puc_E_b[] = {1., 11.11, 14.11, 15.7}; + +double puc_M_a[] = {1., 0.081}; +double puc_M_b[] = {1., 11.15, 18.45, 5.31}; + +double pol(double p[], unsigned int N, double tau) +{ + double s = 0.; + double f = 1.; + for (unsigned int i = 0; i < N; i++, f *= tau) { + s += p[i] * f; + } + + return s; +} + +//---------------------------------------------------------------------------------------------------- + +double CoulombInterference::FF_dipole(double t) const +{ + double f = (di_la_sq / (di_la_sq - t)); + return f*f; +} + +//---------------------------------------------------------------------------------------------------- + +double CoulombInterference::FF_e(double t) const +{ + /// t is negative + + double tau = -t/4./cnts->M_sq; + + switch (ffType) + { + case ffNone: + return 1.; + + case ffDipole: + return FF_dipole(t); + + case ffHofstadter: + return FF_dipole(t) * (1. - tau*cnts->kappa); + + case ffBorkowski: + return bor_E_c[0] / (bor_E_msq[0] - t) + + bor_E_c[1] / (bor_E_msq[1] - t) + + bor_E_c[2] / (bor_E_msq[2] - t) + + bor_E_c[3] / (bor_E_msq[3] - t); + + case ffKelly: + return pol(kel_E_a, 2, tau) / pol(kel_E_b, 4, tau); + + case ffArrington: + return pol(arr_E_a, 4, tau) / pol(arr_E_b, 6, tau); + + case ffPuckett: + return pol(puc_E_a, 2, tau) / pol(puc_E_b, 4, tau); + + case ffPuckettEl: + return pol(puc_E_a, 2, tau) / pol(puc_E_b, 4, tau); + + default: + return 0.; + } +} + +//---------------------------------------------------------------------------------------------------- + +double CoulombInterference::FF_m(double t) const +{ + /// t is negative + + double tau = -t/4./cnts->M_sq; + + switch (ffType) + { + case ffNone: + return 1.; + + case ffDipole: + return FF_dipole(t); + + case ffHofstadter: + return FF_dipole(t) * (1. + cnts->kappa); + + case ffBorkowski: + return (1. + cnts->kappa) * + (bor_M_c[0] / (bor_M_msq[0] - t) + + bor_M_c[1] / (bor_M_msq[1] - t) + + bor_M_c[2] / (bor_M_msq[2] - t) + + bor_M_c[3] / (bor_M_msq[3] - t)); + + case ffKelly: + return (1. + cnts->kappa) * pol(kel_M_a, 2, tau) / pol(kel_M_b, 4, tau); + + case ffArrington: + return (1. + cnts->kappa) * pol(arr_M_a, 4, tau) / pol(arr_M_b, 6, tau); + + case ffPuckett: + return (1. + cnts->kappa) * pol(puc_M_a, 2, tau) / pol(puc_M_b, 4, tau); + + case ffPuckettEl: + return 0.; + + default: + return 0.; + } +} + +//---------------------------------------------------------------------------------------------------- + +double CoulombInterference::FF_sq(double t) const +{ + double eff = FF_e(t); + + if (ffType == ffPuckettEl) + return eff*eff; + + double mff = FF_m(t); + double tau = -t/4./cnts->M_sq; + + return (eff*eff + tau*mff*mff) / (1. + tau); +} + +//---------------------------------------------------------------------------------------------------- + +string CoulombInterference::GetFFName() const +{ + switch (ffType) + { + case ffNone: return "none"; + case ffDipole: return "dipole"; + case ffHofstadter: return "Hofstadter"; + case ffBorkowski: return "Borkowski"; + case ffKelly: return "Kelly"; + case ffArrington: return "Arrington"; + case ffPuckett: return "Puckett"; + case ffPuckettEl: return "Puckett electric only"; + default: return "unknown"; + } +} + +//------------------------------------- COULOMB AMPLITUDE ------------------------------------------ + +TComplex CoulombInterference::Amp_pure(double t) const +{ + switch (cnts->pMode) + { + case Constants::mPP: + return + cnts->alpha * cnts->s * FF_sq(t) / t; + case Constants::mAPP: + return - cnts->alpha * cnts->s * FF_sq(t) / t; + default: + return 0.; + } +} + +//-------------------------------------------------------------------------------------------------- + +double CoulombInterference::A_integrand(double *tt, double *t, const void *obj) +{ + /// tt[0] ... t' + /// t[0] ... t + return log(tt[0] / t[0]) * ((CoulombInterference *)obj)->FF_sq_prime(tt[0]); +} + +//-------------------------------------------------------------------------------------------------- + +double CoulombInterference::A_term(double t) const +{ + //return DoubleInt(this, A_integrand, cnts->t_min, 0., &t); + return DoubleInt(this, A_integrand, t-T, 0., &t); +} + +//-------------------------------------------------------------------------------------------------- + +double CoulombInterference::I_integrand(double *phi, double *par, const void *obj) +{ + /// par[0] ... t' + /// par[1] ... t + + // t2 ... t'' + double t2 = par[0] + par[1] + 2. * sqrt(par[0] * par[1]) * cos(phi[0]); + return ((CoulombInterference *)obj)->FF_sq(t2) / t2; +} + +//-------------------------------------------------------------------------------------------------- + +double CoulombInterference::I_integral(double t, double tp) const +{ + double par[] = {tp, t}; + return DoubleInt(this, I_integrand, 0., 2.*cnts->pi, par); +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::B_integrand(double *tt, double *par, const void *obj) +{ + /// tt[0] ... t' + /// par[0] ... t + /// par[1] ... Re T_H(t) + /// par[2] ... IM T_H(t) + + TComplex T_hadron_t(par[1], par[2]); + double ppar[] = { tt[0], par[0] }; + + TComplex a = model->Amp(tt[0]) / T_hadron_t; + + const double &I = DoubleInt(obj, I_integrand, 0., 2.*cnts->pi, ppar); + + return (a - 1.) * I / 2. / cnts->pi; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::B_term(double t) const +{ + double par[3]; + par[0] = t; // t + TComplex amp_t = model->Amp(t); // T_H(t) + par[1] = amp_t.Re(); // RE T_H(t) + par[2] = amp_t.Im(); // IM T_H(t) + + /** + Function B_integrand(t', t) has problems at point t' = t. It is not defined there (left and right limits are different), + it is not continuous at the point. To avoid problems, we cut out a small interval (t-tau, t+tau), tau > 0 from the + the integration region (t_min, 0). The second note concerns exponential fall off of B_integrand as one goes with t' away + from t. Thus one can take (t-T, 0) instead of (t_min, 0). Of course, T must be suffciently large. + + In fact, one must be careful with lower bound t+tau, since it must be less than 0. Otherwise contribution from the + region (t+tau, 0) isn't present. + **/ + + TComplex ret = CmplxInt(this, B_integrand, t - T, t - tau, par, precision); + if (t+tau < 0.) + ret += CmplxInt(this, B_integrand, t + tau, 0., par, precision); + + return ret; +} + +//-------------------------------------------------------------------------------------------------- + +double CoulombInterference::C_term(double t) const +{ + return FF_sq(t-T) * log(t/(t-T)); + //return FF_sq(cnts->t_min) * log(t/cnts->t_min); +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Phi_WY(double t) const +{ + TComplex corr = (cnts->pMode == cnts->mPP) ? -cnts->alpha : +cnts->alpha; + corr *= + B_term(t) + C_term(t); + return corr; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Phi_SWY(double t) const +{ + // step for discrete derivative + double zero = -1E-7; + double ep = -1E-5; + + // diffractive slope (at t=0) + double B = log(model->Amp(zero+ep).Rho2() / model->Amp(zero).Rho2()) / ep; + + double phi = cnts->gamma + log(- B * t / 2.); + if (cnts->pMode == cnts->mPP) + phi = -phi; + + return cnts->alpha * phi; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Psi_KL(double t) const +{ + TComplex corr = (cnts->pMode == cnts->mPP) ? -cnts->alpha : +cnts->alpha; + corr *= A_term(t) - B_term(t) - C_term(t); + return corr; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Phase(double t) const +{ + switch (mode) + { + case mPC: return 0.; + case mPH: return 0.; + case mWY: return -Phi_WY(t); + case mSWY: return -Phi_SWY(t); + case mKL: return Psi_KL(t); + default: return 0.; + }; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Amp_WY(double t) const +{ + return Amp_pure(t) * TComplex::Exp(i*Phi_WY(t)) + model->Amp(t); +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Amp_SWY(double t) const +{ + return Amp_pure(t) * TComplex::Exp(i*Phi_SWY(t)) + model->Amp(t); +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Amp_KL(double t) const +{ + return Amp_pure(t) + model->Amp(t) * TComplex::Exp(i*Psi_KL(t)); +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Amp(double t) const +{ + switch (mode) + { + case mPC: + return Amp_pure(t); + case mPH: + return model->Amp(t); + case mWY: + return Amp_WY(t); + case mSWY: + return Amp_SWY(t); + case mKL: + return Amp_KL(t); + default: + return 0.; + }; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::R(double t) const +{ + double KL = Amp_KL(t).Rho2(); + double SWY = Amp_SWY(t).Rho2(); + return (KL - SWY) / KL; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::R_with_cutoff(double t, double cutoff) const +{ + double KL = Amp_KL(t).Rho2(); + double ref = (t > cutoff) ? Amp_WY(t).Rho2() : model->Amp(t).Rho2() ; + return (KL - ref) / KL; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::Z(double t) const +{ + double KL = Amp_KL(t).Rho2(); + double PH = model->Amp(t).Rho2(); + double PC = Amp_pure(t).Rho2(); + return (KL - PH - PC) / KL; +} + +//-------------------------------------------------------------------------------------------------- + +TComplex CoulombInterference::C(double t) const +{ + double KL = Amp_KL(t).Rho2(); + double PH = model->Amp(t).Rho2(); + return (KL - PH) / PH; +} + +} // namespace diff --git a/IOMC/Elegent/src/ExpModel.cc b/IOMC/Elegent/src/ExpModel.cc new file mode 100644 index 00000000000..9550afcf6aa --- /dev/null +++ b/IOMC/Elegent/src/ExpModel.cc @@ -0,0 +1,62 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/ExpModel.h" +#include "interface/Constants.h" + +using namespace Elegent; + +//---------------------------------------------------------------------------------------------------- + +ExpModel::ExpModel() +{ + fullLabel.name = "exponential"; shortLabel.name = "exp"; +} + +//---------------------------------------------------------------------------------------------------- + +void ExpModel::Configure() +{ + fullLabel.variant = ""; shortLabel.variant = ""; + fullLabel.version = ""; shortLabel.version = ""; + fullLabel.mode = ""; shortLabel.mode = ""; +} + +//---------------------------------------------------------------------------------------------------- + +void ExpModel::Init() +{ + a = 2E9; + b1 = 10.; + b2 = 0.; + p0 = M_PI/2.; + p1 = 0.; +} + +//---------------------------------------------------------------------------------------------------- + +void ExpModel::Print() const +{ + printf(">> ExpModel::Print\n"); + printf("\ta=%E\n", a); + printf("\tb1=%E, b2=%E\n", b1, b2); + printf("\tp0=%E, p1=%E\n", p0, p1); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex ExpModel::Prf(double ) const +{ + // this function is not planned to be used + printf(">> ExpModel::Prf > not implemented.\n"); + return 0.; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex ExpModel::Amp(double t) const +{ + return a * TComplex::Exp( b1*t + b2*t*t + i*(p0 + p1*t) ); +} diff --git a/IOMC/Elegent/src/Generator.cc b/IOMC/Elegent/src/Generator.cc new file mode 100644 index 00000000000..60c0184d59c --- /dev/null +++ b/IOMC/Elegent/src/Generator.cc @@ -0,0 +1,165 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/Generator.h" + +#include "HepMC/GenEvent.h" + +#include + +#include "TGraph.h" +#include "TFile.h" +#include "TClass.h" +#include "TRandom2.h" + + +using namespace std; +using namespace HepMC; +using namespace Elegent; + +//---------------------------------------------------------------------------------------------------- + +Generator::Generator(const string &_file, const string &_path, double _t_min, double _t_max, unsigned int _verbosity) : + fileName(_file), modelPath(_path), t_min(_t_min), t_max(_t_max), verbosity(_verbosity) +{ +} + +//---------------------------------------------------------------------------------------------------- + +unsigned int Generator::Init() +{ + // try to open the file + TFile file(fileName.c_str()); + if (file.IsZombie()) + { + printf("ERROR in Elegent::Generator::Init > File `%s' can not be loaded.\n", fileName.c_str()); + return 1; + } + + // get cms energy + TGraph *data = (TGraph *) file.Get("data"); + if (!data) + { + printf("ERROR in Elegent::Generator::Init > File `%s' does not contain `data' object.\n", fileName.c_str()); + return 2; + } + double dummy; + data->GetPoint(0, dummy, E_cms); + + // try to load sigma_int graph + TObject *o = file.Get(modelPath.c_str()); + if (!o || !o->IsA()->InheritsFrom("TGraph")) + { + file.ls(); + printf("ERROR in Elegent::Generator::Init > Model `%s' not found.\n", modelPath.c_str()); + return 3; + } + TGraph *sigma_int = (TGraph*) o; + + // prepare normalized inverse c.d.f + int i_min = 0, i_max = sigma_int->GetN() - 1; // default index range + for (int i = 0; i < sigma_int->GetN(); i++) + { + double x, y; + sigma_int->GetPoint(i, x, y); + if (x < t_min) + i_min = i; + if (x > t_max) + { + i_max = i; + break; + } + } + + double p_min = 0., p_max = 0.; + double t_min_real = 0., t_max_real = 0.; + sigma_int->GetPoint(i_min, t_min_real, p_min); + sigma_int->GetPoint(i_max, t_max_real, p_max); + + if (verbosity > 0) + { + printf(">> Elegent::Generator > inverse cdf:\n\tfile: %s\n\tmodel: %s\n", fileName.c_str(), modelPath.c_str()); + printf("\trequested |t| range: %.2E to %.2E GeV^2\n", t_min, t_max); + printf("\tpoints loaded: %i\n", i_max - i_min + 1); + printf("\t\tfirst point: idx = %i, |t| = %.2E GeV^2, p = %.2E mb\n", i_min, t_min_real, p_min); + printf("\t\tlast point: idx = %i, |t| = %.2E GeV^2, p = %.2E mb\n", i_max, t_max_real, p_max); + printf("\t|t| range: %.2E to %.2E GeV^2\n", t_min_real, t_max_real); + printf("\tcorresponding cross-section: %.2E mb\n", p_max - p_min); + } + + if (i_min >= i_max) + { + printf("ERROR in Elegent::Generator::Init > Wrong (t_min, t_max) region (%.2E, %.2E) or empty intersection with CDF domain.\n", t_min, t_max); + return 4; + } + + icdf = new TGraph(); + for (int i = i_min; i <= i_max; i++) + { + double x, y; + sigma_int->GetPoint(i, x, y); + icdf->SetPoint(icdf->GetN(), (y - p_min) / (p_max - p_min), x); + } + + // precompute kinematics + double m = 0.938; // GeV + p_cms = sqrt(E_cms*E_cms - m*m); + if (verbosity > 0) + { + printf("\n>> Elegent::Generator > proton kinematics in CM frame (in GeV)\n"); + printf("\tE = %.3f\n", E_cms); + printf("\tp = %.3f\n", p_cms); + printf("\tm = %.3f\n", m); + } + + return 0; +} + +//---------------------------------------------------------------------------------------------------- + +void Generator::GenerateBase(double rn1, double rn2, GenEvent* gEv) +{ + gEv->set_signal_process_id(Generator::ElasticScattering); + + // create vertex at t = 0, position 0; + GenVertex* gVx = new GenVertex(FourVector(0., 0., 0., 0.)); + gEv->add_vertex(gVx); + + // generation + double p = 0., t = 0., phi = 0., theta = 0.; + p = rn1; + t = icdf->Eval(p); // |t| + phi = rn2 * 2. * M_PI; + + theta = sqrt(t) / p_cms; + + // kinematics collison in CM frame + double p_x = p_cms * sin(theta) * cos(phi); + double p_y = p_cms * sin(theta) * sin(phi); + double p_z = p_cms * cos(theta); + + if (verbosity > 5) + { + if (verbosity > 6) + printf("prob = %.3f\n", p); + printf("|t| = %.2E GeV^2, theta = %.2E\n", t, theta); + printf("phi = %.2E, theta_x = %.2E, theta_y = %.2E\n", phi, theta*cos(phi), theta*sin(phi)); + printf("px = %.2E, py = %.2E, pz = %.2E\n", p_x, p_y, p_z); + } + + // add initial and final particles to the vertex + GenParticle* gPe; + gPe = new GenParticle(HepMC::FourVector(0., 0., p_cms, E_cms), PID, NullState); gPe->suggest_barcode(1); gVx->add_particle_in(gPe); + gPe = new GenParticle(HepMC::FourVector(0., 0., -p_cms, E_cms), PID, NullState); gPe->suggest_barcode(2); gVx->add_particle_in(gPe); + gPe = new GenParticle(HepMC::FourVector(p_x, p_y, p_z, E_cms), PID, FinalState); gPe->suggest_barcode(3); gVx->add_particle_out(gPe); + gPe = new GenParticle(HepMC::FourVector(-p_x, -p_y, -p_z, E_cms), PID, FinalState); gPe->suggest_barcode(4); gVx->add_particle_out(gPe); +} + +//---------------------------------------------------------------------------------------------------- + +void Generator::Generate(GenEvent* gEv) +{ + GenerateBase(gRandom->Rndm(), gRandom->Rndm(), gEv); +} diff --git a/IOMC/Elegent/src/InterpolationModel.cc b/IOMC/Elegent/src/InterpolationModel.cc new file mode 100644 index 00000000000..0414ec4cdfe --- /dev/null +++ b/IOMC/Elegent/src/InterpolationModel.cc @@ -0,0 +1,53 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/InterpolationModel.h" + +#include "TGraph.h" + +namespace Elegent +{ + +//#define DEBUG 1 + +//---------------------------------------------------------------------------------------------------- + +InterpolationModel::InterpolationModel(unsigned int _N, double _t_min, double _t_max) : + N(_N), t_min(_t_min), t_max(_t_max), dt( (t_max - t_min) / (N-1) ), amp_data(N) +{ + fullLabel.name = "Interpolation"; shortLabel.name = "itpl"; +} + +//---------------------------------------------------------------------------------------------------- + +void InterpolationModel::Configure() +{ +} + +//---------------------------------------------------------------------------------------------------- + +InterpolationModel::~InterpolationModel() +{ +} + +//---------------------------------------------------------------------------------------------------- + +void InterpolationModel::Print() const +{ + printf(">> InterpolationModel::Print\n"); + printf("\tN = %u, t_min = %.3E, t_max = %.3E\n", N, t_min, t_max); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex InterpolationModel::Prf(double) const +{ + // this function is not planned to be used + printf(">> InterpolationModel::Prf > not implemented.\n"); + return 0.; +} + + +} // namespace diff --git a/IOMC/Elegent/src/IslamModel.cc b/IOMC/Elegent/src/IslamModel.cc new file mode 100644 index 00000000000..a0aba0ec084 --- /dev/null +++ b/IOMC/Elegent/src/IslamModel.cc @@ -0,0 +1,453 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/IslamModel.h" +#include "interface/Math.h" +#include "interface/Constants.h" + +using namespace std; +using namespace Elegent; + +//#define DEBUG 1 + +//---------------------------------------------------------------------------------------------------- + +IslamModel::IslamModel() +{ + fullLabel.name = "Islam et al."; shortLabel.name = "islam"; +} + +//---------------------------------------------------------------------------------------------------- + +void IslamModel::Configure(IslamModel::VariantType _v, IslamModel::ModeType _m) +{ + variant = _v; + mode = _m; + + if (variant == vHP) + { + fullLabel.variant = "HP"; shortLabel.variant = "hp"; + } + + // low-x gluons variant + if (variant == vLxG) + { + fullLabel.variant = "LxG"; shortLabel.variant = "lxg"; + } + + // set labels + fullLabel.version = "Int. J. Mod. Phys. A21 (2006) 1-42, Mod. Phys. Lett. A24 (2009) 485-496"; shortLabel.version = "06,09"; + + if (mode == mDiff) + { fullLabel.mode = "diffraction"; shortLabel.mode = "diff"; } + if (mode == mCore) + { fullLabel.mode = "core"; shortLabel.mode = "core"; } + if (mode == mQuark) + { fullLabel.mode = "quark-quark"; shortLabel.mode = "quark"; } + if (mode == mDiffCore) + { fullLabel.mode = "diffraction+core"; shortLabel.mode = "diff+core"; } + if (mode == mFull) + { fullLabel.mode = "full"; shortLabel.mode = "full"; } +} + +//---------------------------------------------------------------------------------------------------- + +void IslamModel::Init() +{ + // ---------- diffraction amplitude ---------- + // parameters from page 23 of [4] + double R0 = 2.77; + double R1 = 0.0491; + double a0 = 0.245; + double a1 = 0.126; + R = TComplex(R0 + R1*cnts->ln_s, -R1*cnts->pi/2); + a = TComplex(a0 + a1*cnts->ln_s, -a1*cnts->pi/2); + + double et0 = 0.0844; + double c0 = 0.0; + double si = 2.7; + + // function g(s) according to Eq. (4.2) in [4] + TComplex g_s = (1. - CEF(et0, c0, si)) * (1. + TComplex::Exp(-R/a)) / (1. - TComplex::Exp(-R/a)); + Diff_fac = i * cnts->sqrt_s * cnts->p_cms * g_s; + Diff_fac_profile = g_s * i/2.; + + // ---------- absorbtion factor due to diffraction ---------- + + // parameters from page 23 of [4] + double la0 = 0.727; + double d0 = 13.; + double al = 0.246; + double hga0 = 1.53; + double hga1 = 0.; + double hsi = 1.46; + + if (cnts->pMode == cnts->mPP) + Abs_fac = cnts->s * CEF(hga0, hga1, hsi) * ( CEF(et0, c0, si) + i*CEF(la0, -d0, al) ); + + if (cnts->pMode == cnts->mAPP) + Abs_fac = cnts->s * CEF(hga0, hga1, hsi) * ( CEF(et0, c0, si) - i*CEF(la0, -d0, al) ); + + // ---------- core amplitude ---------- + // parameters from page 23 of [4] + beta = 3.075; + double m_omega = 0.801; + m_omega_sq = m_omega * m_omega; + + if (cnts->pMode == cnts->mPP) + Core_fac = -1; + + if (cnts->pMode == cnts->mAPP) + Core_fac = +1; + + // ---------- quark-quark amplitude ---------- + + // parameter from page 25 of [4] + m0sq = 12.; + + // hard pomeron variant + if (variant == vHP) + { + // parameters from page 25 of [4] + double tgaqq = 0.03; + omega = 0.15; + r0 = 2.; + + // the factor (without s) multiplying the 2nd term in the 2nd brackets in Eq. (6.3) in [4] + Quark_fac = i * tgaqq * TComplex::Power(-i * cnts->s, omega); + + Quark_const = -2. * tgaqq * TComplex::Power(-i * cnts->s, omega); + + // Born term only by default + qqMaxOrder = 1; + } + + // low-x gluons variant + if (variant == vLxG) + { + double tgagg = 0.0056; // TODO: no reference found! + + // parameters from page 8 of [5] + lambda = 0.29; + m_c = 1.67; + + // the factor (without is) multiplying the fraction in Eq. (32) in [5] + cgc_fac = tgagg * TComplex::Power(-i * cnts->s, lambda); + + // Born term only by default + cgcMaxOrder = 1; + } + + // integration parameters + precision = 1E-11; + precision_t = 1E-4; + upper_bound = 50.; + upper_bound_t = -15.; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::CEF(double a, double b, double c) +{ + // crossing-even function: + // a + b / (s exp(-i pi/2))^c + // = a + b / (-i s)^c = a + b (-i s)^(-c) + return a + b * TComplex::Power(-i * cnts->s, -c); +} + +//---------------------------------------------------------------------------------------------------- + +void IslamModel::Print() const +{ + printf(">> IslamModel::Print\n"); + printf("\t%s\n", CompileFullLabel().c_str()); + printf("\tdiffraction variables\n"); + double v1 = R.Im(); v1 = -v1 * 2 / cnts->pi; + double v0 = R.Re(); v0 -= v1 * cnts->ln_s; + printf("\t\tR0=%f, R1=%f\n", v0, v1); + v1 = a.Im(); v1 = -v1 * 2 / cnts->pi; + v0 = a.Re(); v0 -= v1 * cnts->ln_s; + printf("\t\ta0=%f, a1=%f\n", v0, v1); + printf("\t\tR: Re=%E, Im=%E\n", R.Re(), R.Im()); + printf("\t\ta: Re=%E, Im=%E\n", a.Re(), a.Im()); + printf("\t\tDiff_fac_profile: Re=%E, Im=%E\n", Diff_fac_profile.Re(), Diff_fac_profile.Im()); + printf("\t\tDiff_fac: Re=%E, Im=%E\n", Diff_fac.Re(), Diff_fac.Im()); + printf("\t\tAbs_fac: Re=%E, Im=%E\n", Abs_fac.Re(), Abs_fac.Im()); + + printf("\tcore scattering variables\n"); + printf("\t\tbeta = %E\n", beta); + printf("\t\tm_omega_sq = %E\n", m_omega_sq); + printf("\t\tCore_fac = %E\n", Core_fac); + + printf("\tquark-quard scattering variables\n"); + printf("\t\tm0sq = %E\n", m0sq); + printf("\t\tr0 = %E\n", r0); + printf("\t\tomega = %E\n", omega); + printf("\t\tQuark_fac: Re=%E, Im=%E\n", Quark_fac.Re(), Quark_fac.Im()); + printf("\t\tQuark_const: Re=%E, Im=%E\n", Quark_const.Re(), Quark_const.Im()); + printf("\t\tqqMaxOrder = %i\n", qqMaxOrder); + printf("\t\tlambda = %E\n", lambda); + printf("\t\tm_c = %E\n", m_c); + printf("\t\tcgc_fac: Re=%E, Im=%E\n", cgc_fac.Re(), cgc_fac.Im()); + printf("\t\tcgcMaxOrder = %i\n", cgcMaxOrder); + + printf("\tintegration variables\n"); + printf("\t\tprecision = %E\n", precision); + printf("\t\tprecision_t = %E\n", precision_t); + printf("\t\tupper_bound = %E\n", upper_bound); + printf("\t\tupper_bound_t = %E\n", upper_bound_t); +} + +//-------------------------------------- DIFFRACTION AMPLITUDE ------------------------------------ + +TComplex IslamModel::GammaD(double b) const +{ + /// b-dependent part of profile function Gamma_D^+ in Eq. (2.7) in [4] + /// b... impact parameter in fm + return 1. / (1. + TComplex::Exp((b - R) / a)) + 1. / (1. + TComplex::Exp((-b - R) / a)) - 1.; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::GammaD_J0(double *b, double *t, const void *obj) +{ + /// b[0] ... impact parameter in fm + /// t[0] ... t in GeV^2 + return ((IslamModel *)obj)->GammaD(b[0]) * b[0] * TMath::BesselJ0(b[0]*sqrt(-t[0])); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_diff(double t) const +{ +#ifdef DEBUG + printf(">> IslamModel::T_diff\n"); +#endif + + /// t < 0 + return Diff_fac * CmplxInt(this, GammaD_J0, 0, upper_bound, &t, precision); +} + +//----------------------------------------- CORE AMPLITUDE ---------------------------------------- + +double IslamModel::F_sq(double t) const +{ + /// formfactor, t < 0 + return beta * sqrt(m_omega_sq - t) * TMath::BesselK1(beta * sqrt(m_omega_sq - t)); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_core(double t) const +{ +#ifdef DEBUG + printf(">> IslamModel::T_core\n"); +#endif + + /// t < 0 + return Core_fac * Abs_fac * F_sq(t) / (m_omega_sq - t); +} + + +//---------------------------------------- QUARK AMPLITUDE ---------------------------------------- + +double IslamModel::I_integral(double qt, double al) const +{ + double ap = qt/2./al; + double a = sqrt(ap * ap + 1.); + double ival; + + // for small qt values just substitute limit value 16/3 + if (qt > 1E-10) + ival = ( 2./a/a + 1./ap/ap - 3.*ap*ap/a/a/a/a ) / a/ap * log(a + ap) - 1./a/a/ap/ap + 3./a/a/a/a; + else ival = 16./3.; + + return 1./8. /al/al/al/al * ival; +} + +//---------------------------------------------------------------------------------------------------- + +double IslamModel::F_cal_integ(double *x, double *par, const void *obj) +{ + double &qt = par[0]; + double &n = par[1]; + double &omega = par[2]; + double &m0sq = par[3]; + double al_sq = m0sq/4. + cnts->M_sq * x[0] * x[0]; + double al = sqrt(al_sq); + return exp((1. + n * omega) * log(x[0])) / al_sq * ((IslamModel *)obj)->I_integral(qt, al); +} + +//---------------------------------------------------------------------------------------------------- + +double IslamModel::F_cal(int n, double qt, double omega, double m0sq) const +{ + double par[4]; + par[0] = qt; + par[1] = n; + par[2] = omega; + par[3] = m0sq; + return cnts->M * exp(2.5 * log(m0sq)) / 8. / cnts->pi * DoubleInt(this, F_cal_integ, 0., 1., par, 1E-9); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_quark(double t) const +{ + switch (variant) + { + case vHP: return T_hp(t); + case vLxG: return T_lxg(t); + default: + printf("ERROR in IslamModel::T_quark > unknown variant %i\n", variant); + return 0.; + } +} + +//---------------------------------------------------------------------------------------------------- + +double IslamModel::T_hp_integ(double *bArr, double *par, const void *obj) +{ + double &b = bArr[0]; + double &q = par[0]; // par[0] ... q + double &n = par[1]; // par[1] ... n + return b * TMath::BesselJ0(b * q) * pow( TMath::BesselK0(b / ((IslamModel *)obj)->r0) , n); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_hp_n(int n, double t) const +{ + double q = sqrt(fabs(t)); + + if (n == 1) + return Quark_fac / (-t + 1./r0/r0); + + if (n == 2) + { + if (q < 1E-2) + return i * Quark_fac*Quark_fac * r0*r0*r0/4.; // limit + else + return i * Quark_fac*Quark_fac * 2. * asinh(q * r0 / 2.) / q / sqrt( fabs(t) + 4./r0/r0 ); + } + + // general formula + double par[2]; + par[0] = q; + par[1] = n; + + // correct -i + return -i / 2. / TMath::Factorial(n) * TComplex::Power(Quark_const, n) * DoubleInt(this, T_hp_integ, 0., 30., par, 1E-9); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_hp(double t) const +{ +#ifdef DEBUG + printf(">> IslamModel::T_hp\n"); +#endif + + /// t < 0 + double qt = sqrt(-t * (-t / cnts->t_min + 1.)); + + TComplex sum = 0.; + for (int j = 1; j <= qqMaxOrder; j++) + { + double F = F_cal(j, qt, omega, m0sq); + sum += F*F * T_hp_n(j, t); + } + + return Abs_fac * sum; +} + +//------------------------------------ CGC AMPLITUDE ------------------------------------------------- + +double IslamModel::T_lxg_integ(double *bArr, double *par, const void *obj) +{ + double &b = bArr[0]; + double &q = par[0]; // par[0] ... q + double &n = par[1]; // par[1] ... n + double &m_c = ((IslamModel *)obj)->m_c; + return b * TMath::BesselJ0(b * q) * pow(exp(-b * m_c) * m_c*m_c * (1. + b*m_c) / 3., n); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_lxg_n(int n, double t) const +{ + double q = sqrt(fabs(t)); + + if (n == 1) + return i * cgc_fac / pow(1. - t/m_c/m_c, 2.5); + + // general formula + double par[2]; + par[0] = q; + par[1] = n; + return i * pow(-2., n - 1) / TMath::Factorial(n) * TComplex::Power(cgc_fac, n) * DoubleInt(this, T_lxg_integ, 0., 30., par, 1E-9); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::T_lxg(double t) const +{ +#ifdef DEBUG + printf(">> IslamModel::T_lxg\n"); +#endif + + /// t < 0 + double qt = sqrt(-t * (-t / cnts->t_min + 1.)); + + TComplex sum = 0.; + for (int j = 1; j <= cgcMaxOrder; j++) + { + double F = F_cal(j, qt, lambda, m0sq); + sum += F*F * T_lxg_n(j, t); + } + + return Abs_fac * sum; +} + +//---------------------------------------------------------------------------------------------------- +//----------------------------------------- FULL AMPLITUDE ---------------------------------------- + +TComplex IslamModel::Amp(double t) const +{ +#ifdef DEBUG + printf(">> IslamModel::amp, mode = %i\n", mode); +#endif + + switch (mode) + { + case mDiff: return T_diff(t); + case mCore: return T_core(t); + case mQuark: return T_quark(t); + case mDiffCore: return T_diff(t) + T_core(t); + case mFull: return T_diff(t) + T_core(t) + T_quark(t); + default: + printf("ERROR in IslamModel::Amp > unknown mode %i\n", mode); + return 0.; + } +} + + +//---------------------------------------------------------------------------------------------------- +//---------------------------------------- PROFILE FUNCTIONS -------------------------------------- + +TComplex IslamModel::Amp_J0(double *t, double *b, const void *obj) +{ + /// b[0] ... impact parameter in fm + /// t[0] ... t in GeV^2 + return ((IslamModel *)obj)->Amp(t[0]) * TMath::BesselJ0(b[0]*sqrt(-t[0])); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex IslamModel::Prf(double b_fm) const +{ + double b = b_fm / cnts->hbarc; // b in GeV^-1 + return CmplxInt(this, Amp_J0, upper_bound_t, 0., &b, precision_t) / 4. / cnts->p_cms / cnts->sqrt_s; +} diff --git a/IOMC/Elegent/src/JenkovszkyModel.cc b/IOMC/Elegent/src/JenkovszkyModel.cc new file mode 100644 index 00000000000..6640e806283 --- /dev/null +++ b/IOMC/Elegent/src/JenkovszkyModel.cc @@ -0,0 +1,137 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/JenkovszkyModel.h" +#include "interface/Constants.h" +#include "interface/Math.h" + +using namespace Elegent; + +JenkovszkyModel::JenkovszkyModel() +{ + fullLabel.name = "Jenkovszky et al."; shortLabel.name = "jenkovszky"; +} + +//---------------------------------------------------------------------------------------------------- + +void JenkovszkyModel::Configure() +{ + // set labels + fullLabel.variant = ""; shortLabel.variant = ""; + fullLabel.version = "Int. J. Mod. Phys. A 26 (2011) 4755"; shortLabel.version = "11"; + fullLabel.mode = ""; shortLabel.mode = ""; +} + +//---------------------------------------------------------------------------------------------------- + +void JenkovszkyModel::Init() +{ + // fit parameters from Table 3 (corresponding to trajectory (8)), + // reggeon trajectories given under Eq. (4) in [1] + + a_P = 261.966; + b_P = 8.40969; // GeV^-2 + de_P = 0.0504675; + al1_P = 0.436108; + ep_P = 0.0152887; + s_P = 100.; // GeV^2 + + a_O = 0.0875234; + b_O = 14.226; + de_O = 0.172615; + al1_O = 0.0434551; + s_O = 100.; // GeV^2 + + a_om = 8.21009; + b_om = 23.81201; // GeV^-2 + s_om = 1.; // GeV^2 + al0_om = 0.43; + al1_om = 0.93; + + a_f = -12.6303; + b_f = 4.35673; // GeV^-2 + s_f = 1.; // GeV^2 + al0_f = 0.70; + al1_f = 0.84; + + precision_t = 1E-4; + upper_bound_t = -50.; +} + +//---------------------------------------------------------------------------------------------------- + +void JenkovszkyModel::Print() const +{ + printf(">> JenkovszkyModel::Print\n"); + printf("\t%s\n", CompileFullLabel().c_str()); + printf("\tpomeron:\n\t\ta_P=%.3E, b_P=%.3E, de_P=%.3E, al1_P=%.3E, ep_P=%.3E, s_P=%.3E\n", a_P, b_P, de_P, al1_P, ep_P, s_P); + printf("\todderon:\n\t\ta_O=%.3E, b_O=%.3E, de_O=%.3E, al1_O=%.3E, s_O=%.3E\n", a_O, b_O, de_O, al1_O, s_O); + printf("\tomega:\n\t\ta_om=%.3E, b_om=%.3E, s_om=%.3E, al0_om=%.3E, al1_om=%.3E\n", a_om, b_om, s_om, al0_om, al1_om); + printf("\tf:\n\t\ta_f=%.3E, b_f=%.3E, s_f=%.3E, al0_f=%.3E, al1_f=%.3E\n", a_f, b_f, s_f, al0_f, al1_f); + printf("\tupper_bound_t=%.3E, precision_t=%.3E\n", upper_bound_t, precision_t); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex JenkovszkyModel::Amp(double t) const +{ + double s_eff = 0.; + + // pomeron + s_eff = cnts->s / s_P; + double al_P = 1. + de_P + al1_P*t; // TR.1 + TComplex r_1_sq = b_P + log(s_eff) - i*M_PI/2.; + TComplex r_2_sq = log(s_eff) - i*M_PI/2.; + TComplex A_P = i * a_P/b_P * s_eff * ( + r_1_sq * TComplex::Exp(r_1_sq * (al_P - 1.)) + - ep_P * r_2_sq * TComplex::Exp(r_2_sq * (al_P - 1.)) + ); + + // odderon + s_eff = cnts->s / s_O; + double al_O = 1. + de_O + al1_O*t; // TR.1 + TComplex rO_1_sq = b_O + log(s_eff) - i*M_PI/2.; + // NB: wrong sign in Eq (8) in arXiv: 1105.1202v1 + TComplex A_O = - a_O/b_O * s_eff * ( + rO_1_sq * TComplex::Exp(rO_1_sq * (al_O - 1.)) + ); + + if (cnts->pMode == cnts->mPP) + A_O = -A_O; + + // omega + s_eff = cnts->s / s_om; + double al_om = al0_om + al1_om*t; + TComplex A_om = a_om * TComplex::Exp(-i*M_PI/2. * al_om + b_om*t) * pow(s_eff, al_om); + + if (cnts->pMode == cnts->mPP) + A_om = -A_om; + + // f + s_eff = cnts->s / s_f; + double al_f = al0_f + al1_f*t; + TComplex A_f = a_f * TComplex::Exp(-i*M_PI/2. * al_f + b_f*t) * pow(s_eff, al_f); + + //printf("%E | %E, %E | %E, %E\n", t, A_P.Re(), A_P.Im(), A_O.Re(), A_O.Im()); + + return cnts->p_cms/cnts->sqrt_s * (A_P + A_O + A_om + A_f); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex JenkovszkyModel::Amp_J0(double *t, double *b, const void *obj) +{ + /// t[0] ... t in GeV^2 + /// b[0] ... impact parameter in fm + return ((JenkovszkyModel *)obj)->Amp(t[0]) * TMath::BesselJ0(b[0] * sqrt(-t[0])); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex JenkovszkyModel::Prf(double b_fm) const +{ + double b = b_fm / cnts->hbarc; // b in GeV^-1 + return CmplxInt(this, Amp_J0, upper_bound_t, 0., &b, precision_t) / 4. / cnts->p_cms / cnts->sqrt_s; +} diff --git a/IOMC/Elegent/src/Math.cc b/IOMC/Elegent/src/Math.cc new file mode 100644 index 00000000000..be829d8590f --- /dev/null +++ b/IOMC/Elegent/src/Math.cc @@ -0,0 +1,212 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/Math.h" + +namespace Elegent +{ + +double DoubleInt(const void *obj, double (*fcn)(double*, double*, const void*), double a, double b, double *params, double epsilon) +{ + const double Z1 = 1; + const double HF = Z1/2; + const double CST = 5*Z1/1000; + + double x[12] = { 0.96028985649753623, 0.79666647741362674, + 0.52553240991632899, 0.18343464249564980, + 0.98940093499164993, 0.94457502307323258, + 0.86563120238783174, 0.75540440835500303, + 0.61787624440264375, 0.45801677765722739, + 0.28160355077925891, 0.09501250983763744}; + + double w[12] = { 0.10122853629037626, 0.22238103445337447, + 0.31370664587788729, 0.36268378337836198, + 0.02715245941175409, 0.06225352393864789, + 0.09515851168249278, 0.12462897125553387, + 0.14959598881657673, 0.16915651939500254, + 0.18260341504492359, 0.18945061045506850}; + + double h, aconst, bb, aa, c1, c2, u, s8, s16, f1, f2; + double xx[1]; + int i; + + h = 0; + if (b == a) return h; + + aconst = CST/TMath::Abs(b-a); + bb = a; + + CASE1: + aa = bb; + bb = b; + + CASE2: + c1 = HF*(bb+aa); + c2 = HF*(bb-aa); + + s8 = 0; + for (i=0; i<4; i++) { + u = c2*x[i]; + xx[0] = c1+u; + f1 = (*fcn)(xx, params, obj); + xx[0] = c1-u; + f2 = (*fcn)(xx, params, obj); + s8 += w[i]*(f1 + f2); + } + + s16 = 0; + for (i=4; i<12; i++) { + u = c2*x[i]; + xx[0] = c1+u; + f1 = (*fcn)(xx, params, obj); + xx[0] = c1-u; + f2 = (*fcn)(xx, params, obj); + s16 += w[i]*(f1 + f2); + } + + s16 = c2*s16; + + if (TMath::Abs(s16-c2*s8) <= epsilon*(1. + TMath::Abs(s16))) { + h += s16; + if(bb != b) goto CASE1; + } else { + bb = c1; + if(1. + aconst*TMath::Abs(c2) != 1) goto CASE2; + h = s8; //this is a crude approximation (cernlib function returned 0 !) + printf("WARNING in DoubleInt > Crude approximation.\n"); + } + + return h; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex CmplxInt(const void *obj, TComplex (*fcn)(double*, double*, const void *), double a, double b, double *params, double epsilon) +{ + TComplex C; + + const double Z1 = 1; + const double HF = Z1/2; + const double CST = 5*Z1/1000; + + double x[12] = { 0.96028985649753623, 0.79666647741362674, + 0.52553240991632899, 0.18343464249564980, + 0.98940093499164993, 0.94457502307323258, + 0.86563120238783174, 0.75540440835500303, + 0.61787624440264375, 0.45801677765722739, + 0.28160355077925891, 0.09501250983763744}; + + double w[12] = { 0.10122853629037626, 0.22238103445337447, + 0.31370664587788729, 0.36268378337836198, + 0.02715245941175409, 0.06225352393864789, + 0.09515851168249278, 0.12462897125553387, + 0.14959598881657673, 0.16915651939500254, + 0.18260341504492359, 0.18945061045506850}; + + double aconst, bb, aa, c1, c2, u; + double xx[1]; + int i; + + if (b == a) return TComplex(0., 0.); + + // REAL + double Rh, Rs8, Rs16, Rf1, Rf2; + + Rh = 0; + aconst = CST/TMath::Abs(b-a); + bb = a; + + CASE1: + aa = bb; + bb = b; + + CASE2: + c1 = HF*(bb+aa); + c2 = HF*(bb-aa); + + Rs8 = 0; + for (i=0; i<4; i++) { + u = c2 * x[i]; + xx[0] = c1 + u; + C = (*fcn)(xx, params, obj); Rf1 = C.Re(); + xx[0] = c1 - u; + C = (*fcn)(xx, params, obj); Rf2 = C.Re(); + Rs8 += w[i]*(Rf1 + Rf2); + } + + Rs16 = 0; + for (i=4; i<12; i++) { + u = c2 * x[i]; + xx[0] = c1 + u; + C = (*fcn)(xx, params, obj); Rf1 = C.Re(); + xx[0] = c1 - u; + C = (*fcn)(xx, params, obj); Rf2 = C.Re(); + Rs16 += w[i]*(Rf1 + Rf2); + } + + Rs16 = c2*Rs16; + + if (TMath::Abs(Rs16 - c2*Rs8) <= epsilon*(1. + TMath::Abs(Rs16))) { + Rh += Rs16; + if(bb != b) goto CASE1; + } else { + bb = c1; + if (1. + aconst*TMath::Abs(c2) != 1) goto CASE2; + Rh = Rs8; // this is a crude approximation (cernlib function returned 0 !) + printf("WARNING in CmplxInt (real part) > Crude approximation.\n"); + } + + // IMAGINARY + double Ih, Is8, Is16, If1, If2; + + Ih = 0; + aconst = CST/TMath::Abs(b-a); + bb = a; + + CASE1I: + aa = bb; + bb = b; + + CASE2I: + c1 = HF*(bb+aa); + c2 = HF*(bb-aa); + + Is8 = 0; + for (i=0; i<4; i++) { + u = c2 * x[i]; + xx[0] = c1 + u; + C = (*fcn)(xx, params, obj); If1 = C.Im(); + xx[0] = c1 - u; + C = (*fcn)(xx, params, obj); If2 = C.Im(); + Is8 += w[i]*(If1 + If2); + } + + Is16 = 0; + for (i=4; i<12; i++) { + u = c2 * x[i]; + xx[0] = c1 + u; + C = (*fcn)(xx, params, obj); If1 = C.Im(); + xx[0] = c1 - u; + C = (*fcn)(xx, params, obj); If2 = C.Im(); + Is16 += w[i]*(If1 + If2); + } + + Is16 = c2*Is16; + + if (TMath::Abs(Is16 - c2*Is8) <= epsilon*(1. + TMath::Abs(Is16))) { + Ih += Is16; + if(bb != b) goto CASE1I; + } else { + bb = c1; + if (1. + aconst*TMath::Abs(c2) != 1) goto CASE2I; + Ih = Is8; + printf("WARNING in CmplxInt (imaginary part) > Crude approximation.\n"); + } + + // put it together + return TComplex(Rh, Ih); +} + +} // namespace diff --git a/IOMC/Elegent/src/Model.cc b/IOMC/Elegent/src/Model.cc new file mode 100644 index 00000000000..853cb756e80 --- /dev/null +++ b/IOMC/Elegent/src/Model.cc @@ -0,0 +1,49 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/Model.h" + +using namespace std; + +namespace Elegent +{ + +string Model::CompileShortLabel() const +{ + string out = shortLabel.name; + + if (!shortLabel.mode.empty() && shortLabel.mode.compare("full")) + out += ":" + shortLabel.mode; + + if (!shortLabel.variant.empty()) + out += " (" + shortLabel.variant + ")"; + + out += " [" + shortLabel.version + "]"; + + return out; +} + +//---------------------------------------------------------------------------------------------------- + +string Model::CompileFullLabel() const +{ + string out = fullLabel.name; + + if (!fullLabel.mode.empty() && fullLabel.mode.compare("full")) + out += ":" + fullLabel.mode; + + if (!fullLabel.variant.empty()) + out += " (" + fullLabel.variant + ")"; + + out += " [" + fullLabel.version + "]"; + + return out; +} + +//---------------------------------------------------------------------------------------------------- + +Model *model = NULL; + +} diff --git a/IOMC/Elegent/src/ModelFactory.cc b/IOMC/Elegent/src/ModelFactory.cc new file mode 100644 index 00000000000..1c8e91c6e70 --- /dev/null +++ b/IOMC/Elegent/src/ModelFactory.cc @@ -0,0 +1,79 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/ModelFactory.h" + +using namespace std; + +namespace Elegent +{ + +ModelFactory::ModelFactory() +{ + IslamModel *islam_hp = new IslamModel(); + islam_hp->Configure(IslamModel::vHP, IslamModel::mFull); + model_map[islam_hp->CompileShortLabel()] = islam_hp; + + IslamModel *islam_lxg = new IslamModel(); + islam_lxg->Configure(IslamModel::vLxG, IslamModel::mFull); + model_map[islam_lxg->CompileShortLabel()] = islam_lxg; + + PPPModel *ppp2 = new PPPModel(); + ppp2->Configure(PPPModel::v2P); + model_map[ppp2->CompileShortLabel()] = ppp2; + + PPPModel *ppp3 = new PPPModel(); + ppp3->Configure(PPPModel::v3P); + model_map[ppp3->CompileShortLabel()] = ppp3; + + BSWModel *bsw = new BSWModel(); + bsw->Configure(BSWModel::mPomReg); + model_map[bsw->CompileShortLabel()] = bsw; + + BHModel *bh = new BHModel(); + bh->Configure(); + model_map[bh->CompileShortLabel()] = bh; + + JenkovszkyModel *jenkovszky = new JenkovszkyModel(); + jenkovszky->Configure(); + model_map[jenkovszky->CompileShortLabel()] = jenkovszky; +} + +//---------------------------------------------------------------------------------------------------- + +void ModelFactory::PrintList() const +{ + printf(">> ModelFactory::PrintList > available models:\n"); + + for (map::const_iterator it = model_map.begin(); it != model_map.end(); ++it) + { + printf("\t%s : %s\n", it->first.c_str(), it->second->CompileFullLabel().c_str()); + } +} + +//---------------------------------------------------------------------------------------------------- + +Model* ModelFactory::MakeInstance(const std::string &tag, bool callInit) const +{ + // look for tag in model map + map::const_iterator it = model_map.find(tag); + Model* model = (it == model_map.end()) ? NULL : it->second; + + // if not found print all possibilities + if (model == NULL) + { + printf("ERROR in ModelFactory::MakeInstance: model tag `%s' not available\n", tag.c_str()); + PrintList(); + return NULL; + } + + // initialise model + if (callInit) + model->Init(); + + return model; +} + +} // namespace diff --git a/IOMC/Elegent/src/PPPModel.cc b/IOMC/Elegent/src/PPPModel.cc new file mode 100644 index 00000000000..939b53b622c --- /dev/null +++ b/IOMC/Elegent/src/PPPModel.cc @@ -0,0 +1,154 @@ +/************************************************** + * This file is a part of the Elegent package: + * http://elegent.hepforge.org/ + *************************************************/ + +#include "interface/PPPModel.h" +#include "interface/Math.h" +#include "interface/Constants.h" + +using namespace std; +using namespace Elegent; + +//---------------------------------------------------------------------------------------------------- + +PPPModel::PPPModel() +{ + fullLabel.name = "Petrov et al."; shortLabel.name = "petrov"; +} + +//---------------------------------------------------------------------------------------------------- + +void PPPModel::Configure(PPPModel::VariantType _v) +{ + variant = _v; + + if (variant == v2P) + { + fullLabel.variant = "2P"; shortLabel.variant = "2p"; + } + + if (variant == v3P) + { + fullLabel.variant = "3P"; shortLabel.variant = "3p"; + } + + if (variant != v2P && variant != v3P) + printf("ERROR in PPPModel::Init > Unknown variant %u.\n", variant); + + // set labels + fullLabel.version = "Eur. Phys. J. C23 (2002) 135-143"; shortLabel.version = "02"; + fullLabel.mode = ""; shortLabel.mode = ""; +} + +//---------------------------------------------------------------------------------------------------- + +void PPPModel::SetTrajectory(Trajectory &t, double D, double c, double ap, double r2, double s0) +{ + t.D = D; t.c = c; t.ap = ap; t.r2 = r2; + + // now pre-compute rho2 and gamma factor + // physics must be already intialized !!! + t.rho2 = 4. * t.ap * log(cnts->s/s0) + t.r2; + t.gamma = t.c / s0 * TComplex::Power(-i * cnts->s/s0, t.D); +} + +//---------------------------------------------------------------------------------------------------- + +void PPPModel::Init() +{ + // physics parameters + s0 = 1.; // in GeV^2 + + // Delta c a' r^2 + // 1 1 GeV^2 GeV^2 + if (variant == v2P) + { + // two pomerons + SetTrajectory(pom1, 0.08590, 53.18, 0.360, 9.595, s0); + SetTrajectory(pom2, 0.14437, 6.87, 0.082, 4.765, s0); + SetTrajectory(oder, -0.2707, 1.8134, 0.029, 1.159, s0); + SetTrajectory(regf, -0.3100, 188.51, 0.84, 41.424, s0); + SetTrajectory(rego, -0.5300, -171.36, 0.93, 2.621, s0); + } + + if (variant == v3P) + { + // three pomerons + SetTrajectory(pom1, 0.0578, 53.007, 0.5596, 6.3096, s0); + SetTrajectory(pom2, 0.1669, 9.6762, 0.2733, 3.1097, s0); + SetTrajectory(pom3, 0.2032, 1.6654, 0.0937, 2.4771, s0); + SetTrajectory(oder, 0.1920, 0.0166, 0.048, 0.1398, s0); + SetTrajectory(regf, -0.31, 191.69, 0.84, 31.593, s0); + SetTrajectory(rego, -0.53, -174.18, 0.93, 7.467, s0); + } + + // integration parameters + precision = 1E-14; + upper_bound = 60.; +} + +//---------------------------------------------------------------------------------------------------- + +void PPPModel::Print() const +{ + printf(">> PPPModel::Print\n"); + printf("\t%s\n", CompileFullLabel().c_str()); + printf("\tvariant: %u\n", variant); + + printf("\tpom1: delta=%.4f, c=%.4f, a'=%.4f, r^2=%.4f\n", pom1.D, pom1.c, pom1.ap, pom1.r2); + printf("\tpom2: delta=%.4f, c=%.4f, a'=%.4f, r^2=%.4f\n", pom2.D, pom2.c, pom2.ap, pom2.r2); + if (variant == v3P) + printf("\tpom3: delta=%.4f, c=%.4f, a'=%.4f, r^2=%.4f\n", pom3.D, pom3.c, pom3.ap, pom3.r2); + printf("\toder: delta=%.4f, c=%.4f, a'=%.4f, r^2=%.4f\n", oder.D, oder.c, oder.ap, oder.r2); + printf("\tregf: delta=%.4f, c=%.4f, a'=%.4f, r^2=%.4f\n", regf.D, regf.c, regf.ap, regf.r2); + printf("\trego: delta=%.4f, c=%.4f, a'=%.4f, r^2=%.4f\n", rego.D, rego.c, rego.ap, rego.r2); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex PPPModel::tr_eik(Trajectory t, double , double b) const +{ + // delta+-(s, b) ... eq (11), (12) without the leading i + // the s-dependence is now computed during initialization + // therefore any cnts->s change after init() won't have any affect + return t.gamma * exp(- b * b / t.rho2) / (4. * cnts->pi * t.rho2); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex PPPModel::prf0(double b) const +{ + TComplex delta = i*tr_eik(pom1, cnts->s, b) + i*tr_eik(pom2, cnts->s, b) + i*tr_eik(regf, cnts->s, b); + + if (cnts->pMode == cnts->mPP) + delta += tr_eik(oder, cnts->s, b) + tr_eik(rego, cnts->s, b); + else + delta -= tr_eik(oder, cnts->s, b) + tr_eik(rego, cnts->s, b); + + if (variant == v3P) + delta += i*tr_eik(pom3, cnts->s, b); + + return (TComplex::Exp(2.*i*delta) - 1.) / 2. / i; +} + +//---------------------------------------------------------------------------------------------------- + +TComplex PPPModel::Prf(double b) const +{ + return prf0(b / cnts->hbarc); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex PPPModel::prf_J0(double *b, double *t, const void *obj) +{ + return ((PPPModel *)obj)->prf0(b[0]) * b[0] * TMath::BesselJ0(b[0] * sqrt(-t[0])); +} + +//---------------------------------------------------------------------------------------------------- + +TComplex PPPModel::Amp(double t) const +{ + return 2.*cnts->p_cms*cnts->sqrt_s * CmplxInt(this, prf_J0, 0, upper_bound, &t, precision); +} diff --git a/IOMC/Elegent/test/ElegentSourceTest_cfg.py b/IOMC/Elegent/test/ElegentSourceTest_cfg.py new file mode 100644 index 00000000000..6beea81c7c6 --- /dev/null +++ b/IOMC/Elegent/test/ElegentSourceTest_cfg.py @@ -0,0 +1,28 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("ElegentSourceTest") + +# Specify the maximum events to simulate +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(200) +) + +process.load("Configuration.TotemCommon.LoggerMin_cfi") + +# random number seeds +process.load("Configuration.TotemCommon.RandomNumbers_cfi") + +# use particle table +#process.load("SimGeneral.HepPDTESSource.pdt_cfi") + +process.source = cms.Source("EmptySource") + +# Use random number generator service +process.load("Configuration.TotemCommon.RandomNumbers_cfi") + +import IOMC.Elegent.ElegentSource_cfi +process.generator = IOMC.Elegent.ElegentSource_cfi.generator +energy = "4000" +process.generator.fileName = IOMC.Elegent.ElegentSource_cfi.ElegentDefaultFileName(energy) + +process.p1 = cms.Path(process.generator)