source: fact/tools/rootmacros/zerosearch.C@ 13534

Last change on this file since 13534 was 13534, checked in by neise, 13 years ago
added a lot of includes
File size: 15.2 KB
Line 
1#include "Region.h"
2#include <iostream>
3#include <vector>
4
5#include "zerosearch.h"
6
7// searches for zero crossings in a given vector of floats
8// for zero crossings in falling edge
9// give edge = -1
10//
11//
12// returns pointer to vetctor of ints
13
14vector<Region> *zerosearch(
15 vector<float> &input,
16 int edge, // search on rising edge=1, -1:falling
17 unsigned int step, // search in steps of step
18 int VerbosityLevel
19){
20
21vector<Region> * ZeroPositions = new vector<Region>;
22Region currentRegion = {0, 0, 0, 0.0, 0, 0};
23 if (step < 1){
24 if (VerbosityLevel > 0)
25 cout << "zerosearch - stepsize=" << step
26 << " is smaller than 1. returning." << endl;
27 return ZeroPositions;
28 }
29 if (input.size() < step){
30 if (VerbosityLevel > 0)
31 cout << "zerosearch - input-vector.size()="<< input.size()
32 << " is smaller than stepsize=" << step
33 << "returning." << endl;
34 return ZeroPositions;
35 }
36
37 if (edge > 0) // search for zero-x-ings on the rising edge
38 {
39 for (unsigned int sl = 0 ; sl < (input.size()-step) ; sl+=step)
40 {
41 if (input[sl] > 0.0) // can't be a rising 0-x-ing
42 {
43 continue;
44 }
45 if (input[sl] * input[sl+step] <= 0.0) // 0-x-ing or both are 0
46 {
47 currentRegion.begin = sl;
48 currentRegion.end = sl+step;
49 ZeroPositions->push_back(currentRegion);
50 }
51 }
52 }
53 else if (edge < 0) // search for zero-x-ings on the falling edge
54 {
55 for (unsigned int sl = 0 ; sl < (input.size()-step) ; sl+=step)
56 {
57 if (input[sl] < 0.0) // can't be a falling 0-x-ing
58 {
59 continue;
60 }
61 if (input[sl] * input[sl+step] <= 0.0) // 0-x-ing or both are 0
62 {
63 currentRegion.begin = sl;
64 currentRegion.end = sl+step;
65 ZeroPositions->push_back(currentRegion);
66 }
67 }
68
69 }
70 else // search for zero-x-ings on both esges
71 {
72 for (unsigned int sl = 0 ; sl < (input.size()-step) ; sl+=step)
73 {
74 if (input[sl] * input[sl+step] <= 0.0) // 0-x-ing or both are 0
75 {
76 currentRegion.begin = sl;
77 currentRegion.end = sl+step;
78 ZeroPositions->push_back(currentRegion);
79 }
80 }
81 }
82
83
84 return ZeroPositions;
85}
86
87size_t ShiftRegionBy(vector<Region> &src,
88 int Shift,
89 int VerbosityLevel)
90{
91 vector<Region>::iterator it;
92 // I copy code here ... not good, but I hope nobody is giving VL > 10 ever...
93 if (VerbosityLevel > 10){
94 for (it = src.begin() ; it < src.end() ; it++){
95 cout << " it->begin="<< it->begin;
96 it->begin += Shift;
97 cout << "--> shifted="<< it->begin << endl;
98 cout << " it->end="<< it->end;
99 it->end += Shift;
100 cout << "--> shifted="<< it->end << endl;
101 cout << " it->maxPos="<< it->maxPos;
102 it->maxPos += Shift;
103 cout << "--> shifted="<< it->maxPos << endl;
104 }
105 return src.size();
106 }
107
108 for (it = src.begin() ; it < src.end() ; it++){
109 it->begin += Shift;
110 it->end += Shift;
111 it->maxPos += Shift;
112 }
113 return src.size();
114}
115
116size_t EnlargeRegion(vector<Region> &src,
117 int Left,
118 int Right,
119 int VerbosityLevel)
120{
121 vector<Region>::iterator it;
122 // I copy code here ... not good, but I hope nobody is giving VL > 10 ever...
123 if (VerbosityLevel > 10){
124 for (it = src.begin() ; it < src.end() ; it++){
125 cout << " it->begin="<< it->begin;
126 it->begin -= Left;
127 cout << "--> enlarged="<< it->begin << endl;
128 cout << " it->end="<< it->end;
129 it->end += Right;
130 cout << "--> enlarged="<< it->end << endl;
131 }
132 return src.size();
133 }
134
135
136 for (it = src.begin() ; it < src.end() ; it++){
137 it->begin -= Left;
138 it->end += Right;
139 }
140 return src.size();
141
142}
143
144#include <limits>
145size_t findAbsMaxInRegions(
146 vector<Region> &regions,
147 vector<float> &data,
148 int VerbosityLevel)
149{
150 vector<Region>::iterator reg;
151 for (reg = regions.begin() ; reg < regions.end() ; reg++){
152 reg->maxVal=-numeric_limits<float>::max();
153 // 1st check if both ends of the region are in the data-vector
154 if (reg->begin < 0) reg->begin=0;
155 if ((unsigned int)reg->end > data.size()-1) reg->end=data.size()-1;
156
157 // TODO or TOTHINKOF:
158 // Region might overlap ... I don't care .. I just search
159 // in a later step Maxima at the same Positions can be removed...
160 // of course this means, some searches were needless ...
161 //cout << "searching from " << reg->begin << " to " << reg->end << endl;
162 for (unsigned int pos=reg->begin; pos <= (unsigned int)reg->end; pos++){
163 if (data[pos] > reg->maxVal){
164 reg->maxVal = data[pos];
165 reg->maxPos = pos;
166 }
167 }
168 if (VerbosityLevel > 3) {
169 cout << "findAbsMaxInRegions - found Max at:"
170 << reg->maxPos << " with Value:" << reg->maxVal << endl;
171 }
172 }
173 return regions.size();
174}
175
176#include <algorithm>
177bool compMaxPosOfRegions (Region a, Region b) {
178 return (a.maxPos == b.maxPos);
179}
180
181size_t removeEqualMaxima(
182 vector<Region> &regions,
183 int VerbosityLevel)
184{
185 if (VerbosityLevel > 2){
186 cout << "removeEqualMaxima:" << endl;
187 cout << "region before contains:" << endl;
188 for (unsigned int i=0; i<regions.size(); i++){
189 cout << i <<"\t";
190 cout << regions[i].begin <<"\t";
191 cout << regions[i].end <<"\t";
192 cout << regions[i].maxPos <<"\t";
193 cout << regions[i].maxVal <<"\t";
194 cout << endl;
195 }
196 }
197
198 vector<Region>::iterator it;
199 it = unique (regions.begin(), regions.end() , compMaxPosOfRegions);
200 regions.resize( it - regions.begin() );
201
202 if (VerbosityLevel > 1){
203 cout << "region now contains:" << endl;
204 for (unsigned int i=0; i<regions.size(); i++){
205 cout << i <<"\t";
206 cout << regions[i].begin <<"\t";
207 cout << regions[i].end <<"\t";
208 cout << regions[i].maxPos <<"\t";
209 cout << regions[i].maxVal <<"\t";
210 cout << endl;
211 }
212 }
213 return regions.size();
214}
215
216size_t removeRegionOnFallingEdge(
217 vector<Region> &regions,
218 unsigned int FallingEdgeWidth,
219 int VerbosityLevel)
220{
221if ( FallingEdgeWidth < 1){
222 if (VerbosityLevel > 0){
223 cout << " removeRegionOnFallingEdge: FallingEdgeWidth < 1" << endl;
224 cout << " FallingEdgeWidth =" << FallingEdgeWidth << endl;
225 cout << "returning." << endl;
226 return regions.size();
227 }
228 }
229 if (regions.size() < 1){
230 if (VerbosityLevel > 3)
231 cout << "removeRegionOnFallingEdge: source vector empty." << endl;
232 return 0;
233 }
234
235 vector<Region>::reverse_iterator it = regions.rbegin();
236 while( it != regions.rend()-1 )
237 {
238 if (VerbosityLevel >10)
239 cout << it->maxPos << "\t" << (it+1)->maxPos << "\t" << it->maxPos - (it+1)->maxPos << endl;
240
241 if ( it->maxPos - (it+1)->maxPos < (int)FallingEdgeWidth) {
242 if (VerbosityLevel > 3)
243 cout << "erasing Region @ " << it->maxPos << endl;
244 regions.erase( --it.base() ) ;
245 ++it;
246 }else
247 ++it;
248 }
249
250 return regions.size();
251}
252
253
254size_t removeRegionWithMaxOnEdge(
255 vector<Region> &regions,
256 unsigned int EdgeWidth,
257 int VerbosityLevel)
258{
259 if (EdgeWidth < 1){
260 if (VerbosityLevel > 0){
261 cout << "removeReginWithMaximaOnEdge: EdgeWidth < 1" << endl;
262 cout << "EdgeWidth=" << EdgeWidth << endl;
263 cout << "returning." << endl;
264 return regions.size();
265 }
266 }
267
268 vector<Region>::iterator it = regions.begin();
269 while( it != regions.end() )
270 {
271// cout << it->begin << "\t";
272// cout << it->maxPos << "\t";
273// cout << it->end << "\t";
274// cout << it->maxVal << endl;
275
276 if (it->maxPos < (int)(it->begin+EdgeWidth)) {
277 if (VerbosityLevel > 3)
278 cout << "erasing Region(max@left edge) " << it->maxPos << endl;
279 it = regions.erase( it ) ;
280 //++it;
281 }else if (it->maxPos > (int)(it->end-EdgeWidth)) {
282 if (VerbosityLevel > 3)
283 cout << "erasing Region(max@right edge) " << it->maxPos << endl;
284 it = regions.erase( it ) ;
285 //++it;
286 }else
287 ++it;
288
289 }
290
291 return regions.size();
292}
293
294size_t removeMaximaBelow(
295 vector<Region> &regions,
296 float threshold,
297 int VerbosityLevel)
298{
299// if (threshold < 0){
300// if (VerbosityLevel > 0)
301// cout << "removeMaximaBelow: threshold < 0" << endl;
302// cout << "threshold=" << threshold << endl;
303// cout << "returning." << endl;
304// return regions.size();
305// }
306
307 vector<Region>::iterator it = regions.begin();
308 while( it != regions.end() )
309 {
310 if (it->maxVal < threshold ) {
311 if (VerbosityLevel > 3){
312 cout << "removing max " << it->maxVal << "\t";
313 cout << " @ " << it->maxPos << "\t";
314 cout << endl;
315 }
316 it = regions.erase( it ) ;
317 }else
318 ++it;
319 }
320
321 return regions.size();
322}
323
324size_t removeMaximaAbove(
325 vector<Region> &regions,
326 float threshold,
327 int VerbosityLevel)
328{
329 if (threshold < 0){
330 if (VerbosityLevel > 0)
331 cout << "removeMaximaAbove: threshold < 0" << endl;
332 cout << "threshold=" << threshold << endl;
333 cout << "returning." << endl;
334 return regions.size();
335 }
336
337 vector<Region>::iterator it = regions.begin();
338 while( it != regions.end() )
339 {
340 if (it->maxVal > threshold ) {
341 if (VerbosityLevel > 3){
342 cout << "removing max " << it->maxVal << "\t";
343 cout << " @ " << it->maxPos << "\t";
344 cout << endl;
345 }
346 it = regions.erase( it ) ;
347 }else
348 ++it;
349 }
350
351 return regions.size();
352}
353
354Region FindAbsMax(
355 vector<Region> &regions,
356 int VerbosityLevel)
357{
358 Region AbsMax;
359 AbsMax.begin = -1;
360 AbsMax.maxPos = -1;
361 AbsMax.end = -1;
362 AbsMax.maxVal=-numeric_limits<float>::max();
363 if (regions.size() < 1)
364 return AbsMax;
365
366 for (vector<Region>::iterator it = regions.begin(); it < regions.end(); ++it)
367 {
368 if (it->maxVal > AbsMax.maxVal ) {
369 AbsMax = *it;
370 }
371 }
372 if (VerbosityLevel > 5){
373 AbsMax.begin +=0;
374 }
375 return AbsMax;
376}
377
378////////////////
379////////////// old Version of the code
380/*
381 for (unsigned int sl = step; sl < input.size(); sl+=step){
382 if (input[sl] * input[sl-] < 0 || input[sl]==0.0 ){ // sign change --> zero crossing OR really zero
383
384 if ( (input[sl-1] - input[sl]) * edge < 0){ // this is the crossing the user wanted
385
386 // check if we go lower than a certain limit in the next few slices
387 for ( int lala=0; lala<post; lala++){
388 if (input[sl+lala] > 1.5) {
389 zeroPositions->push_back(sl);
390 sl += lala;
391 break;
392 }
393 }
394
395 } else if ( (input[sl-1] - input[sl]) * edge > 0){ // this is the zero x-ing the user did not want
396
397 // do nothing
398
399 } else { // sl and sl-1 are equal .. don't know waht do to...
400
401 }
402
403 }
404
405 } // end of loop over slices - between pre and post
406
407*/
408
409
410size_t findTimeOfHalfMaxLeft(
411 vector<Region> &regions,
412 vector<float> &data,
413 float baseline,
414 int beginRisingEdge,
415 int endRisingEdge,
416 int VerbosityLevel)
417{
418 float pulse_size = 0; //
419 float thr = 0;
420
421 //int begin = beginRisingEdge;
422 int end = endRisingEdge;
423 int counter = 0;
424 // local vars for line fitting
425 float xmean = 0.0;
426 float ymean = 0.0;
427 float cov = 0.0; // empiric covarianve between x and y
428 float var = 0.0; // empiric variance of x
429 // result of line fitting
430 float slope = 0.0;
431 float intercept = 0.0;
432 // result of this function -- the position of the half rising edge
433 float pos_of_thr_Xing = 0.0;
434 int result = 0;
435
436 vector<Region>::iterator reg;
437 for (reg = regions.begin() ; reg < regions.end() ; reg++){
438
439 // check if linear falling edge is completely in pipeline
440 // if not --> delete
441 if ( reg->maxPos - end < 0 )
442 {
443 // delete this region from vector<Region>
444 reg = regions.erase( reg ) ;
445 --reg;
446 continue;
447 }
448
449 // The maximum was probably found using smoothed data,
450 // so I read the value at the position of the maximum from the data
451 // again. So I rely on a well defined maxPos.
452 if (VerbosityLevel > 1) cout << "## baseline: " << baseline << endl;
453 pulse_size = data[reg->maxPos] - baseline;
454 if (VerbosityLevel > 1) cout << "## pulse_size: " << pulse_size << endl;
455 thr = pulse_size / 2. + baseline;
456 if (VerbosityLevel > 1) cout << "## thr: " << thr << endl;
457
458 // I think 5 slices left of the max there begins the rising edge
459 // and I think the rising edge is about 6 slices long.
460 // but these numbers are input as parameters
461 // beginRisingEdge &
462 // endRisingEdge
463
464 // I fit a linear function to the falling edge
465 // ALARM check for out of range values...
466
467
468 for (int slice=reg->maxPos - beginRisingEdge;
469 slice > reg->maxPos - endRisingEdge; --slice)
470 {
471 xmean += slice;
472 ymean += data[slice];
473 counter++;
474 }
475// xmean /= beginRisingEdge - endRisingEdge;
476// ymean /= beginRisingEdge - endRisingEdge;
477 xmean /= counter;
478 ymean /= counter;
479 if (VerbosityLevel > 2) cout << "## xmean: " << xmean << endl;
480 if (VerbosityLevel > 2) cout << "## ymean: " << ymean << endl;
481
482 for (int slice=reg->maxPos - beginRisingEdge;
483 slice > reg->maxPos - endRisingEdge; --slice)
484 {
485 cov = (data[slice] - ymean) * (slice - xmean);
486 var = (slice - xmean) * (slice - xmean);
487 }
488 if (VerbosityLevel > 2) cout << "## cov: " << cov << endl;
489 if (VerbosityLevel > 2) cout << "## var: " << var << endl;
490
491 slope = cov / var;
492 intercept = ymean - slope * xmean;
493 // now calculate, where the fittet line crosses the threshold
494 pos_of_thr_Xing = (thr - intercept) / slope;
495 result = (int)(pos_of_thr_Xing + 0.5);
496
497
498 if (VerbosityLevel > 2)
499 {
500 cout << "findTimeOfHalfMaxLeft() is still in debugging phase:" << endl;
501 cout << "please edit the code in oder to suppress this output:" << endl;
502 cout << "threshold: " << thr << endl;
503 cout << "slope: " << slope << " [mV/timeslice]" << endl;
504 cout << "intercept: " << intercept << "[mV]" << endl;
505 cout << "position where line crosses threshold " << pos_of_thr_Xing << endl;
506 cout << "converted to slice number " << result << endl;
507
508 }
509
510 reg->halfRisingEdgePos = result;
511 reg->slopeOfRisingEdge = slope;
512 }
513 return regions.size();
514}
Note: See TracBrowser for help on using the repository browser.