19 #include "libxml/parser.h"
20 #include "libxml/xmlmemory.h"
21 #include "libxml/xmlreader.h"
24 #include <TLorentzVector.h>
28 #include "Framework/Conventions/GBuild.h"
41 using namespace std::chrono ;
66 map<string, map<string, Spline *> >::iterator mm_iter = fSplineMap.begin();
67 for( ; mm_iter != fSplineMap.end(); ++mm_iter) {
69 map<string, Spline *> & spl_map_curr_tune = mm_iter->second;
70 map<string, Spline *>::iterator m_iter = spl_map_curr_tune.begin();
71 for( ; m_iter != spl_map_curr_tune.end(); ++m_iter) {
72 Spline * spline = m_iter->second;
76 spl_map_curr_tune.clear();
95 string key = this->BuildSplineKey(alg,interaction);
96 return this->SplineExists(key);
102 if ( fCurrentTune.size() == 0 ) {
103 SLOG(
"XSecSplLst",
pERROR) <<
"Spline requested while CurrentTune not set" ;
108 <<
"Checking for spline: " << key <<
" in tune: " << fCurrentTune;
110 map<string, map<string, Spline *> >::const_iterator
111 mm_iter = fSplineMap.find(fCurrentTune);
112 if(mm_iter == fSplineMap.end()) {
114 <<
"No splines for tune " << fCurrentTune <<
" were found!";
117 const map<string, Spline *> & spl_map_curr_tune = mm_iter->second;
118 bool exists = (spl_map_curr_tune.count(key) == 1);
127 string key = this->BuildSplineKey(alg,interaction);
128 return this->GetSpline(key);
134 if ( fCurrentTune.size() == 0 ) {
135 SLOG(
"XSecSplLst",
pFATAL) <<
"Spline requested while CurrentTune not set" ;
140 <<
"Getting spline: " << key <<
" in tune: " << fCurrentTune;
142 map<string, map<string, Spline *> >::const_iterator
143 mm_iter = fSplineMap.find(fCurrentTune);
144 if(mm_iter == fSplineMap.end()) {
146 <<
"No splines for tune " << fCurrentTune <<
" were found!";
149 const map<string, Spline *> & spl_map_curr_tune = mm_iter->second;
150 map<string, Spline *>::const_iterator
151 m_iter = spl_map_curr_tune.find(key);
152 if(m_iter == spl_map_curr_tune.end()) {
154 <<
"Couldn't find spline: " << key <<
" in tune: " << fCurrentTune;
157 return m_iter->second;
161 const Interaction * interaction,
int nknots,
double e_min,
double e_max)
175 <<
"Creating cross section spline using the algorithm: " << *alg;
177 string key = this->BuildSplineKey(alg,interaction);
182 if (e_min < 0.) e_min = this->Emin();
183 if (e_max < 0.) e_max = this->Emax();
184 if (nknots <= 2) nknots = this->NKnots();
185 assert( e_min < e_max );
187 std::vector<double> xsec( nknots, 0. ) ;
188 std::vector<double> E( nknots, 0. ) ;
201 <<
"Energy threshold for current interaction = " << Ethr <<
" GeV";
204 SLOG(
"XSecSplLst",
pFATAL) <<
"Energy threshold higher than maximum.";
205 SLOG(
"XSecSplLst",
pFATAL) <<
"Energy threshold = " << Ethr <<
" GeV";
206 SLOG(
"XSecSplLst",
pFATAL) <<
"Energy maximum = " << e_max <<
" GeV";
210 int nkb = (Ethr>e_min) ? 5 : 0;
211 int nka = nknots-nkb;
214 double dEb = (Ethr>e_min) ? (Ethr - e_min) / nkb : 0;
215 for(
int i=0; i<nkb; i++) {
216 E[i] = e_min + i*dEb;
219 double E0 = TMath::Max(Ethr,e_min);
222 dEa = (TMath::Log10(e_max) - TMath::Log10(E0)) /(nka-1);
224 dEa = (e_max-E0) /(nka-1);
226 for(
int i=0; i<nka; i++) {
228 E[i+nkb] = TMath::Power(10., TMath::Log10(E0) + i * dEa);
230 E[i+nkb] = E0 + i * dEa;
239 for (
int i = 0; i < nknots; i++) {
240 TLorentzVector p4(0,0,E[i],E[i]);
242 double pz = TMath::Max(0.,E[i]*E[i] - pr_mass*pr_mass);
243 pz = TMath::Sqrt(pz);
248 steady_clock::time_point start = steady_clock::now();
250 xsec[i] = alg->
Integral(interaction);
252 steady_clock::time_point end = steady_clock::now();
254 duration<double> time_span = duration_cast<duration<double>>(end - start);
257 <<
"xsec(E = " << E[i] <<
") = "
258 << (1E+38/
units::cm2)*xsec[i] <<
" x 1E-38 cm^2, evaluated in " << time_span.count() <<
" s";
259 if ( std::isnan(xsec[i]) ) {
262 <<
"xsec(E = " << E[i] <<
") = "
263 << (1E+38/
units::cm2)*xsec[i] <<
" x 1E-38 cm^2"
264 <<
" : converting NaN to 0.0";
272 const double eps_xsec = 1.0e-5;
273 const double xsec_scale = (1.0-eps_xsec);
274 if ( xsec[nknots-1] < xsec[nknots-2]*xsec_scale ) {
276 <<
"Last point oddity: " << key <<
" has "
277 <<
" xsec[nknots-1] " << xsec[nknots-1] <<
" < "
278 <<
" xsec[nknots-2] " << xsec[nknots-2];
283 Spline * spline =
new Spline(nknots, E.data(), xsec.data());
287 map<string, map<string, Spline *> >::iterator
288 mm_iter = fSplineMap.find(fCurrentTune);
289 if(mm_iter == fSplineMap.end()) {
290 map<string, Spline *> spl_map_curr_tune;
291 fSplineMap.insert( map<
string, map<string, Spline *> >::value_type(
292 fCurrentTune, spl_map_curr_tune) );
293 mm_iter = fSplineMap.find(fCurrentTune);
295 map<string, Spline *> & spl_map_curr_tune = mm_iter->second;
296 spl_map_curr_tune.insert( map<string, Spline *>::value_type(key, spline) );
301 map<string, map<string, Spline *> >::const_iterator
302 mm_iter = fSplineMap.find(fCurrentTune);
303 if(mm_iter == fSplineMap.end()) {
305 <<
"No splines for tune " << fCurrentTune <<
" were found!";
308 const map<string, Spline *> & spl_map_curr_tune = mm_iter->second;
309 return (
int) spl_map_curr_tune.size();
314 int n = this->NSplines();
326 if(fNKnots<10) fNKnots = 10;
344 <<
"Saving XSecSplineList as XML in file: " << filename;
346 ofstream outxml(filename.c_str());
347 if(!outxml.is_open()) {
348 SLOG(
"XSecSplLst",
pERROR) <<
"Couldn't create file = " << filename;
351 outxml <<
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
352 outxml << endl << endl;
353 outxml <<
"<!-- generated by genie::XSecSplineList::SaveSplineList() -->";
354 outxml << endl << endl;
356 int uselog = (fUseLogE ? 1 : 0);
357 outxml <<
"<genie_xsec_spline_list "
358 <<
"version=\"3.00\" uselog=\"" << uselog <<
"\">";
359 outxml << endl << endl;
362 map<string, map<string, Spline *> >::const_iterator
363 mm_iter = fSplineMap.begin();
364 for( ; mm_iter != fSplineMap.end(); ++mm_iter) {
366 string tune_name = mm_iter->first;
367 outxml <<
" <genie_tune name=\"" << tune_name <<
"\">";
368 outxml << endl << endl;
371 const map<string, Spline *> & spl_map_curr_tune = mm_iter->second;
372 map<string, Spline *>::const_iterator
373 m_iter = spl_map_curr_tune.begin();
374 for( ; m_iter != spl_map_curr_tune.end(); ++m_iter) {
375 string key = m_iter->first;
380 bool from_init_set =
false;
381 map<string, set<string> >::const_iterator
382 it = fLoadedSplineSet.find(tune_name);
383 if(it != fLoadedSplineSet.end()) {
384 const set<string> & init_set_curr_tune = it->second;
385 from_init_set = (init_set_curr_tune.count(key) == 1);
387 if(from_init_set && !save_init)
continue;
390 Spline * spline = m_iter->second;
391 spline->
SaveAsXml(outxml,
"E",
"xsec", key);
394 outxml <<
" </genie_tune>" << endl;
397 outxml <<
"</genie_xsec_spline_list>" << endl;
409 <<
"Loading splines from: " << filename;
411 <<
"Option to keep pre-existing splines is switched "
412 << ( (keep) ?
"ON" :
"OFF" );
414 if(!keep) fSplineMap.clear();
416 const int kNodeTypeStartElement = 1;
417 const int kNodeTypeEndElement = 15;
418 const int kKnotX = 0;
419 const int kKnotY = 1;
421 xmlTextReaderPtr reader;
423 int ret = 0, val_type = -1, iknot = 0, nknots = 0;
424 double * E = 0, * xsec = 0;
425 string spline_name =
"";
428 reader = xmlNewTextReaderFilename(filename.c_str());
429 if (reader != NULL) {
430 ret = xmlTextReaderRead(reader);
432 xmlChar * name = xmlTextReaderName (reader);
433 xmlChar * value = xmlTextReaderValue (reader);
434 int type = xmlTextReaderNodeType (reader);
435 int depth = xmlTextReaderDepth (reader);
437 if(depth==0 && type==kNodeTypeStartElement) {
438 LOG(
"XSecSplLst",
pDEBUG) <<
"Root element = " << name;
439 if(xmlStrcmp(name, (
const xmlChar *)
"genie_xsec_spline_list")) {
441 <<
"\nXML doc. has invalid root element! [filename: " << filename <<
"]";
445 xmlChar * xvrs = xmlTextReaderGetAttribute(reader,(
const xmlChar*)
"version");
446 xmlChar * xinlog = xmlTextReaderGetAttribute(reader,(
const xmlChar*)
"uselog");
451 <<
"Input x-section spline XML file format version: " << svrs;
453 if (atoi(sinlog.c_str()) == 1) this->SetLogE(
true);
454 else this->SetLogE(
false);
460 if( (!xmlStrcmp(name, (
const xmlChar *)
"genie_tune")) && type==kNodeTypeStartElement) {
461 xmlChar * xtune = xmlTextReaderGetAttribute(reader,(
const xmlChar*)
"name");
463 SLOG(
"XSecSplLst",
pNOTICE) <<
"Loading x-section splines for GENIE tune: " << temp_tune;
467 if( (!xmlStrcmp(name, (
const xmlChar *)
"spline")) && type==kNodeTypeStartElement) {
468 xmlChar * xname = xmlTextReaderGetAttribute(reader,(
const xmlChar*)
"name");
469 xmlChar * xnkn = xmlTextReaderGetAttribute(reader,(
const xmlChar*)
"nknots");
474 SLOG(
"XSecSplLst",
pNOTICE) <<
"Loading spline: " << spline_name;
476 nknots = atoi( snkn.c_str() );
478 E =
new double[nknots];
479 xsec =
new double[nknots];
485 if( (!xmlStrcmp(name, (
const xmlChar *)
"E")) && type==kNodeTypeStartElement) { val_type = kKnotX; }
486 if( (!xmlStrcmp(name, (
const xmlChar *)
"xsec")) && type==kNodeTypeStartElement) { val_type = kKnotY; }
488 if( (!xmlStrcmp(name, (
const xmlChar *)
"#text")) && depth==5) {
489 if (val_type==kKnotX) E [iknot] = atof((
const char *)value);
490 else if (val_type==kKnotY) xsec[iknot] = atof((
const char *)value);
492 if( (!xmlStrcmp(name, (
const xmlChar *)
"knot")) && type==kNodeTypeEndElement) {
495 if( (!xmlStrcmp(name, (
const xmlChar *)
"spline")) && type==kNodeTypeEndElement) {
496 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
497 LOG(
"XSecSplLst",
pINFO) <<
"Done with current spline";
498 for(
int i=0; i<nknots; i++) {
499 LOG(
"XSecSplLst",
pINFO) <<
"xsec[E = " << E[i] <<
"] = " << xsec[i];
508 map<string, map<string, Spline *> >::iterator
509 mm_iter = fSplineMap.find( temp_tune );
510 if(mm_iter == fSplineMap.end()) {
511 map<string, Spline *> spl_map_curr_tune;
512 fSplineMap.insert( map<
string, map<string, Spline *> >::value_type(
513 temp_tune, spl_map_curr_tune) );
514 mm_iter = fSplineMap.find( temp_tune );
516 map<string, Spline *> & spl_map_curr_tune = mm_iter->second;
517 spl_map_curr_tune.insert(
518 map<string, Spline *>::value_type(spline_name, spline) );
519 fLoadedSplineSet[temp_tune].insert(spline_name);
523 ret = xmlTextReaderRead(reader);
525 xmlFreeTextReader(reader);
528 <<
"\nXML file could not be parsed! [filename: " << filename <<
"]";
533 <<
"\nXML file could not be found! [filename: " << filename <<
"]";
544 <<
"Null XSecAlgorithmI - Returning empty spline key";
550 <<
"Null Interaction - Returning empty spline key";
554 string alg_name = alg->
Id().
Name();
555 string param_set = alg->
Id().
Config();
556 string intkey = interaction->
AsString();
558 string key = alg_name +
"/" + param_set +
"/" + intkey;
565 map<string, map<string, Spline *> >::const_iterator
566 mm_iter = fSplineMap.find(fCurrentTune);
567 if(mm_iter == fSplineMap.end()) {
569 <<
"No splines for tune " << fCurrentTune <<
" were found!";
572 const map<string, Spline *> & spl_map_curr_tune = mm_iter->second;
573 vector<string> * keyv =
new vector<string>(spl_map_curr_tune.size());
575 map<string, Spline *>::const_iterator m_iter = spl_map_curr_tune.begin();
576 for( ; m_iter != spl_map_curr_tune.end(); ++m_iter) {
577 string key = m_iter->first;
585 stream <<
"\n ******************* XSecSplineList *************************";
586 stream <<
"\n [-] Options:";
588 stream <<
"\n |-----o UseLogE..................." << fUseLogE;
589 stream <<
"\n |-----o Spline Emin..............." << fEmin;
590 stream <<
"\n |-----o Spline Emax..............." << fEmax;
591 stream <<
"\n |-----o Spline NKnots............." << fNKnots;
594 map<string, map<string, Spline *> >::const_iterator mm_iter;
595 for(mm_iter = fSplineMap.begin(); mm_iter != fSplineMap.end(); ++mm_iter) {
597 string curr_tune = mm_iter->first;
598 stream <<
"\n [-] Available x-section splines for tune: " << curr_tune ;
601 const map<string, Spline *> & spl_map_curr_tune = mm_iter->second;
602 map<string, Spline *>::const_iterator m_iter = spl_map_curr_tune.begin();
603 for( ; m_iter != spl_map_curr_tune.end(); ++m_iter) {
604 string key = m_iter->first;
605 stream <<
"\n |-----o " << key;
void DummyMethodAndSilentCompiler()
Cross Section Calculation Interface.
const KPhaseSpace & PhaseSpace(void) const
string BuildSplineKey(const XSecAlgorithmI *alg, const Interaction *i) const
void SetProbeP4(const TLorentzVector &P4)
void CreateSpline(const XSecAlgorithmI *alg, const Interaction *i, int nknots=-1, double e_min=-1, double e_max=-1)
const vector< string > * GetSplineKeys(void) const
double Threshold(void) const
Energy threshold.
bool SplineExists(const XSecAlgorithmI *alg, const Interaction *i) const
string BoolAsYNString(bool b)
A numeric analysis tool class for interpolating 1-D functions.
void SetMinE(double Ev)
set default minimum energy for xsec splines
TParticlePDG * Probe(void) const
static XSecSplineList * Instance()
string AsString(void) const
Summary information for an interaction.
void Print(ostream &stream) const
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
static constexpr double cm2
void SetNKnots(int nk)
set default number of knots for building the spline
virtual ~XSecSplineList()
void SaveAsXml(const string &filename, bool save_init=true) const
string TrimSpaces(string input)
void SaveAsXml(string filename, string xtag, string ytag, string name="") const
virtual const AlgId & Id(void) const
Get algorithm ID.
static XSecSplineList * fInstance
ostream & operator<<(ostream &stream, const AlgConfigPool &config_pool)
void SetLogE(bool on)
set opt to build splines as f(E) or as f(logE)
InitialState * InitStatePtr(void) const
void SetMaxE(double Ev)
set default maximum energy for xsec splines
enum genie::EXmlParseStatus XmlParserStatus_t
#define SLOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a short string (using the FUNCTION and...
const Spline * GetSpline(const XSecAlgorithmI *alg, const Interaction *i) const
List of cross section vs energy splines.
XmlParserStatus_t LoadFromXml(const string &filename, bool keep=false)
virtual double Integral(const Interaction *i) const =0
string Config(void) const