alcap-org / AlcapDAQ

Alcap DAQ
alcap-org.github.io
8 stars 0 forks source link

Interpolator #257

Closed dmalexan closed 9 years ago

dmalexan commented 9 years ago

I've been working on using the interpolator from the mathmore library in root to improve on the constant fraction methods. I am however, running into a problem with the compilation. It does not seem to recognize the functions I am calling. I have verified that the header files are present and called correctly (at least according to the root website).

#define USE_PRINT_OUT 

#include "AnalysePulseIsland.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <map>
#include <vector>
#include <utility>
#include <algorithm>
#include "TMath.h"
#include "TROOT.h"
#include "TFormula.h"
#include "Math/Interpolator.h"
#include "Math/InterpolationTypes.h"

#include "TAnalysedPulse.h"

using std::string;
using std::map;
using std::vector;
using std::pair;

extern std::map<std::string, std::vector<TAnalysedPulse*> > gAnalysedPulseMap;

the code for the interpolator call is below, though it's a bit hectic (I'm trying to work around the problem)

void AnalysePulseIsland::GetAllParameters_InterCFT(TSetupData* gSetup, const TPulseIsland* pulse,
                        double& amplitude, double& time, double& integral, double& tintegral, double& energy, double& ratio) {
  float constant_fraction = 0.50;
  std::string bankname = pulse->GetBankName();
  int trigger_polarity = gSetup->GetTriggerPolarity(bankname);
  double eCalib_slope = gSetup->GetADCSlopeCalib(bankname);
  double eCalib_offset = gSetup->GetADCOffsetCalib(bankname);
  double clock_tick_in_ns = gSetup->GetClockTick(bankname);
  double time_shift = gSetup->GetTimeShift(bankname);
  double pedestal = 0;//gSetup->GetPedestal(bankname);
  int sum = 0, count = 40;
  double int_fact = 4;
  double precision = 1;

  std::string detname = gSetup->GetDetectorName(bankname);
  if(detname == "NDet")
    time_shift += 192;
  if(detname == "NDet2")
    time_shift += 34;

  // First find the position of the peak
  const std::vector<int>& samps = pulse->GetSamples();
  vector<double> x, y; 
  const std::vector<int>::const_iterator b = samps.begin(), e = samps.end();

  /*
  for(std::vector<int>::const_iterator siter = b; siter != e; ++siter){
    double time = std::distance(b, siter);
    double value = *siter;
    x.push_back(time);
    y.push_back(value);
  }
  */

  ROOT::Math::Interpolator inter(x, y, ROOT::Math::Interpolation::kCSPLINE);

  inter.SetData(x, y);

  for(std::vector<int>::const_iterator j = b; j < b+count; ++j){
    sum += inter.Eval(std::distance(b,j)/int_fact);
  }
  pedestal = sum/count;

  std::vector<int>::const_iterator m = trigger_polarity > 0 ? std::max_element(b, e) : std::min_element(b, e);

There is more, but the primary difficulty must be here. when compiling I receive an error,

///////////

/home/damien/AlcapDAQ/analyzer/rootana/src/AnalysePulseIsland.cpp:208: undefined reference to ROOT::Math::Interpolator::Interpolator(std::vector<double, std::allocator<double> > const&, std::vector<double, std::allocator<double> > const&, ROOT::Math::Interpolation::Type)' /home/damien/AlcapDAQ/analyzer/rootana/src/AnalysePulseIsland.cpp:210: undefined reference toROOT::Math::Interpolator::SetData(std::vector<double, std::allocator > const&, std::vector<double, std::allocator > const&)' /home/damien/AlcapDAQ/analyzer/rootana/src/AnalysePulseIsland.cpp:213: undefined reference to ROOT::Math::Interpolator::Eval(double) const' /home/damien/AlcapDAQ/analyzer/rootana/src/AnalysePulseIsland.cpp:230: undefined reference toROOT::Math::Interpolator::Eval(double) const' /home/damien/AlcapDAQ/analyzer/rootana/src/AnalysePulseIsland.cpp:234: undefined reference to ROOT::Math::Interpolator::Eval(double) const' /home/damien/AlcapDAQ/analyzer/rootana/src/AnalysePulseIsland.cpp:241: undefined reference toROOT::Math::Interpolator::Eval(double) const' /home/damien/AlcapDAQ/analyzer/rootana/src/AnalysePulseIsland.cpp:255: undefined reference to ROOT::Math::Interpolator::Eval(double) const' /home/damien/AlcapDAQ/analyzer/rootana/src/AnalysePulseIsland.cpp:208: undefined reference toROOT::Math::Interpolator::~Interpolator()' /home/damien/AlcapDAQ/analyzer/rootana/src/AnalysePulseIsland.cpp:208: undefined reference to `ROOT::Math::Interpolator::~Interpolator()' collect2: error: ld returned 1 exit status

//////////

Please let me know if you have any ideas. I've pushed the current version of this to the github under the Neutron_Detectors feature. All references to the interpolator are in the AnalysePulseIsland module.

benkrikler commented 9 years ago

When you get undefined reference errors like that it's a link-time complaint. The compiler has compiled all the code into individual units and is now trying to link together the executable or library. The final error confirms this: error: ld returned 1 exit status ld is the linker used by gcc.

The exact problem here is because the linker doesn't know how to find the ''symbols'' needed by the Root MathMore methods you're now using. The symbols are contained in the MathMore library and at the moment we don't tell gcc to use this hence the problems you've got.

And so the solution is to go to line 61 in the makefile and add:

-lMathMore

to the end of the line.

It's worth pointing out though, that John had implemented linear interpolation in the algorithm for Constant Fraction Time. Unless you're doing quadratic interpolation or something more exotic, you should consider swapping to just using the Rootana Constant Fraction Algorithm. This would have avoided both this and the last (#252) problems, would help us to help you since we know how that Algorithm is implemented, and would allow you to help us by giving it a further use-case to debug it against. That's the point of this framework, we're supposed to work together and save effort by re-using each other's code.

dmalexan commented 9 years ago

I am switching to the interpolator to use a cubic spline interpolation for better accuracy at the lower constant fraction. It is probably overkill, but I had difficulties going below 65% on the constant fraction method developed by John. The lower energy pulses would not interpolate correctly and there would be a jump in the amp vs tdiff plots. The reason for much of these difficulties is rewriting the code to fit the framework I had been using. I am making efforts (albeit slower than I should) to switch to the newer framework, though for simple testing of ideas, I find the old setup easier to manage.