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

Last change on this file since 17894 was 15368, checked in by Jens Buss, 12 years ago
add functions
File size: 20.2 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){
21vector<Region> * ZeroPositions = new vector<Region>;
22Region currentRegion = {0, 0, 0, 0.0, 0, 0.0, 0.0, 0, 0};
23
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 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 return ZeroPositions;
84}
85
86size_t ShiftRegionBy(vector<Region> &src,
87 int Shift,
88 int VerbosityLevel)
89{
90 vector<Region>::iterator it;
91 // I copy code here ... not good, but I hope nobody is giving VL > 10 ever...
92 if (VerbosityLevel > 10){
93 for (it = src.begin() ; it < src.end() ; it++){
94 cout << " it->begin="<< it->begin;
95 it->begin += Shift;
96 cout << "--> shifted="<< it->begin << endl;
97 cout << " it->end="<< it->end;
98 it->end += Shift;
99 cout << "--> shifted="<< it->end << endl;
100 cout << " it->maxPos="<< it->maxPos;
101 it->maxPos += Shift;
102 cout << "--> shifted="<< it->maxPos << endl;
103 }
104 return src.size();
105 }
106
107 for (it = src.begin() ; it < src.end() ; it++){
108 it->begin += Shift;
109 it->end += Shift;
110 it->maxPos += Shift;
111 }
112 return src.size();
113}
114
115size_t EnlargeRegion(vector<Region> &src,
116 int Left,
117 int Right,
118 int VerbosityLevel)
119{
120 vector<Region>::iterator it;
121 // I copy code here ... not good, but I hope nobody is giving VL > 10 ever...
122 if (VerbosityLevel > 10){
123 for (it = src.begin() ; it < src.end() ; it++){
124 cout << " it->begin="<< it->begin;
125 it->begin -= Left;
126 cout << "--> enlarged="<< it->begin << endl;
127 cout << " it->end="<< it->end;
128 it->end += Right;
129 cout << "--> enlarged="<< it->end << endl;
130 }
131 return src.size();
132 }
133
134
135 for (it = src.begin() ; it < src.end() ; it++){
136 it->begin -= Left;
137 it->end += Right;
138 }
139 return src.size();
140
141}
142
143#include <limits>
144size_t findAbsMaxInRegions(
145 vector<Region> &regions,
146 vector<float> &data,
147 int VerbosityLevel)
148{
149 vector<Region>::iterator reg;
150 for (reg = regions.begin() ; reg < regions.end() ; reg++){
151 reg->maxVal=-numeric_limits<float>::max();
152 // 1st check if both ends of the region are in the data-vector
153 if (reg->begin < 0) reg->begin=0;
154 if ((unsigned int)reg->end > data.size()-1) reg->end=data.size()-1;
155
156 // TODO or TOTHINKOF:
157 // Region might overlap ... I don't care .. I just search
158 // in a later step Maxima at the same Positions can be removed...
159 // of course this means, some searches were needless ...
160 //cout << "searching from " << reg->begin << " to " << reg->end << endl;
161 for (unsigned int pos=reg->begin; pos <= (unsigned int)reg->end; pos++){
162 if (data[pos] > reg->maxVal)
163 {
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 if (reg->maxPos <= 0)
174 {
175 reg = regions.erase( reg ) ;
176 --reg;
177 continue;
178 }
179 }
180 return regions.size();
181}
182
183#include <algorithm>
184bool compMaxPosOfRegions (Region a, Region b) {
185 return (a.maxPos == b.maxPos);
186}
187
188size_t removeEqualMaxima(
189 vector<Region> &regions,
190 int VerbosityLevel)
191{
192 if (VerbosityLevel > 2){
193 cout << "removeEqualMaxima:" << endl;
194 cout << "region before contains:" << endl;
195 for (unsigned int i=0; i<regions.size(); i++){
196 cout << i <<"\t";
197 cout << regions[i].begin <<"\t";
198 cout << regions[i].end <<"\t";
199 cout << regions[i].maxPos <<"\t";
200 cout << regions[i].maxVal <<"\t";
201 cout << endl;
202 }
203 }
204
205 vector<Region>::iterator it;
206 it = unique (regions.begin(), regions.end() , compMaxPosOfRegions);
207 regions.resize( it - regions.begin() );
208
209 if (VerbosityLevel > 1){
210 cout << "region now contains:" << endl;
211 for (unsigned int i=0; i<regions.size(); i++){
212 cout << i <<"\t";
213 cout << regions[i].begin <<"\t";
214 cout << regions[i].end <<"\t";
215 cout << regions[i].maxPos <<"\t";
216 cout << regions[i].maxVal <<"\t";
217 cout << endl;
218 }
219 }
220 return regions.size();
221}
222
223size_t removeRegionOnFallingEdge(
224 vector<Region> &regions,
225 unsigned int FallingEdgeWidth,
226 int VerbosityLevel)
227{
228 //throw exceptions
229 if ( FallingEdgeWidth < 1){
230 if (VerbosityLevel > 0){
231 cout << " removeRegionOnFallingEdge: FallingEdgeWidth < 1" << endl;
232 cout << " FallingEdgeWidth =" << FallingEdgeWidth << endl;
233 cout << "returning." << endl;
234 return regions.size();
235 }
236 }
237 //throw exceptions
238 if (regions.size() < 1){
239 if (VerbosityLevel > 3)
240 cout << "removeRegionOnFallingEdge: source vector empty." << endl;
241 return 0;
242 }
243
244 vector<Region>::reverse_iterator it = regions.rbegin();
245 while( it != regions.rend()-1 )
246 {
247 if (VerbosityLevel >10)
248 cout << it->maxPos << "\t" << (it+1)->maxPos << "\t" << it->maxPos - (it+1)->maxPos << endl;
249
250 if ( it->maxPos - (it+1)->maxPos < (int)FallingEdgeWidth) {
251 if (VerbosityLevel > 3)
252 cout << "erasing Region @ " << it->maxPos << endl;
253 regions.erase( --it.base() ) ;
254 ++it;
255 }else
256 ++it;
257 }
258
259 return regions.size();
260}
261
262
263size_t removeRegionWithMaxOnEdge(
264 vector<Region> &regions,
265 unsigned int EdgeWidth,
266 int VerbosityLevel)
267{
268 if (EdgeWidth < 1){
269 if (VerbosityLevel > 0){
270 cout << "removeRegionWithMaximaOnEdge: EdgeWidth < 1" << endl;
271 cout << "EdgeWidth=" << EdgeWidth << endl;
272 cout << "returning." << endl;
273 return regions.size();
274 }
275 }
276
277 vector<Region>::iterator it = regions.begin();
278 while( it != regions.end() )
279 {
280// cout << it->begin << "\t";
281// cout << it->maxPos << "\t";
282// cout << it->end << "\t";
283// cout << it->maxVal << endl;
284
285 if (it->maxPos < (int)(it->begin+EdgeWidth)) {
286 if (VerbosityLevel > 3)
287 cout << "erasing Region(max@left edge) " << it->maxPos << endl;
288 it = regions.erase( it ) ;
289 //++it;
290 }else if (it->maxPos > (int)(it->end-EdgeWidth)) {
291 if (VerbosityLevel > 3)
292 cout << "erasing Region(max@right edge) " << it->maxPos << endl;
293 it = regions.erase( it ) ;
294 //++it;
295 }else
296 ++it;
297
298 }
299
300 return regions.size();
301}
302
303size_t removeMaximaBelow(
304 vector<Region> &regions,
305 float threshold,
306 int VerbosityLevel)
307{
308// if (threshold < 0){
309// if (VerbosityLevel > 0)
310// cout << "removeMaximaBelow: threshold < 0" << endl;
311// cout << "threshold=" << threshold << endl;
312// cout << "returning." << endl;
313// return regions.size();
314// }
315
316 vector<Region>::iterator it = regions.begin();
317 while( it != regions.end() )
318 {
319 if (it->maxVal < threshold ) {
320 if (VerbosityLevel > 3){
321 cout << "removing max " << it->maxVal << "\t";
322 cout << " @ " << it->maxPos << "\t";
323 cout << endl;
324 }
325 it = regions.erase( it ) ;
326 }else
327 ++it;
328 }
329
330 return regions.size();
331}
332
333size_t removeMaximaAbove(
334 vector<Region> &regions,
335 float threshold,
336 int VerbosityLevel)
337{
338 if (threshold < 0){
339 if (VerbosityLevel > 0)
340 cout << "removeMaximaAbove: threshold < 0" << endl;
341 cout << "threshold=" << threshold << endl;
342 cout << "returning." << endl;
343 return regions.size();
344 }
345
346 vector<Region>::iterator it = regions.begin();
347 while( it != regions.end() )
348 {
349 if (it->maxVal > threshold ) {
350 if (VerbosityLevel > 3){
351 cout << "removing max " << it->maxVal << "\t";
352 cout << " @ " << it->maxPos << "\t";
353 cout << endl;
354 }
355 it = regions.erase( it ) ;
356 }else
357 ++it;
358 }
359
360 return regions.size();
361}
362
363Region FindAbsMax(
364 vector<Region> &regions,
365 int VerbosityLevel)
366{
367 Region AbsMax;
368 AbsMax.begin = -1;
369 AbsMax.maxPos = -1;
370 AbsMax.end = -1;
371 AbsMax.maxVal=-numeric_limits<float>::max();
372 if (regions.size() < 1)
373 return AbsMax;
374
375 for (vector<Region>::iterator it = regions.begin(); it < regions.end(); ++it)
376 {
377 if (it->maxVal > AbsMax.maxVal ) {
378 AbsMax = *it;
379 }
380 }
381 if (VerbosityLevel > 5){
382 AbsMax.begin +=0;
383 }
384 return AbsMax;
385}
386
387////////////////
388////////////// old Version of the code
389/*
390 for (unsigned int sl = step; sl < input.size(); sl+=step){
391 if (input[sl] * input[sl-] < 0 || input[sl]==0.0 ){ // sign change --> zero crossing OR really zero
392
393 if ( (input[sl-1] - input[sl]) * edge < 0){ // this is the crossing the user wanted
394
395 // check if we go lower than a certain limit in the next few slices
396 for ( int lala=0; lala<post; lala++){
397 if (input[sl+lala] > 1.5) {
398 zeroPositions->push_back(sl);
399 sl += lala;
400 break;
401 }
402 }
403
404 } else if ( (input[sl-1] - input[sl]) * edge > 0){ // this is the zero x-ing the user did not want
405
406 // do nothing
407
408 } else { // sl and sl-1 are equal .. don't know waht do to...
409
410 }
411
412 }
413
414 } // end of loop over slices - between pre and post
415
416*/
417
418//size_t calcAmplitudeWeightedTime(
419// vector<Region> &regions,
420// vector<float> &data,
421
422// ){
423
424//}
425
426size_t calcCFDPositions(
427 vector<Region> &regions,
428 vector<float> &cfd_data
429 )
430{
431 vector<Region>::iterator reg;
432 for (reg = regions.begin() ; reg < regions.end() ; reg++)
433 {
434 int neg_zero_crossing = -1;
435 int min_in_cfd = -1;
436 int pos_zero_crossing = reg->maxPos;
437 float minVal = 10.0;
438
439 for (int i = pos_zero_crossing; i > pos_zero_crossing - 40; i--)
440 {
441 if (i <= 1 || i >= 1439) break;
442
443 if ( cfd_data[i] < minVal)
444 {
445 minVal = cfd_data[i];
446 min_in_cfd = i;
447 }
448
449 if (cfd_data[i] > 0 && cfd_data[i+1] <= 0 && cfd_data[i+2] < 0 )
450 {
451 neg_zero_crossing = i+1;
452 }
453 }
454
455 reg->cfdMinPos = min_in_cfd;
456 reg->cfdNegZerocrossing = neg_zero_crossing;
457 }
458 return regions.size();
459}
460
461
462
463size_t findTimeOfHalfMaxLeft(
464 vector<Region> &regions,
465 vector<float> &data,
466 float baseline,
467 int beginRisingEdge,
468 int endRisingEdge,
469 int VerbosityLevel
470 )
471{
472// float pulse_size = 0; //
473 float thr = 0;
474 //int begin = beginRisingEdge;
475 int end = 20;
476 int counter = 0;
477 // local vars for line fitting
478 float xmean = 0.0;
479 float ymean = 0.0;
480 float cov = 0.0; // empiric covariance between x and y
481 float var = 0.0; // empiric variance of x
482 // result of line fitting
483 float slope = 0.0;
484 float intercept = 0.0;
485 // result of this function -- the position of the half rising edge
486 float pos_of_thr_Xing = 0.0;
487 int result = 0;
488
489
490 vector<Region>::iterator reg;
491 for (reg = regions.begin() ; reg < regions.end() ; reg++)
492 {
493 // check if linear rising edge is completely in pipeline
494 // if not --> delete
495 if ( reg->maxPos - end < 0 )
496 {
497 // delete this region from vector<Region>
498 reg = regions.erase( reg ) ;
499 --reg;
500 continue;
501 }
502
503 // I think 5 slices left of the max there begins the rising edge
504 // and I think the rising edge is about 6 slices long.
505 // but these numbers are input as parameters
506 // beginRisingEdge &
507 // endRisingEdge
508
509 // I fit a linear function to the falling edge
510 // ALARM check for out of range values...
511
512 float average_of_max = -1;
513 int stepwidth = 2;
514
515 counter = 0;
516 for ( int i = reg->maxPos -stepwidth; i <= reg->maxPos + stepwidth; i++)
517 {
518 average_of_max += data[i];
519 counter++;
520 }
521 average_of_max /= counter;
522
523 thr = average_of_max / 2.0;
524
525 float max_slope = 0;
526 int max_slope_pos = -1;
527 int half_height_pos = -1;
528
529 bool passed = false;
530 for (int slice=reg->maxPos; slice > reg->maxPos - end; --slice)
531 {
532 if (slice <= 0) break;
533// if ( data[slice] < 0.9*data[reg->maxPos] && !passed)
534// {
535// endRisingEdge = slice;
536// beginRisingEdge = endRisingEdge -3;
537// passed = true;
538// }
539// else if ( data[slice] < 0) //0.4*data[reg->maxPos] )
540// {
541// beginRisingEdge = slice;
542// reg->lengthOfRisingEdge=endRisingEdge - beginRisingEdge;
543// break;
544// }
545
546 //calculate max slope on leading edge
547 if (data[slice] - data[slice-4] > max_slope && slice-4 > 0)
548 {
549 max_slope = data[slice] - data[slice-4];
550 max_slope_pos = slice-2;
551 }
552
553 if ( data[slice] <= thr && !passed){
554 half_height_pos = slice;
555 passed = true;
556 }
557 }
558 reg->maxSlope = max_slope/4;
559 reg->maxSlopePos = max_slope_pos;
560 reg->halfRisingEdgePos = half_height_pos;
561 reg->halfHeight = data[half_height_pos];
562
563 result = half_height_pos;
564
565 endRisingEdge = result +2;
566 beginRisingEdge = result -2;
567
568 counter = 0;
569 //calculate mean of x and y coordinate
570 for (int slice= beginRisingEdge; slice < endRisingEdge; ++slice)
571 {
572 if (slice <= 0) break;
573
574 xmean += slice;
575 ymean += data[slice];
576 counter++;
577 }
578 xmean /= counter;
579 ymean /= counter;
580
581 if (VerbosityLevel > 2) cout << "## xmean: " << xmean << endl;
582 if (VerbosityLevel > 2) cout << "## ymean: " << ymean << endl;
583
584 cov = 0.0;
585 var = 0.0;
586
587 //calculate covariance and variance
588 for (int slice=beginRisingEdge; slice < endRisingEdge; ++slice)
589 {
590 if (slice <= 0) break;
591
592 cov += (data[slice] - ymean) * (slice - xmean);
593 var += (slice - xmean) * (slice - xmean);
594 }
595 if (VerbosityLevel > 2) cout << "## cov: " << cov << endl;
596 if (VerbosityLevel > 2) cout << "## var: " << var << endl;
597
598 slope = cov / var;
599 intercept = ymean - slope * xmean;
600
601 // The maximum was probably found using smoothed data,
602 // so I read the value at the position of the maximum from the data
603 // again. So I rely on a well defined maxPos.
604// if (VerbosityLevel > 4) cout << "## baseline: " << baseline << endl;
605// pulse_size = data[reg->maxPos] - baseline;
606// if (VerbosityLevel > 4) cout << "## pulse_size: " << pulse_size << endl;
607// thr = pulse_size / 2. + baseline;
608// if (VerbosityLevel > 4) cout << "## thr: " << thr << endl;
609
610 // now calculate, where the fittet line crosses the threshold
611// pos_of_thr_Xing = (thr - intercept) / slope;
612// result = (int)(pos_of_thr_Xing + 0.5);
613
614
615 if (VerbosityLevel > 2)
616 {
617 cout << "findTimeOfHalfMaxLeft() is still in debugging phase:" << endl;
618 cout << "please edit the code in oder to suppress this output:" << endl;
619 cout << "threshold: " << thr << endl;
620 cout << "slope: " << slope << " [mV/timeslice]" << endl;
621 cout << "intercept: " << intercept << "[mV]" << endl;
622 cout << "position where line crosses threshold " << pos_of_thr_Xing << endl;
623 cout << "converted to slice number " << result << endl;
624
625 }
626
627 reg->distanceEdgeToMax = reg->maxPos - result;
628 reg->interceptRisingEdge = reg->maxPos - intercept;
629 reg->slopeOfRisingEdge = slope;
630
631 if (reg->halfRisingEdgePos <= 0 || reg->halfRisingEdgePos >= 1024)
632 {
633 reg = regions.erase( reg ) ;
634 --reg;
635 continue;
636 }
637 }
638 return regions.size();
639}
640
641size_t removeRegionWithToFlatSlope(
642 vector<Region> &regions,
643 float minSlope,
644 int VerbosityLevel)
645{
646 vector<Region>::iterator it = regions.begin();
647 while( it != regions.end() )
648 {
649 if (it->slopeOfRisingEdge < minSlope ) {
650 if (VerbosityLevel > 3){
651 cout << "removing max " << it->maxVal << "\t";
652 cout << " @ " << it->maxPos << "\t";
653 cout << endl;
654 }
655 it = regions.erase( it ) ;
656 }else
657 ++it;
658 }
659
660 return regions.size();
661}
662
663size_t GetMaxPositions(
664 vector<Region> &regions,
665 vector<int> &positions,
666 int VerbosityLevel)
667{
668 positions.clear();
669 vector<Region>::iterator it = regions.begin();
670 while( it != regions.end() )
671 {
672 positions.push_back(it->maxPos);
673 if (VerbosityLevel > 3){
674 cout << "getting maxPos@ " << it->maxPos << "\t";
675 cout << endl;
676 }
677 ++it;
678 }
679
680 return regions.size();
681}
682
683size_t GetEdgePositions(
684 vector<Region> &regions,
685 vector<int> &positions,
686 int VerbosityLevel)
687{
688 positions.clear();
689 vector<Region>::iterator it = regions.begin();
690 while( it != regions.end() )
691 {
692 positions.push_back(it->halfRisingEdgePos);
693 if (VerbosityLevel > 3){
694 cout << "getting maxPos@ " << it->halfRisingEdgePos << "\t";
695 cout << endl;
696 }
697 ++it;
698 }
699
700 return regions.size();
701}
Note: See TracBrowser for help on using the repository browser.