10 if(riseIntervals.empty() && decayIntervals.empty()) {
12 err.SetDescription(__FILE__,__LINE__,
"Empty rise and decay intervals");
15 for(
size_t v = 0; v < riseIntervals.size(); v++) {
16 if(riseIntervals[v].GetMin() >= riseIntervals[v].GetMax() || riseIntervals[v].GetMax() > 1) {
18 err.SetDescription(__FILE__,__LINE__,
"Rise intervals must be < 1, and Min < Max");
21 fRise.push_back(make_pair(riseIntervals[v].GetMin(),v));
22 fRise.push_back(make_pair(riseIntervals[v].GetMax(),v));
25 for(
size_t v = 0; v < decayIntervals.size(); v++) {
26 if(decayIntervals[v].GetMin() >= decayIntervals[v].GetMax() || decayIntervals[v].GetMax() > 1) {
28 err.SetDescription(__FILE__,__LINE__,
"Decay intervals must be < 1, and Min < Max");
31 fDecay.push_back(make_pair(decayIntervals[v].GetMin(),v));
32 fDecay.push_back(make_pair(decayIntervals[v].GetMax(),v));
34 sort(fRise.begin(),fRise.end(),PairComparatorAsc);
35 sort(fDecay.begin(),fDecay.end(),PairComparatorAsc);
47 if(auxMaxpos < 1 || auxMaxpos >= (
int)input.Size()) {
51 size_t size = (int)input.Size();
55 double prevMaxValue = -1e15, currMaxValue = -1e15;
56 while(from+window < size)
58 currMax = input.GetMaxIndex(window,from);
59 currMaxValue = input[currMax];
60 if(currMaxValue > prevMaxValue)
62 prevMaxValue = currMaxValue;
68 double base = baseLine;
71 if(auxMaxpos > 0) base = input.GetMean(auxMaxpos*3./4);
73 double max = input[auxMaxpos]-base;
77 int riseCounter = fRise.size()-1;
78 for(
int i = auxMaxpos; i >= 0; i--) {
79 if(input[i]-base < fRise[riseCounter].first*
max) {
80 double time = i + (fRise[riseCounter].first*
max - input[i]+base)/(input[i+1] - input[i]);
81 if(rise[fRise[riseCounter].second] ==
Q_DOUBLE_DEFAULT) rise[fRise[riseCounter].second] = time+input.Size();
82 else rise[fRise[riseCounter].second] -= time+input.Size();
86 if(riseCounter < 0)
break;
89 for(
size_t v = 0; v < rise.size();v++) {
95 int decayCounter = fDecay.size()-1;
96 for(
int i = auxMaxpos; i < (int)input.Size()-1; i++) {
97 if(input[i]-base < fDecay[decayCounter].first*
max) {
98 double time = i - (fDecay[decayCounter].first*
max - input[i]+base)/(input[i-1] - input[i]);
99 if(decay[fDecay[decayCounter].second] ==
Q_DOUBLE_DEFAULT) decay[fDecay[decayCounter].second] = -time;
100 else decay[fDecay[decayCounter].second] += time;
104 if(decayCounter < 0)
break;
108 for(
size_t v = 0; v < decay.size();v++) {
119 return l.first < r.first;
124 return l.first > r.first;
error class with error type and description
QPulseTimeConstants(const std::vector< Diana::QInterval > &riseIntervals, const std::vector< Diana::QInterval > &decayIntervals)
static bool PairComparatorAsc(const std::pair< double, int > l, std::pair< double, int > r)
static bool PairComparatorDesc(const std::pair< double, int > l, std::pair< double, int > r)
QError Compute(const Diana::QVector &input, const int maxpos, const double baseLine, std::vector< double > &rise, std::vector< double > &decay)
the Diana namespace is needed because sometimes we use Qt libraries, that use same class names of our...