1 | #include <stdio.h>
|
---|
2 | #include <iostream>
|
---|
3 |
|
---|
4 | using namespace std;
|
---|
5 |
|
---|
6 | // this function reads a (hopefully smoothed, and baseline corrected) DRS pipeline and produces
|
---|
7 | // The DRs pipiline is given as a vector<float>.
|
---|
8 | //
|
---|
9 | // the Output is a vector of Over-Threshold-Regions, which are described by
|
---|
10 | // * the index of its start
|
---|
11 | // * the index of its Maximum
|
---|
12 | // * the index of its end
|
---|
13 | // * the height of its Maximum
|
---|
14 | //
|
---|
15 | // it needs a threshold and the length of the falling edge
|
---|
16 |
|
---|
17 | #include "discriminator.h"
|
---|
18 |
|
---|
19 | vector<Region> * discriminator(
|
---|
20 | vector<float>& input, // vector of floats, the discriminator acts on
|
---|
21 | float thr, // threshold
|
---|
22 | bool clean, // choose here, if the discriminator should already discard Regions, which are assumend to sit on the predessesors falling edge
|
---|
23 | int fallingEdge, // number of slices, after the maximum, which should be discarded...
|
---|
24 | bool debug
|
---|
25 | ){ //----- start of function discrimnator--------
|
---|
26 |
|
---|
27 | // this vector will contain the Region, found by the simple
|
---|
28 | // discriminator
|
---|
29 | vector<Region> * uncleaned = new vector<Region>;
|
---|
30 |
|
---|
31 | // The former vector will be cleaned, by checking the distance of the
|
---|
32 | // position of the Maxima .... Maxima, sitting on
|
---|
33 | // falling edges of other pulses, should be discarded.
|
---|
34 | vector<Region> * Cleaned = new vector<Region>;
|
---|
35 |
|
---|
36 | Region currentRegion;
|
---|
37 | currentRegion.begin = 0;
|
---|
38 | currentRegion.end = 0;
|
---|
39 | currentRegion.maxPos = 0;
|
---|
40 | currentRegion.maxVal = 0.;
|
---|
41 | bool over_thr_found = false;
|
---|
42 |
|
---|
43 | for ( unsigned int sl = 0; sl < input.size() ; sl++ ){
|
---|
44 | if ( input[sl] > thr ) {
|
---|
45 | // mark as -start-
|
---|
46 | if ( !over_thr_found ) {
|
---|
47 | over_thr_found = true;
|
---|
48 | currentRegion.begin = sl;
|
---|
49 | }
|
---|
50 |
|
---|
51 | // Find the -Maximum- in this Region
|
---|
52 | if ( input[sl] > currentRegion.maxVal) {
|
---|
53 | currentRegion.maxVal = input[sl];
|
---|
54 | currentRegion.maxPos = sl;
|
---|
55 | }
|
---|
56 |
|
---|
57 | } else if ( input[sl] < thr ) {
|
---|
58 |
|
---|
59 | // mark the -end-
|
---|
60 | if ( over_thr_found ) {
|
---|
61 | over_thr_found = false;
|
---|
62 | currentRegion.end = sl;
|
---|
63 | // store the region in a vector.
|
---|
64 | uncleaned->push_back(currentRegion);
|
---|
65 | currentRegion.begin = 0;
|
---|
66 | currentRegion.end = 0;
|
---|
67 | currentRegion.maxPos = 0;
|
---|
68 | currentRegion.maxVal = 0.;
|
---|
69 | }
|
---|
70 | }
|
---|
71 | } // end of for loop over all slices
|
---|
72 |
|
---|
73 | if (debug){ // output the vector
|
---|
74 | cout << "------------Discriminator Debug Output:"
|
---|
75 | <<"----------------" << endl;
|
---|
76 | cout << "\t uncleaned Over Threshold Regions found: "
|
---|
77 | << uncleaned->size() << endl;
|
---|
78 | for (unsigned int p=0 ; p < uncleaned->size() ; p++ ){
|
---|
79 | cout << p << ":\t";
|
---|
80 | cout << uncleaned->at(p).begin << "\t";
|
---|
81 | cout << uncleaned->at(p).end << "\t";
|
---|
82 | cout << uncleaned->at(p).maxPos << "\t";
|
---|
83 | cout << uncleaned->at(p).maxVal << endl;
|
---|
84 | }
|
---|
85 | }
|
---|
86 |
|
---|
87 | if (clean){
|
---|
88 | cleanRegionsOnFallingEdge ( *Cleaned, *uncleaned, fallingEdge, debug);
|
---|
89 | delete uncleaned;
|
---|
90 | return Cleaned;
|
---|
91 | } else
|
---|
92 | return uncleaned;
|
---|
93 |
|
---|
94 |
|
---|
95 |
|
---|
96 |
|
---|
97 | } // end of function - discriminator
|
---|
98 | ///////////////////////////////////////////////////////////////////////////////////////
|
---|
99 |
|
---|
100 |
|
---|
101 |
|
---|
102 |
|
---|
103 | ////////// Cleaning Funcs ////////////
|
---|
104 |
|
---|
105 | int cleanRegionsOnFallingEdge (
|
---|
106 | vector<Region> &dest,
|
---|
107 | vector<Region> &src,
|
---|
108 | int fallingEdgeLen,
|
---|
109 | bool debug
|
---|
110 | ){
|
---|
111 | // This function scans the src-vector for Maxima, sitting on its predesessors falling edge.
|
---|
112 | // the out vector is cleaned from these regions.
|
---|
113 | // note: the cleaned regions are appended to the dest-vector.
|
---|
114 | //
|
---|
115 | //
|
---|
116 | // note further: in case pulses pile up to form a broad Region over threshold
|
---|
117 | // the maximum of this region is caused by pile up, even though is is far away from the next region.
|
---|
118 | // TODO
|
---|
119 | // write another cleaning function - or implement into this function a check,
|
---|
120 | // if the maximum the first of all local maxima in the region.
|
---|
121 | // maybe the search for the maximum should be oursourced and not be done in the first
|
---|
122 | // discrimnator loop in line 51ff...
|
---|
123 |
|
---|
124 | if (dest.size() > 0 && debug)
|
---|
125 | cout << "discriminator::cleanRegionsOnFallingEdge: destination vector.size()=" << dest.size() << endl;
|
---|
126 |
|
---|
127 | // if nothing to do
|
---|
128 | if (src.size() == 0){
|
---|
129 | if (debug)
|
---|
130 | cout << "discriminator::cleanRegionsOnFallingEdge: src vector empty" << endl;
|
---|
131 | return -1;
|
---|
132 | }
|
---|
133 |
|
---|
134 | // local copy of source
|
---|
135 | vector<Region> localSrc(src);
|
---|
136 | // last Region in (local)-src
|
---|
137 | Region last;
|
---|
138 | while (!localSrc.empty()){
|
---|
139 | last = localSrc.back();
|
---|
140 | localSrc.pop_back();
|
---|
141 | // last.begin = result->back().begin;
|
---|
142 | // last.end = result->back().end;
|
---|
143 | // last.maxPos = result->back().maxPos;
|
---|
144 | // last.maxVal = result->back().maxVal;
|
---|
145 |
|
---|
146 | // if localSrc is _now_ empty, then there was no predecessor
|
---|
147 | if (localSrc.empty()){
|
---|
148 | dest.push_back(last);
|
---|
149 | break;
|
---|
150 | }
|
---|
151 | if (last.maxPos - localSrc.back().maxPos > fallingEdgeLen)
|
---|
152 | dest.push_back(last);
|
---|
153 | }
|
---|
154 |
|
---|
155 | if (debug){ // output the vector
|
---|
156 | cout << "------------Discriminator::CleanRegionsOnFallingEdge - Debug Output:----------------" << endl;
|
---|
157 | cout << "\t Cleaned Regions found: " << dest.size() << endl;
|
---|
158 | for (unsigned int p=0 ; p < dest.size() ; p++ ){
|
---|
159 | cout << p << ":\t";
|
---|
160 | cout << dest.at(p).begin << "\t";
|
---|
161 | cout << dest.at(p).end << "\t";
|
---|
162 | cout << dest.at(p).maxPos << "\t";
|
---|
163 | cout << dest.at(p).maxVal << endl;
|
---|
164 | }
|
---|
165 | }
|
---|
166 |
|
---|
167 | return 0;
|
---|
168 | }
|
---|
169 |
|
---|
170 | ////// alternative loop, but it didn't work ////////////////
|
---|
171 | /*
|
---|
172 | vector<vector<DiscOut>::iterator> toBeDeleted;
|
---|
173 |
|
---|
174 | for (vector<DiscOut>::iterator it=result->begin(); it != result->end()-1; ++it ){
|
---|
175 | if ( (*it).begin==0 ){
|
---|
176 | toBeDeleted.push_back(it);
|
---|
177 | }
|
---|
178 | if ( ((*(it+1)).maxPos - (*it).maxPos) < fallingEdge ){
|
---|
179 | toBeDeleted.push_back(it);
|
---|
180 | }
|
---|
181 | }
|
---|
182 |
|
---|
183 | for (int i=0; i<toBeDeleted.size(); i++) {
|
---|
184 | result->erase(toBeDeleted[i]);
|
---|
185 | if (debug)
|
---|
186 | cout << "erased peak at:" << (*toBeDeleted[i]).maxPos << endl;
|
---|
187 | }
|
---|
188 | */
|
---|
189 |
|
---|
190 |
|
---|
191 |
|
---|