Commit ec3b3d6f authored by Iain's avatar Iain
Browse files

the code iains been messing around with

parent a45895a2
Pipeline #40353 failed with stages
in 23 seconds
......@@ -4,7 +4,7 @@ ROOTANASLIBS = $(ROOTANASYS)/lib/librootana.so
ROOTANADIR = $(ROOTANASYS)/include
JSONCPPLIBS = $(JSONCPP)/lib
GFLAGS = -g -O0
GFLAGS = -g -DDEBUG -O0
# CFLAGS = -c -fPIC $(GFLAGS) $(shell root-config --cflags) -I. -I/home/exo/packages/hdf5-1.8.13/include -I$(MIDASSYS)/include -I$(ROOTANASYS)/include
CFLAGS = -c -fPIC $(GFLAGS) $(shell root-config --cflags) -I. -I$(MIDASSYS)/include -I$(ROOTANASYS)/include -I$(JSONCPP)/include
# LFLAGS = $(GFLAGS) $(shell root-config --libs) -lMinuit -L /home/exo/packages/hdf5-1.8.13/lib -lhdf5 -lhdf5_cpp -lz -lm $(ROOTANALIBS) $(MIDASLIBS)
......@@ -14,21 +14,25 @@ all: lib bin/vanwftk
PF : bin/PulseFinding.exe
lib : lib/libSipmAnalysis.so
lib : lib/libSipmAnalysis.so lib/libSipmAnalysis2.so
lib/libSipmAnalysis.so : obj/Waveform.o obj/old/LecroyFile.o obj/old/V1730File.o obj/old/DataFile.o obj/RootDict.o #obj/LecroyHdfFile.o obj/WaveformProcessor.o
mkdir -p $(@D)
g++ -shared -fPIC -o lib/libSipmAnalysis.so $^ $(LFLAGS)
lib/libSipmAnalysis2.so : obj/RunManager.o obj/reader/V1730Factory.o obj/reader/Reader.o obj/writer/PulseWriteProcessor.o obj/reader/V1730File.o obj/Waveform.o obj/Event.o obj/Channel.o obj/WaveformStatistic.o obj/pulse_finding/PFS.o obj/pulse_finding/PulseFindingProcessor.o obj/pulse_analysis/PulseFittingStrategy1.o obj/pulse_analysis/PulseAnalysisProcessor.o obj/writer/NTupleWriter.o obj/baseline/BaselineProcessor.o obj/baseline/MostProbBaselineStrategy.o obj/RootDict.o #obj/LecroyHdfFile.o obj/WaveformProcessor.o
mkdir -p $(@D)
g++ -shared -fPIC -o lib/libSipmAnalysis2.so $^ $(LFLAGS)
bin/PulseFinding.exe : obj/PulseFinding.o obj/WaveformStatistic.o obj/old/LecroyFile.o obj/old/V1730File.o obj/old/V1730Reader.o obj/WaveformProcessor.o obj/Waveform.o obj/old/DataFile.o obj/Event.o obj/Channel.o #obj/LecroyHdfFile.o
mkdir -p $(@D)
g++ -o bin/PulseFinding.exe $^ $(LFLAGS)
bin/vanwftk : obj/RunManager.o obj/reader/V1730Factory.o obj/reader/Reader.o obj/reader/V1730File.o obj/Waveform.o obj/Event.o obj/Channel.o obj/WaveformStatistic.o obj/pulse_finding/PFS.o obj/pulse_finding/PulseFindingProcessor.o obj/pulse_analysis/PulseFittingStrategy1.o obj/pulse_analysis/PulseAnalysisProcessor.o
bin/vanwftk : obj/RunManager.o obj/reader/V1730Factory.o obj/reader/Reader.o obj/writer/PulseWriteProcessor.o obj/reader/V1730File.o obj/Waveform.o obj/Event.o obj/Channel.o obj/WaveformStatistic.o obj/pulse_finding/PFS.o obj/pulse_finding/PulseFindingProcessor.o obj/pulse_analysis/PulseFittingStrategy1.o obj/pulse_analysis/PulseAnalysisProcessor.o obj/writer/NTupleWriter.o obj/baseline/BaselineProcessor.o obj/baseline/MostProbBaselineStrategy.o
mkdir -p $(@D)
g++ -o bin/vanwftk -L$(JSONCPPLIBS) $^ $(LFLAGS) -ljsoncpp
obj/RootDict.o : code/Waveform.h code/reader/V1730File.h code/reader/DataFile.h code/reader/Reader.h code/pulse_finding/PFS.h code/pulse_finding/PulseFindingProcessor.h code/pulse_analysis/PulseAnalysisProcessor.h code/pulse_analysis/PulseFittingStrategy1.h code/EventProcessor.h code/Linkdef.h
obj/RootDict.o : code/Pulse.h code/Channel.h code/Event.h code/Waveform.h code/RunManager.h
# rootcint -f code/RootDict.cxx -c -I/home/deap/nEXO/packages/hdf5-1.8.13/hdf5/include -I$ROOTANADIR $^
rootcint -f code/RootDict.cxx -c -I$(ROOTANADIR) -I$(JSONCPP)/include $^
mkdir -p $(@D)
......@@ -48,6 +52,16 @@ obj/reader/%.o: code/reader/%.cxx
g++ -c -o $@ $< $(CFLAGS)
$(build-obj)
obj/baseline/%.o: code/baseline/%.cxx
mkdir -p $(@D)
g++ -c -o $@ $< $(CFLAGS)
$(build-obj)
obj/writer/%.o: code/writer/%.cxx
mkdir -p $(@D)
g++ -c -o $@ $< $(CFLAGS)
$(build-obj)
obj/old/%.o: code/old/%.cxx
mkdir -p $(@D)
g++ -c -o $@ $< $(CFLAGS)
......
......@@ -6,7 +6,9 @@
*
* Takes a Waveform as the parameter and sets the member variable, `wf`.
*/
Channel::Channel(Waveform *newWaveform) { wf = newWaveform; }
Channel::Channel(Waveform *newWaveform) {
wf = newWaveform;
}
/**
* Store the pulses found.
......@@ -47,4 +49,18 @@ void Channel::setTriggerTime(double channelTriggerTime) {
*
* Returns the member variable, `triggerTime` when called.
*/
double Channel::getTriggerTime() { return triggerTime; }
\ No newline at end of file
double Channel::getTriggerTime() { return triggerTime; }
/**
* Returns if the waveform is vaild for the channel (polraity and timeing for exmaple)
*
* Returns the memeber variable 'isVaild'
*/
bool Channel::getValid(){ return isValid; };
/**
* Set the if the processed waveform is vaild (polraity and timeing for exmaple) for the channel.
*
* Takes a bool as a parameter (Deafult true) and sets the member variable, `isVaild`.
*/
void Channel::setValid(bool isValid) { this->isValid = isValid; };
\ No newline at end of file
......@@ -14,6 +14,8 @@
*/
class Channel {
public:
typedef std::vector<Channel> Channels;//trying to clean the cod eup a bit
Channel(Waveform *newWaveform);
void setPulses(std::vector<Pulse> pulses);
......@@ -21,9 +23,12 @@ public:
std::vector<Pulse> *getPulses();
void setTriggerTime(double channelTriggerTime);
double getTriggerTime();
bool getValid();
void setValid(bool vaild = true);
private:
Waveform *wf; /*!< Waveform of the current channel. */
bool isValid;
std::vector<Pulse>
pulses; /*!< Pulses discovered of the current channel's waveform. */
double triggerTime; /*!< Trigger time of the channel. */
......
......@@ -12,7 +12,7 @@ Event::Event() {}
* Takes a vector of Channel as the parameter and sets the member vector,
* `channels`.
*/
void Event::addChannels(std::vector<Channel> newChannels) {
void Event::addChannels(Channel::Channels newChannels) {
channels = newChannels;
}
......@@ -23,4 +23,4 @@ void Event::addChannels(std::vector<Channel> newChannels) {
* This allows pass by reference and changes to the channels outside of the
* Event class will persist.
*/
std::vector<Channel> *Event::getChannels() { return &channels; }
\ No newline at end of file
Channel::Channels* Event::getChannels() { return &channels; }
\ No newline at end of file
......@@ -4,9 +4,13 @@
#pragma link off all functions;
#pragma link C++ nestedclasses;
#pragma link C++ class Waveform;
#pragma link C++ class WaveformProcessor;
#pragma link C++ class LecroyFile;
//#pragma link C++ class LecroyHdfFile;
#pragma link C++ class V1730File;
#pragma link C++ class Channel;
#pragma link C++ class Event;
#pragma link C++ class IEventProcessor;
#pragma link C++ class BaselineProcessor;
#pragma link C++ class PulseFindingProcessor;
#pragma link C++ class PulseAnalysisProcessor;
#pragma link C++ class PulseWriteProcessor;
#pragma link C++ class RunManager;
#endif
#ifndef PULSE_H
#define PULSE_H
/**
* A structure that represents a single pulse.
* After fitting
*/
struct FitPulse{
FitPulse() :lowLimit(0),
highLimit(0),
baseline(0),
time(0),
amp(0),
riseTime(0),
fallTime(0),
time2Frac(0),
fallTime2(0),
chi2(0),
NDF(0),
charge(0) {};
double lowLimit;
double highLimit;
double baseline;
double time;
double amp;
double riseTime;
double fallTime;
double time2Frac;
double fallTime2;
double chi2;
double NDF;
double charge;
//int mFirstPulseInGroup;
};
/**
* A structure that represents a single pulse.
*
......@@ -8,30 +40,15 @@
* charge and width.
*/
struct Pulse {
int debug_id;
double time;
double absAmp;
double amp;
double baseline;
double charge;
int width;
/*
double mSPTemplateChi2;
double mFitLowLimit;
double mFitHighLimit;
double mFitBaseline;
double mFitTime;
double mFitAmp;
double mFitRiseTime;
double mFitFallTime;
double mFitTime2Frac;
double mFitFallTime2;
double mFitChi2;
double mFitNDF;
double mFitQ;
double mRefitChi2;
double mRefitNDF;
int mFirstPulseInGroup;
*/
double singlePulseTemplateChi2;
FitPulse fit;
};
#endif // PULSE_H
......@@ -2,6 +2,8 @@
#include "pulse_analysis/PulseAnalysisProcessor.h"
#include "pulse_finding/PulseFindingProcessor.h"
#include "reader/V1730Factory.h"
#include "writer/PulseWriteProcessor.h"
#include "baseline/BaselineProcessor.h"
#include <cstdlib>
#include <iostream>
......@@ -46,26 +48,35 @@ Reader *RunManager::createReader() {
*/
void RunManager::processEvents() {
Reader *it = createReader();
BaselineProcessor bsProcessor{channelConfigs};
PulseFindingProcessor pfProcessor{channelConfigs};
PulseAnalysisProcessor paProcessor{channelConfigs};
PulseWriteProcessor wrProcessor{channelConfigs};
int c = 0, pulses = 0, totalPulses = 0, pulsesAnalyzed = 0;
int c = 0, pulses = 0, totalPulses = 0, pulsesAnalyzed = 0, pulsesSaved = 0;
for (auto event = it->getCurrent(); !(it->isDone()) && c < eventLimit;
it->next()) {
event = it->getCurrent();// why shoudl this be nessiary, (maybe it shoudl be setting the chneels in the reader or maybe
std::cout << "\rprocessing event " << ++c << "/" << eventLimit;
bsProcessor.processEvent(event);
pulses = pfProcessor.processEvent(event);
totalPulses += pulses;
if (!paProcessor.processEvent(event)) {
// event was not skipped
pulsesAnalyzed += pulses;
pulsesSaved += wrProcessor.processEvent(event);
}
}
wrProcessor.write();
std::cout << "\n\n"
<< totalPulses << " pulses found (pre-analysis)\n\n"
<< pulsesAnalyzed << " pulses analyzed" << std::endl;
<< pulsesAnalyzed << " pulses analyzed\n\n"
<< pulsesSaved << " pulses saved" << std::endl;
}
/**
......@@ -81,7 +92,7 @@ int main(int argc, char **argv) {
std::unique_ptr<RunManager> rm;
try {
rm = RunManager::fromConfigFile(argv[1]);
RunManager::fromConfigFile(rm,argv[1]);
} catch (Json::RuntimeError err) {
std::cerr << "Config file must be valid JSON:\n" << err.what() << std::endl;
return EXIT_FAILURE;
......
......@@ -31,12 +31,16 @@ public:
* flexibility if developers want to introduce new config formats, or source
* JSON objects from sources other than locally-available files.
*/
static std::unique_ptr<RunManager> fromConfigFile(std::string path) {
static void fromConfigFile(std::unique_ptr<RunManager> &rm, std::string path) {
Json::Value rootCfgJson;
std::ifstream configFile{path, std::ifstream::binary};
configFile >> rootCfgJson;
return RunManager::fromJson(rootCfgJson);
if(rm == nullptr){
rm = std::unique_ptr<RunManager>( new RunManager() );
}
fromJson(rm, rootCfgJson);
}
/**
......@@ -48,7 +52,7 @@ public:
* program. That said, major (i.e. top-level) schema changes should be
* validated here.
*/
static std::unique_ptr<RunManager> fromJson(Json::Value rootCfgJson) {
static void fromJson(std::unique_ptr<RunManager> &rm, Json::Value rootCfgJson) {//thb this should just be an alt constutror
const auto eventLimit = rootCfgJson.get("EventLimit", 0).asInt();
const auto dataSourceCfgJson{rootCfgJson["DataSource"]};
const auto channelCfgJson{rootCfgJson["ChannelConfigs"]};
......@@ -94,20 +98,23 @@ public:
channelConfigs.push_back({pfs, pas, vars});
}
return std::unique_ptr<RunManager>{new RunManager{
eventLimit, {device, filePath, channels, vars}, channelConfigs}};
rm->eventLimit = eventLimit;
rm->dataSource = {device, filePath, channels, vars};
rm->channelConfigs = channelConfigs;
}
void processEvents();
RunManager(){};
virtual void processEvents();
const int eventLimit; /*!< Limits the number of events that get processed. */
const DataSource
int eventLimit; /*!< Limits the number of events that get processed. */
DataSource
dataSource; /*!< Defines the datasource providing Events for analysis */
std::vector<ChannelConfig>
channelConfigs; /*!< Holds strategy configs and variables for each channel
that gets analyzed */
private:
protected:
Reader *createReader();
RunManager(int eventLimit, DataSource dataSource,
......
......@@ -1034,3 +1034,21 @@ Waveform *Waveform::getSubset(int aFirstBin, int aLastBin, const char *aName) {
}
return tWaveform;
}
/**
* Returns if the waveforms global basline
*
* Returns the memeber variable 'waveformBaseline'
*/
Baseline Waveform::getWaveformBaseline(){
return waveformBaseline;
}
/**
* Sets the varriable waveforms global baseline to the baseline passed baseline
*
* Takes a Baseline as a parameter and sets the member variable, `waveformBaseline`.
*/
void Waveform::setWaveformBaseline(Baseline baseline){
waveformBaseline = baseline;
}
\ No newline at end of file
......@@ -5,17 +5,30 @@
#include "TH2.h"
#include "TProfile.h"
struct Baseline{//TODO maybe not where this shoud go in the end but...
double mu;
double RMS;
//double STD;//not used yet
};
/**
* A waveform class that contains the data and logic to process statistics about
* a waveform.
*/
class Waveform : public TH1D {
public:
//***************************Stuff added by iain***********************************
Baseline getWaveformBaseline();
void setWaveformBaseline(Baseline baseline);
//***********We Should gut the rest of this class so it's not soo messy************
Waveform(int aNBin, double aMin, double aMax, const char *aName = 0,
int aRebin = 1); // always created in time domain
Waveform(const TH1D &aWF, int aRebin = 1, const char *aName = 0);
virtual ~Waveform();
void setNegPolarity() { mPolarity = -1; }
const int getPolarity() { return mPolarity; }
void setFilter(TF1 &aFunction);
Waveform *getSubset(int aFirstBin, int aLastBin, const char *aName = 0);
......@@ -59,6 +72,9 @@ public:
void simpleBaselineCalc();
TH1D *getBaseline() { return mHBaseline; }
double getMeanBaseline();
inline double getBaselineRMS(){return mBaselineRMS;}
inline void setBaselineRMS(double rms) {mBaselineRMS = rms;}//TODO move to baseline processor and maybe add a baseline struct
inline void setMeanBaseline(double mean) {mBaselineMean=mean;}//TODO move this to a separate processor
double getSigmaBaseline();
int validBaseline() {
return (mBaselineMean > mBaselineMeanMin &&
......@@ -121,6 +137,7 @@ public:
private:
// Waveform(const char* aName, TH1D* aHReal, TH2D* aHComp);
Baseline waveformBaseline;
void initFourier();
void fourierTransform();
......
#include "PulseAnalysisProcessor.h"
#include "PulseFittingStrategy1.h"
#include "PulseFittingStrategy2.h"
#include "PulseFittingStrategy3.h"
/**
* PulseAnalysisProcessor constructor.
......@@ -17,6 +19,10 @@ PulseAnalysisProcessor::PulseAnalysisProcessor(
if (pasName == "PulseFittingStrategy1") {
pas = new PulseFittingStrategy1();
} else if (pasName == "PulseFittingStrategy2") {
pas = new PulseFittingStrategy2();
} else if (pasName == "PulseFittingStrategy3") {
pas = new PulseFittingStrategy3();
} else {
throw std::runtime_error("Pulse analysis strategy not recognized");
}
......@@ -47,7 +53,7 @@ int PulseAnalysisProcessor::processEvent(Event *event) {
auto channels = event->getChannels();
for (int i = 0; i < channels->size(); i++) {
auto channel = channels[i];
auto channel = channels->at(i);
if (strategies[i]->analyze(channels->at(i), vars[i])) {
skipped++;
}
......
#include "PulseFittingStrategy1.h"
#include "../WaveformStatistic.h"
#include "TROOT.h"
#include <Math/MinimizerOptions.h>
/**
* Analyzes the Pulses and does all the fitting
......@@ -18,11 +20,172 @@
* different fit types.
*/
bool PulseFittingStrategy1::analyze(Channel &channel, Json::Value cfg) {
const double noise = cfg["Noise"].asDouble();
double riseTimeSigma = cfg["RiseTimeSigma"].asDouble();
int pulseBaselineCalcEndOffset = cfg["PulseBaselineCalcEndOffset"].asInt();
double fallTimeTau = cfg["FallTimeTau"].asDouble();
double fallTime2Tau = cfg["FallTime2Tau"].asDouble();
int fallTimeTauCoefficient = cfg["FallTimeTauCoefficient"].asInt();
const double riseTimeSigmaUpperLimitCoefficient = cfg["RiseTimeSigmaUpperLimitCoefficient"].asDouble();
int fallTime2TauCoefficient = cfg["CoefficientFallTime2Tau"].asInt();
int polarity = cfg["Polarity"].asInt();
int riseTimeSigmaCoefficient = cfg["CoefficientRiseTimeSigma"].asInt();
int maxNumPulsesFit = cfg["NumPulsesFit"].asInt();
fitOption = cfg["FitOption"].asCString();
pulseGroups = std::vector<PulseGroup>();
TF1 *fitFunction = createFitFunction(cfg);
// TODO: Add remaining pulse analysis functionality.
Waveform* wf = channel.getWaveform();
std::vector<Pulse>* pulses = channel.getPulses();
// TODO: check if the should just be removed, or left in as legacy
if(cfg["TemplateCheck"].asInt())
calcSinglePulseTemplateChi2(&channel,cfg);
//sets each bins error (the 'SetError' for all bin gave a seg fault)
for (int bin = 1; bin <= wf->GetNbinsX(); bin++)
wf->SetBinError(bin, noise);
int pulseGroupSize = 1;// total number of pulses fitted together
auto pulse = pulses->begin();
while(pulse != pulses->end()){//check if the next thing works
double fitLowLimit = std::max( pulse->time - riseTimeSigma * 10 - pulseBaselineCalcEndOffset * wf->GetBinWidth(1), wf->GetXaxis()->GetXmin() );//should the 10 be a parameter?
double fitUppLimit = std::min( pulse->time + fallTimeTau*fallTimeTauCoefficient + fallTime2Tau*fallTime2TauCoefficient + riseTimeSigma*riseTimeSigmaUpperLimitCoefficient + riseTimeSigmaUpperLimitCoefficient*wf->GetBinWidth(1),
wf->GetXaxis()->GetXmax() );
pulseGroupSize = 1;
for(auto it = std::next(pulse); it != pulses->end(); ++it){//finding all valid pulses for the fit group
if( fitUppLimit < it->time )
break;
fitUppLimit = it->time + fallTimeTau*fallTimeTauCoefficient + fallTime2Tau + riseTimeSigma*riseTimeSigmaUpperLimitCoefficient + riseTimeSigmaUpperLimitCoefficient*wf->GetBinWidth(1);//should 5 be parapmetr
pulseGroupSize++;
}
fitFunction->FixParameter(5, pulseGroupSize);
setFitParemeters(fitFunction, *pulse, cfg);
for (int fitPulseIndex = 0; fitPulseIndex < pulseGroupSize; fitPulseIndex++) {//setting the params of the fit group to the acc pulses
fitFunction->ReleaseParameter(6 + 2 * fitPulseIndex);
fitFunction->SetParameter(6 + 2 * fitPulseIndex, (std::next(pulse,fitPulseIndex)->charge * polarity));
if (polarity > 0)
fitFunction->SetParLimits(6 + 2 * fitPulseIndex, 0, 1e10);
else// polarity cant be zero otherwise it breaks other things
fitFunction->SetParLimits(6 + 2 * fitPulseIndex, -1e10, 0);
return checkPulses(channel, cfg);
// Prima era commentata
// mFFit->SetParLimits(6+2*iFitPulse,-20000.,0);
fitFunction->ReleaseParameter(7 + 2 * fitPulseIndex);
fitFunction->SetParameter(7 + 2 * fitPulseIndex, std::next(pulse,fitPulseIndex)->time - riseTimeSigma*riseTimeSigmaCoefficient );
fitFunction->SetParLimits(7 + 2 * fitPulseIndex, fitLowLimit, fitUppLimit); // bad things happen when pulses are allowed in front.
}
for (int fitPulseIndex = pulseGroupSize; fitPulseIndex < maxNumPulsesFit; fitPulseIndex++) {//setting the unused pulses as zero
fitFunction->FixParameter(6 + 2 * fitPulseIndex, 0);
fitFunction->FixParameter(7 + 2 * fitPulseIndex, 0);
}
fitFunction->SetRange( fitLowLimit, fitUppLimit );
/*for (int iFitPulse = iPulse; iFitPulse < iPulse + tNPulseInGroup; this is probably not nessisary
iFitPulse++) {
mPulse[iFitPulse].mFirstPulseInGroup = iPulse;
mPulse[iFitPulse].mFitLowLimit = mPulse[iPulse].mFitLowLimit;
mPulse[iFitPulse].mFitHighLimit = mPulse[iPulse].mFitHighLimit;
}*/
ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls(100000);// Increase number of cicles to fit
wf->Fit( fitFunction->GetName(), fitOption.c_str() );
PulseGroup group;
group.uppLimit = fitUppLimit;
group.lowLimit = fitLowLimit;
//>>> Store the fit information
for (int fitPulseIndex = 0; fitPulseIndex != pulseGroupSize; ++fitPulseIndex) {
Pulse* currentPulse = &(*std::next(pulse,fitPulseIndex));
currentPulse->fit.amp = fitFunction->GetParameter(6 + 2 * fitPulseIndex);
currentPulse->fit.time = fitFunction->GetParameter(7 + 2 * fitPulseIndex);
currentPulse->fit.baseline = fitFunction->GetParameter(0);
currentPulse->fit.riseTime = fitFunction->GetParameter(1);
currentPulse->fit.fallTime = fitFunction->GetParameter(2);
currentPulse->fit.time2Frac = fitFunction->GetParameter(3);
currentPulse->fit.fallTime2 = fitFunction->GetParameter(4);
currentPulse->fit.chi2 = fitFunction->GetChisquare();
currentPulse->fit.NDF = fitFunction->GetNDF();
currentPulse->fit.charge = fitFunction->Integral(fitLowLimit, fitUppLimit); // COMPUTE integral between define limits
group.pulseGroup.push_back(currentPulse);
}
pulseGroups.push_back(group);
pulse = std::next(pulse, pulseGroupSize);
}
bool doSort = pulses->size() > 1;
if (cfg["refit"].asInt())
doSort = doSort && refit(&channel, fitFunction, cfg);
if(doSort)
sortPulses(&channel);
channel.setValid( checkPulses(channel, cfg) );//sets if the chanel is valid, used in writer to determin what to write
return channel.getValid();
}
/**
* Sets the paremeters on a fitting fucntion for Pulse Analysis.
*
* Take in a pointer to a fitting function 'fit'
* And sets the apropirate parameters of the function for the fitting object
*
* This helper method should be called int pulse analysis
* code before fitting is executed.
*/
void PulseFittingStrategy1::setFitParemeters(TF1* fit, Pulse &p, Json::Value cfg){
double riseTimeSigma = cfg["RiseTimeSigma"].asDouble();
double fallTimeTau = cfg["FallTimeTau"].asDouble();
double time2Frac = cfg["Time2Frac"].asDouble();
double fallTime2Tau = cfg["FallTime2Tau"].asDouble();
fit->ReleaseParameter(0);
fit->SetParameter(0, p.baseline);
if (strcmp(fit->GetName(), "FExpRise") == 0) {//maybe this sould go to a sepeare clas, more investigation is needed
fit->FixParameter(1, riseTimeSigma);
fit->FixParameter(2, fallTimeTau - riseTimeSigma);
fit->FixParameter(3, time2Frac);
if (fallTime2Tau != 0)
fit->FixParameter(4, fallTime2Tau - riseTimeSigma - fallTimeTau);
else
fit->FixParameter(4, 0);
} else {
fit->FixParameter(1, riseTimeSigma);
fit->FixParameter(2, fallTimeTau);
fit->FixParameter(3, time2Frac);
fit->FixParameter(4, fallTime2Tau);
}
}
bool PulseFittingStrategy1::checkParams(Json::Value params) { return true; }
......@@ -77,8 +240,8 @@ bool PulseFittingStrategy1::checkPulses(Channel &channel, Json::Value cfg) {
}