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

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