Spline.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*
3  Copyright (c) 2003-2020, The GENIE Collaboration
4  For the full text of the license visit http://copyright.genie-mc.org
5 
6  Costas Andreopoulos <constantinos.andreopoulos \at cern.ch>
7  University of Liverpool & STFC Rutherford Appleton Laboratory
8 */
9 //____________________________________________________________________________
10 
11 #include <cassert>
12 #include <iomanip>
13 #include <cfloat>
14 
15 #include "libxml/parser.h"
16 #include "libxml/xmlmemory.h"
17 
18 #include <TFile.h>
19 #include <TNtupleD.h>
20 #include <TTree.h>
21 #include <TSQLServer.h>
22 #include <TGraph.h>
23 #include <TMath.h>
24 #include <TH2F.h>
25 #include <TROOT.h>
26 
31 
32 using std::endl;
33 using std::setw;
34 using std::setprecision;
35 using std::setfill;
36 using std::ios;
37 
38 using namespace genie;
39 
41 
42 //___________________________________________________________________________
43 namespace genie
44 {
45  ostream & operator << (ostream & stream, const Spline & spl)
46  {
47  spl.Print(stream);
48  return stream;
49  }
50 }
51 //___________________________________________________________________________
53 {
54  this->InitSpline();
55 }
56 //___________________________________________________________________________
57 Spline::Spline(string filename, string xtag, string ytag, bool is_xml) :
58 TObject()
59 {
60  string fmt = (is_xml) ? "XML" : "ASCII";
61 
62  LOG("Spline", pDEBUG)
63  << "Constructing spline from data in " << fmt << " file: " << filename;
64 
65  this->InitSpline();
66 
67  if(is_xml)
68  this->LoadFromXmlFile(filename, xtag, ytag);
69  else
70  this->LoadFromAsciiFile(filename);
71 }
72 //___________________________________________________________________________
73 Spline::Spline(TNtupleD * ntuple, string var, string cut) :
74 TObject()
75 {
76  LOG("Spline", pDEBUG) << "Constructing spline from data in a TNtuple";
77 
78  this->InitSpline();
79  this->LoadFromNtuple(ntuple, var, cut);
80 }
81 //___________________________________________________________________________
82 Spline::Spline(TTree * tree, string var, string cut) :
83 TObject()
84 {
85  LOG("Spline", pDEBUG) << "Constructing spline from data in a TTree";
86 
87  this->InitSpline();
88  this->LoadFromTree(tree, var, cut);
89 }
90 //___________________________________________________________________________
91 Spline::Spline(TSQLServer * db, string query) :
92 TObject()
93 {
94  LOG("Spline", pDEBUG) << "Constructing spline from data in a MySQL server";
95 
96  this->InitSpline();
97  this->LoadFromDBase(db, query);
98 }
99 //___________________________________________________________________________
100 Spline::Spline(int nentries, double x[], double y[]) :
101 TObject()
102 {
103  LOG("Spline", pDEBUG)
104  << "Constructing spline from the arrays passed to the ctor";
105 
106  this->InitSpline();
107  this->BuildSpline(nentries, x, y);
108 }
109 //___________________________________________________________________________
110 Spline::Spline(int nentries, float x[], float y[]) :
111 TObject()
112 {
113  LOG("Spline", pDEBUG)
114  << "Constructing spline from the arrays passed to the ctor";
115 
116  double * dblx = new double[nentries];
117  double * dbly = new double[nentries];
118 
119  for(int i = 0; i < nentries; i++) {
120  dblx[i] = double( x[i] );
121  dbly[i] = double( y[i] );
122  }
123 
124  this->InitSpline();
125  this->BuildSpline(nentries, dblx, dbly);
126 
127  delete [] dblx;
128  delete [] dbly;
129 }
130 //___________________________________________________________________________
132  TObject(), fInterpolator(0)
133 {
134  LOG("Spline", pDEBUG) << "Spline copy constructor";
135 
136  this->LoadFromTSpline3( *spline.GetAsTSpline(), spline.NKnots() );
137 }
138 //___________________________________________________________________________
139 Spline::Spline(const TSpline3 & spline, int nknots) :
140  TObject(), fInterpolator(0)
141 {
142  LOG("Spline", pDEBUG)
143  << "Constructing spline from the input TSpline3 object";
144 
145  this->LoadFromTSpline3( spline, nknots );
146 }
147 //___________________________________________________________________________
149 {
150  if(fInterpolator) delete fInterpolator;
151 }
152 //___________________________________________________________________________
153 bool Spline::LoadFromXmlFile(string filename, string xtag, string ytag)
154 {
155  LOG("Spline", pDEBUG) << "Retrieving data from file: " << filename;
156 
157  xmlDocPtr xml_doc = xmlParseFile(filename.c_str());
158 
159  if(xml_doc==NULL) {
160  LOG("Spline", pERROR)
161  << "XML file could not be parsed! [filename: " << filename << "]";
162  return false;
163  }
164 
165  xmlNodePtr xmlCur = xmlDocGetRootElement(xml_doc);
166 
167  if(xmlCur==NULL) {
168  LOG("Spline", pERROR)
169  << "XML doc. has null root element! [filename: " << filename << "]";
170  return false;
171  }
172  if( xmlStrcmp(xmlCur->name, (const xmlChar *) "spline") ) {
173  LOG("Spline", pERROR)
174  << "XML doc. has invalid root element! [filename: " << filename << "]";
175  return false;
176  }
177 
178  string name = utils::str::TrimSpaces(
179  utils::xml::GetAttribute(xmlCur, "name"));
180  string snkn = utils::str::TrimSpaces(
181  utils::xml::GetAttribute(xmlCur, "nknots"));
182  int nknots = atoi( snkn.c_str() );
183 
184  LOG("Spline", pINFO)
185  << "Parsing XML spline: " << name << ", nknots = " << nknots;
186 
187  int iknot = 0;
188  double * vx = new double[nknots];
189  double * vy = new double[nknots];
190 
191  xmlNodePtr xmlSplChild = xmlCur->xmlChildrenNode; // <knots>'s
192 
193  // loop over all xml tree nodes that are children of the <spline> node
194  while (xmlSplChild != NULL) {
195  LOG("Spline", pDEBUG)
196  << "Got <spline> children node: " << xmlSplChild->name;
197 
198  // enter everytime you find a <knot> tag
199  if( (!xmlStrcmp(xmlSplChild->name, (const xmlChar *) "knot")) ) {
200 
201  xmlNodePtr xmlKnotChild = xmlSplChild->xmlChildrenNode;
202 
203  // loop over all xml tree nodes that are children of this <knot>
204  while (xmlKnotChild != NULL) {
205  LOG("Spline", pDEBUG)
206  << "Got <knot> children node: " << xmlKnotChild->name;
207 
208  // enter everytime you find a <E> or a <xsec> tag
209  const xmlChar * tag = xmlKnotChild->name;
210  bool is_xtag = ! xmlStrcmp(tag,(const xmlChar *) xtag.c_str());
211  bool is_ytag = ! xmlStrcmp(tag,(const xmlChar *) ytag.c_str());
212  if (is_xtag || is_ytag) {
213  xmlNodePtr xmlValTagChild = xmlKnotChild->xmlChildrenNode;
214  string val = utils::xml::TrimSpaces(
215  xmlNodeListGetString(xml_doc, xmlValTagChild, 1));
216 
217  if (is_xtag) vx[iknot] = atof(val.c_str());
218  if (is_ytag) vy[iknot] = atof(val.c_str());
219 
220  xmlFree(xmlValTagChild);
221  LOG("Spline", pDEBUG) << "tag: " << tag << ", value: " << val;
222  }//if current tag is <E>,<xsec>
223 
224  xmlKnotChild = xmlKnotChild->next;
225  }//[end of] loop over tags within <knot>...</knot> tags
226  xmlFree(xmlKnotChild);
227  iknot++;
228  } // if <knot>
229  xmlSplChild = xmlSplChild->next;
230  } //[end of] loop over tags within <spline>...</spline> tags
231  xmlFree(xmlSplChild);
232 
233  this->BuildSpline(nknots, vx, vy);
234  delete [] vx;
235  delete [] vy;
236 
237  return true;
238 }
239 //___________________________________________________________________________
241 {
242  LOG("Spline", pDEBUG) << "Retrieving data from file: " << filename;
243 
244  TNtupleD nt("ntuple","","x:y");
245  nt.ReadFile(filename.c_str());
246 
247  this->LoadFromNtuple(&nt, "x:y");
248  return true;
249 }
250 //___________________________________________________________________________
251 bool Spline::LoadFromNtuple(TNtupleD * nt, string var, string cut)
252 {
253  if(!nt) return false;
254 
255  TTree * tree = dynamic_cast<TTree *> (nt);
256  return this->LoadFromTree(tree,var,cut);
257 }
258 //___________________________________________________________________________
259 bool Spline::LoadFromTree(TTree * tree, string var, string cut)
260 {
261  LOG("Spline", pDEBUG) << "Retrieving data from tree: " << tree->GetName();
262 
263  if(!cut.size()) tree->Draw(var.c_str(), "", "GOFF");
264  else tree->Draw(var.c_str(), cut.c_str(), "GOFF");
265 
266  TH2F * hst = (TH2F*)gROOT->FindObject("htemp");
267  if(hst) { hst->SetDirectory(0); delete hst; }
268 
269  // Now, take into account that the data retrieved from the ntuple would
270  // not be sorted in x and the resulting spline will be bogus...
271  // Sort the x array, use the x-sorting to re-arrange the y array and only
272  // then build the spline..
273 
274  int n = tree->GetSelectedRows();
275 
276  int * idx = new int[n];
277  double * x = new double[n];
278  double * y = new double[n];
279 
280  TMath::Sort(n,tree->GetV1(),idx,false);
281 
282  for(int i=0; i<n; i++) {
283  int ii = idx[i];
284  x[i] = (tree->GetV1())[ii];
285  y[i] = (tree->GetV2())[ii];
286  }
287 
288  this->BuildSpline(n,x,y);
289 
290  delete [] idx;
291  delete [] x;
292  delete [] y;
293 
294  return true;
295 }
296 //___________________________________________________________________________
297 bool Spline::LoadFromDBase(TSQLServer * /*db*/, string /*query*/)
298 {
299  LOG("Spline", pDEBUG) << "Retrieving data from data-base: ";
300  return false;
301 }
302 //___________________________________________________________________________
303 bool Spline::LoadFromTSpline3(const TSpline3 & spline, int nknots)
304 {
305  int nentries = nknots;
306 
307  double * x = new double[nentries];
308  double * y = new double[nentries];
309  double cx = 0, cy = 0;
310 
311  for(int i = 0; i < nentries; i++) {
312  spline.GetKnot(i, cx, cy);
313  x[i] = cx;
314  y[i] = cy;
315  }
316  this->BuildSpline(nentries, x, y);
317 
318  delete [] x;
319  delete [] y;
320 
321  return true;
322 }
323 //___________________________________________________________________________
324 void Spline::GetKnot(int iknot, double & x, double & y) const
325 {
326  if(!fInterpolator) {
327  LOG("Spline", pWARN) << "Spline has not been built yet!";
328  return;
329  }
330  fInterpolator->GetKnot(iknot,x,y);
331 }
332 //___________________________________________________________________________
333 double Spline::GetKnotX(int iknot) const
334 {
335  if(!fInterpolator) {
336  LOG("Spline", pWARN) << "Spline has not been built yet!";
337  return 0;
338  }
339  double x,y;
340  fInterpolator->GetKnot(iknot,x,y);
341  return x;
342 }
343 //___________________________________________________________________________
344 double Spline::GetKnotY(int iknot) const
345 {
346  if(!fInterpolator) {
347  LOG("Spline", pWARN) << "Spline has not been built yet!";
348  return 0;
349  }
350  double x,y;
351  fInterpolator->GetKnot(iknot,x,y);
352  return y;
353 }
354 //___________________________________________________________________________
355 bool Spline::IsWithinValidRange(double x) const
356 {
357  bool is_in_range = (fXMin <= x && x <= fXMax);
358  return is_in_range;
359 }
360 //___________________________________________________________________________
361 double Spline::Evaluate(double x) const
362 {
363  LOG("Spline", pDEBUG) << "Evaluating spline at point x = " << x;
364  assert(!TMath::IsNaN(x));
365 
366  double y = 0;
367  if( this->IsWithinValidRange(x) ) {
368 
369  // we can interpolate within the range of spline knots - be careful with
370  // strange cubic spline behaviour when close to knots with y=0
371  bool is0p = this->ClosestKnotValueIsZero(x, "+");
372  bool is0n = this->ClosestKnotValueIsZero(x, "-");
373 
374  if(!is0p && !is0n) {
375  // both knots (on the left and right are non-zero) - just interpolate
376  LOG("Spline", pDEBUG) << "Point is between non-zero knots";
377  y = fInterpolator->Eval(x);
378  } else {
379  // at least one of the neighboring knots has y=0
380  if(is0p && is0n) {
381  // both neighboring knots have y=0
382  LOG("Spline", pDEBUG) << "Point is between zero knots";
383  y=0;
384  } else {
385  // just 1 neighboring knot has y=0 - do a linear interpolation
386  LOG("Spline", pDEBUG)
387  << "Point has zero" << (is0n ? " left " : " right ") << "knot";
388  double xpknot=0, ypknot=0, xnknot=0, ynknot=0;
389  this->FindClosestKnot(x, xnknot, ynknot, "-");
390  this->FindClosestKnot(x, xpknot, ypknot, "+");
391  if(is0n) y = ypknot * (x-xnknot)/(xpknot-xnknot);
392  else y = ynknot * (x-xnknot)/(xpknot-xnknot);
393  }
394  }
395 
396  } else {
397  LOG("Spline", pDEBUG) << "x = " << x
398  << " is not within spline range [" << fXMin << ", " << fXMax << "]";
399  }
400 
401  if(y<0 && !fYCanBeNegative) {
402  LOG("Spline", pINFO) << "Negative y (" << y << ")";
403  LOG("Spline", pINFO) << "x = " << x;
404  LOG("Spline", pINFO) << "spline range [" << fXMin << ", " << fXMax << "]";
405  }
406 
407  LOG("Spline", pDEBUG) << "Spline(x = " << x << ") = " << y;
408 
409  return y;
410 }
411 //___________________________________________________________________________
413  string filename, string xtag, string ytag, string name) const
414 {
415  ofstream outxml(filename.c_str());
416  if(!outxml.is_open()) {
417  LOG("Spline", pERROR) << "Couldn't create file = " << filename;
418  return;
419  }
420  string spline_name = (name.size()>0 ? name : fName);
421 
422  this->SaveAsXml(outxml, xtag, ytag, spline_name);
423 
424  outxml << endl;
425  outxml.close();
426 }
427 //___________________________________________________________________________
429  ofstream & ofs, string xtag, string ytag, string name) const
430 {
431  string spline_name = (name.size()>0 ? name : fName);
432 
433  // create a spline tag with the number of knots as an attribute
434  int nknots = this->NKnots();
435  string padding = " ";
436  ofs << padding << "<spline name=\"" << spline_name
437  << "\" nknots=\"" << nknots << "\">" << endl;
438 
439  // start printing the knots
440  double x=0, y=0;
441  for(int iknot = 0; iknot < nknots; iknot++)
442  {
443  fInterpolator->GetKnot(iknot, x, y);
444 
445  ofs << std::fixed << setprecision(5);
446  ofs << "\t<knot>"
447  << " <" << xtag << "> " << setfill(' ')
448  << setw(10) << x << " </" << xtag << ">";
449  ofs << std::scientific << setprecision(10);
450  ofs << " <" << ytag << "> " << setfill(' ')
451  << setw(10) << y << " </" << ytag << ">"
452  << " </knot>" << endl;
453  }
454  ofs << padding << "</spline>" << endl;
455 }
456 //___________________________________________________________________________
457 void Spline::SaveAsText(string filename, string format) const
458 {
459  ofstream outtxt(filename.c_str());
460  if(!outtxt.is_open()) {
461  LOG("Spline", pERROR) << "Couldn't create file = " << filename;
462  return;
463  }
464  int nknots = this->NKnots();
465  outtxt << nknots << endl;
466 
467  double x=0, y=0;
468  for(int iknot = 0; iknot < nknots; iknot++) {
469  fInterpolator->GetKnot(iknot, x, y);
470  char line[1024];
471  sprintf(line,format.c_str(),x,y);
472  outtxt << line << endl;
473  }
474  outtxt << endl;
475  outtxt.close();
476 }
477 //___________________________________________________________________________
478 void Spline::SaveAsROOT(string filename, string name, bool recreate) const
479 {
480  string spline_name = (name.size()>0 ? name : fName);
481 
482  string opt = ( (recreate) ? "RECREATE" : "UPDATE" );
483 
484  TFile f(filename.c_str(), opt.c_str());
485  if(fInterpolator) fInterpolator->Write(spline_name.c_str());
486  f.Close();
487 }
488 //___________________________________________________________________________
490  int np, bool scale_with_x, bool in_log, double fx, double fy) const
491 {
492  double xmin = fXMin;
493  double xmax = fXMax;
494 
495  np = TMath::Max(np,2);
496 
497  bool use_log = in_log && (fXMin>0) && (fXMax>0);
498 
499  if(use_log) {
500  xmin = TMath::Log10(xmin);
501  xmax = TMath::Log10(xmax);
502  }
503 
504  double dx = (xmax - xmin) / (np-1);
505 
506  double * x = new double[np];
507  double * y = new double[np];
508 
509  for(int i=0; i<np; i++) {
510  x[i] = ( (use_log) ? TMath::Power(10, xmin+i*dx) : xmin + i*dx );
511  y[i] = this->Evaluate( x[i] );
512 
513  // scale with x if needed
514  if (scale_with_x) y[i] /= x[i];
515 
516  // apply x,y scaling
517  y[i] *= fy;
518  x[i] *= fx;
519  }
520 
521  TGraph * graph = new TGraph(np, x, y);
522  delete[] x;
523  delete[] y;
524  return graph;
525 }
526 //___________________________________________________________________________
528  double x, double & xknot, double & yknot, Option_t * opt) const
529 {
530  string option(opt);
531 
532  bool pos = (option.find("+") != string::npos);
533  bool neg = (option.find("-") != string::npos);
534 
535  if(!pos && !neg) return;
536 
537  int iknot = fInterpolator->FindX(x);
538 
539  double xp=0, yp=0, xn=0, yn=0;
540  fInterpolator->GetKnot(iknot, xn,yn);
541  fInterpolator->GetKnot(iknot+1,xp,yp);
542 
543  bool p = (TMath::Abs(x-xp) < TMath::Abs(x-xn));
544 
545  if(pos&&neg) {
546  if(p) { xknot = xp; yknot = yp; }
547  else { xknot = xn; yknot = yn; }
548  } else {
549  if(pos) { xknot = xp; yknot = yp; }
550  if(neg) { xknot = xn; yknot = yn; }
551  }
552 }
553 //___________________________________________________________________________
554 bool Spline::ClosestKnotValueIsZero(double x, Option_t * opt) const
555 {
556  double xknot = 0, yknot = 0;
557  this->FindClosestKnot(x, xknot, yknot, opt);
558  if(utils::math::AreEqual(yknot,0)) return true;
559  return false;
560 }
561 //___________________________________________________________________________
562 void Spline::Print(ostream & stream) const
563 {
564  int nknots = this->NKnots();
565  double xmin = this->XMin();
566  double xmax = this->XMax();
567 
568  stream << endl;
569  stream << "** Spline: " << this->Name() << endl;
570  stream << "Has " << nknots
571  << " knots in the [" << xmin << ", " << xmax << "] range" << endl;
572  double x,y;
573  for(int i=0; i<nknots; i++) {
574  this->GetKnot(i,x,y);
575  stream << "-- knot : " << i
576  << " -> (x = " << x << ", y = " << y << ")" << endl;
577  }
578 }
579 //___________________________________________________________________________
580 void Spline::Add(const Spline & spl, double c)
581 {
582  // continue only if the input spline is defined at a wider x-range
583  double xmin = this->XMin();
584  double xmax = this->XMax();
585  bool ok = spl.IsWithinValidRange(xmin) && spl.IsWithinValidRange(xmax);
586  if(!ok) {
587  LOG("Spline", pERROR) << "** Can't add splines. X-range mismatch!";
588  return;
589  }
590 
591  int nknots = this->NKnots();
592  double * x = new double[nknots];
593  double * y = new double[nknots];
594 
595  for(int i=0; i<nknots; i++) {
596  this->GetKnot(i,x[i],y[i]);
597  y[i] += (c * spl.Evaluate(x[i]));
598  }
599  this->ResetSpline();
600  this->BuildSpline(nknots,x,y);
601  delete [] x;
602  delete [] y;
603 }
604 //___________________________________________________________________________
605 void Spline::Multiply(const Spline & spl, double c)
606 {
607  // continue only if the input spline is defined at a wider x-range
608  double xmin = this->XMin();
609  double xmax = this->XMax();
610  bool ok = spl.IsWithinValidRange(xmin) && spl.IsWithinValidRange(xmax);
611  if(!ok) {
612  LOG("Spline", pERROR) << "** Can't multiply splines. X-range mismatch!";
613  return;
614  }
615 
616  int nknots = this->NKnots();
617  double * x = new double[nknots];
618  double * y = new double[nknots];
619 
620  for(int i=0; i<nknots; i++) {
621  this->GetKnot(i,x[i],y[i]);
622  y[i] *= (c * spl.Evaluate(x[i]));
623  }
624  this->ResetSpline();
625  this->BuildSpline(nknots,x,y);
626  delete [] x;
627  delete [] y;
628 }
629 //___________________________________________________________________________
630 void Spline::Divide(const Spline & spl, double c)
631 {
632  // continue only if the input spline is defined at a wider x-range
633  double xmin = this->XMin();
634  double xmax = this->XMax();
635  bool ok = spl.IsWithinValidRange(xmin) && spl.IsWithinValidRange(xmax);
636  if(!ok) {
637  LOG("Spline", pERROR) << "** Can't divide splines. X-range mismatch!";
638  return;
639  }
640 
641  int nknots = this->NKnots();
642  double * x = new double[nknots];
643  double * y = new double[nknots];
644 
645  for(int i=0; i<nknots; i++) {
646  this->GetKnot(i,x[i],y[i]);
647  double denom = c * spl.Evaluate(x[i]);
648  bool denom_is_zero = TMath::Abs(denom) < DBL_EPSILON;
649  if(denom_is_zero) {
650  LOG("Spline", pERROR) << "** Refusing to divide spline knot by 0";
651  delete [] x;
652  delete [] y;
653  return;
654  }
655  y[i] /= denom;
656  }
657  this->ResetSpline();
658  this->BuildSpline(nknots,x,y);
659  delete [] x;
660  delete [] y;
661 }
662 //___________________________________________________________________________
663 void Spline::Add(double a)
664 {
665  int nknots = this->NKnots();
666  double * x = new double[nknots];
667  double * y = new double[nknots];
668 
669  for(int i=0; i<nknots; i++) {
670  this->GetKnot(i,x[i],y[i]);
671  y[i]+=a;
672  }
673  this->ResetSpline();
674  this->BuildSpline(nknots,x,y);
675  delete [] x;
676  delete [] y;
677 }
678 //___________________________________________________________________________
679 void Spline::Multiply(double a)
680 {
681  int nknots = this->NKnots();
682  double * x = new double[nknots];
683  double * y = new double[nknots];
684 
685  for(int i=0; i<nknots; i++) {
686  this->GetKnot(i,x[i],y[i]);
687  y[i]*=a;
688  }
689  this->ResetSpline();
690  this->BuildSpline(nknots,x,y);
691  delete [] x;
692  delete [] y;
693 }
694 //___________________________________________________________________________
695 void Spline::Divide(double a)
696 {
697  bool a_is_zero = TMath::Abs(a) < DBL_EPSILON;
698  if(a_is_zero==0) {
699  LOG("Spline", pERROR) << "** Refusing to divide spline by 0";
700  return;
701  }
702  int nknots = this->NKnots();
703  double * x = new double[nknots];
704  double * y = new double[nknots];
705 
706  for(int i=0; i<nknots; i++) {
707  this->GetKnot(i,x[i],y[i]);
708  y[i]/=a;
709  }
710  this->ResetSpline();
711  this->BuildSpline(nknots,x,y);
712  delete [] x;
713  delete [] y;
714 }
715 //___________________________________________________________________________
717 {
718  LOG("Spline", pDEBUG) << "Initializing spline...";
719 
720  fName = "genie-spline";
721  fXMin = 0.0;
722  fXMax = 0.0;
723  fYMax = 0.0;
724 
725  fInterpolator = 0;
726 
727  fYCanBeNegative = false;
728 
729  LOG("Spline", pDEBUG) << "...done initializing spline";
730 }
731 //___________________________________________________________________________
733 {
734  if(fInterpolator) delete fInterpolator;
735  this->InitSpline();
736 }
737 //___________________________________________________________________________
738 void Spline::BuildSpline(int nentries, double x[], double y[])
739 {
740  LOG("Spline", pDEBUG) << "Building spline...";
741 
742  double xmin = x[0]; // minimum x in spline
743  double xmax = x[nentries-1]; // maximum x in spline
744 
745  fNKnots = nentries;
746  fXMin = xmin;
747  fXMax = xmax;
748  fYMax = y[ TMath::LocMax(nentries, y) ]; // maximum y in spline
749 
750  if(fInterpolator) delete fInterpolator;
751 
752  fInterpolator = new TSpline3("spl3", x, y, nentries, "0");
753 
754  LOG("Spline", pDEBUG) << "...done building spline";
755 }
756 //___________________________________________________________________________
static QCString name
Definition: declinfo.cpp:673
TGraph * GetAsTGraph(int np=500, bool xscaling=false, bool inlog=false, double fx=1., double fy=1.) const
Definition: Spline.cxx:489
THE MAIN GENIE PROJECT NAMESPACE
Definition: AlgCmp.h:25
#define pERROR
Definition: Messenger.h:59
bool AreEqual(double x1, double x2)
Definition: MathUtils.cxx:236
string TrimSpaces(xmlChar *xmls)
A numeric analysis tool class for interpolating 1-D functions.
Definition: Spline.h:46
opt
Definition: train.py:196
static bool format(QChar::Decomposition tag, QString &str, int index, int len)
Definition: qstring.cpp:11496
void Print(ostream &stream) const
Definition: Spline.cxx:562
def graph(desc, maker=maker)
Definition: apa.py:294
bool LoadFromAsciiFile(string filename)
Definition: Spline.cxx:240
void BuildSpline(int nentries, double x[], double y[])
Definition: Spline.cxx:738
bool fYCanBeNegative
Definition: Spline.h:130
double Evaluate(double x) const
Definition: Spline.cxx:361
string filename
Definition: train.py:213
bool ClosestKnotValueIsZero(double x, Option_t *opt="-+") const
Definition: Spline.cxx:554
Q_EXPORT QTSManip setprecision(int p)
Definition: qtextstream.h:343
bool IsWithinValidRange(double x) const
Definition: Spline.cxx:355
TSpline3 * GetAsTSpline(void) const
Definition: Spline.h:96
bool LoadFromXmlFile(string filename, string xtag, string ytag)
Definition: Spline.cxx:153
double GetKnotX(int iknot) const
Definition: Spline.cxx:333
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
void ResetSpline(void)
Definition: Spline.cxx:732
std::void_t< T > n
const double a
ClassImp(Spline) namespace genie
Definition: Spline.cxx:40
p
Definition: test.py:223
double fXMax
Definition: Spline.h:127
void SaveAsROOT(string filename, string name="", bool recreate=false) const
Definition: Spline.cxx:478
#define pINFO
Definition: Messenger.h:62
void Add(const Spline &spl, double c=1)
Definition: Spline.cxx:580
void Multiply(const Spline &spl, double c=1)
Definition: Spline.cxx:605
void GetKnot(int iknot, double &x, double &y) const
Definition: Spline.cxx:324
#define pWARN
Definition: Messenger.h:60
double fYMax
Definition: Spline.h:128
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
string TrimSpaces(string input)
Definition: StringUtils.cxx:18
double GetKnotY(int iknot) const
Definition: Spline.cxx:344
double XMax(void) const
Definition: Spline.h:77
string fName
Definition: Spline.h:124
bool LoadFromTSpline3(const TSpline3 &spline, int nknots)
Definition: Spline.cxx:303
void SaveAsText(string filename, string format="%10.6f\t%10.6f") const
Definition: Spline.cxx:457
void SaveAsXml(string filename, string xtag, string ytag, string name="") const
Definition: Spline.cxx:412
int fNKnots
Definition: Spline.h:125
TSpline3 * fInterpolator
Definition: Spline.h:129
bool LoadFromNtuple(TNtupleD *nt, string xy, string cut="")
Definition: Spline.cxx:251
bool LoadFromDBase(TSQLServer *db, string query)
Definition: Spline.cxx:297
int var
Definition: 018_def.c:9
ostream & operator<<(ostream &stream, const AlgConfigPool &config_pool)
string Name(void) const
Definition: Spline.h:83
void line(double t, double *p, double &x, double &y, double &z)
int NKnots(void) const
Definition: Spline.h:72
void InitSpline(void)
Definition: Spline.cxx:716
bool LoadFromTree(TTree *tr, string xy, string cut="")
Definition: Spline.cxx:259
list x
Definition: train.py:276
virtual ~Spline()
Definition: Spline.cxx:148
double fXMin
Definition: Spline.h:126
void FindClosestKnot(double x, double &xknot, double &yknot, Option_t *opt="-+") const
Definition: Spline.cxx:527
double XMin(void) const
Definition: Spline.h:76
query_result< Args... > query(sqlite3 *db, std::string const &ddl)
Definition: select.h:75
string GetAttribute(xmlNodePtr xml_cur, string attr_name)
Q_EXPORT QTSManip setfill(int f)
Definition: qtextstream.h:337
void Divide(const Spline &spl, double c=1)
Definition: Spline.cxx:630
QTextStream & endl(QTextStream &s)
#define pDEBUG
Definition: Messenger.h:63