- Timestamp:
- 02/06/05 17:40:28 (20 years ago)
- Location:
- trunk/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/SDLineFinder.cc
r368 r369 33 33 // ASAP 34 34 #include "SDLineFinder.h" 35 #include "SDFitter.h" 35 36 36 37 // STL … … 434 435 // determine the off-line variance first 435 436 // an assumption made: lines occupy a small part of the spectrum 436 437 437 438 std::vector<float> variances(edge.second-edge.first); 438 439 DebugAssert(variances.size(),AipsError); 439 440 440 441 for (;running_box->haveMore();running_box->next()) 441 442 variances[running_box->getChannel()-edge.first]= 442 443 running_box->getLinVariance(); 443 444 444 445 // in the future we probably should do a proper Chi^2 estimation 445 446 // now a simple 80% of smaller values will be used. … … 447 448 // due to a bias of the Chi^2 distribution. 448 449 stable_sort(variances.begin(),variances.end()); 450 449 451 Float offline_variance=0; 450 452 uInt offline_cnt=uInt(0.8*variances.size()); … … 459 461 Vector<Int> signs(spectrum.nelements(),0); 460 462 461 ofstream os("dbg.dat");463 //ofstream os("dbg.dat"); 462 464 for (running_box->rewind();running_box->haveMore(); 463 465 running_box->next()) { … … 471 473 else if (buf<0) signs[ch]=-1; 472 474 else if (buf==0) signs[ch]=0; 473 os<<ch<<" "<<spectrum[ch]<<" "<<running_box->getLinMean()<<" "<<474 threshold*offline_variance<<endl;475 // os<<ch<<" "<<spectrum[ch]<<" "<<running_box->getLinMean()<<" "<< 476 // threshold*offline_variance<<endl; 475 477 } 476 478 if (lines.size()) … … 578 580 SDLineFinder::SDLineFinder() throw() : edge(0,0) 579 581 { 580 // detection threshold - the minimal signal to noise ratio 581 threshold=sqrt(3.); // 3 sigma and 3 channels is a default -> sqrt(3) in 582 // a single channel 583 box_size=1./5.; // default box size for running mean calculations is 584 // 1/5 of the whole spectrum 585 // A minimum number of consequtive channels, which should satisfy 586 // the detection criterion, to be a detection 587 min_nchan=3; // default is 3 channels 582 setOptions(); 583 } 584 585 // set the parameters controlling algorithm 586 // in_threshold a single channel threshold default is sqrt(3), which 587 // means together with 3 minimum channels at least 3 sigma 588 // detection criterion 589 // For bad baseline shape, in_threshold may need to be 590 // increased 591 // in_min_nchan minimum number of channels above the threshold to report 592 // a detection, default is 3 593 // in_avg_limit perform the averaging of no more than in_avg_limit 594 // adjacent channels to search for broad lines 595 // Default is 8, but for a bad baseline shape this 596 // parameter should be decreased (may be even down to a 597 // minimum of 1 to disable this option) to avoid 598 // confusing of baseline undulations with a real line. 599 // Setting a very large value doesn't usually provide 600 // valid detections. 601 // in_box_size the box size for running mean calculation. Default is 602 // 1./5. of the whole spectrum size 603 void SDLineFinder::setOptions(const casa::Float &in_threshold, 604 const casa::Int &in_min_nchan, 605 const casa::Int &in_avg_limit, 606 const casa::Float &in_box_size) throw() 607 { 608 threshold=in_threshold; 609 min_nchan=in_min_nchan; 610 avg_limit=in_avg_limit; 611 box_size=in_box_size; 588 612 } 589 613 … … 635 659 edge.second=scan->nChan()-edge.second; 636 660 } else edge.second=scan->nChan()-edge.first; 637 if (edge.second<0 || (edge. second+edge.first)>scan->nChan())661 if (edge.second<0 || (edge.first>=edge.second)) 638 662 throw AipsError("SDLineFinder::setScan - all channels are rejected by the in_edge parameter"); 639 663 } … … 674 698 // a buffer for new lines found at this iteration 675 699 std::list<pair<int,int> > new_lines; 676 // line find algorithm677 LFAboveThreshold lfalg(new_lines,avg_factor*min_nchan, threshold);678 700 679 701 try { 702 // line find algorithm 703 LFAboveThreshold lfalg(new_lines,avg_factor*min_nchan, threshold); 680 704 lfalg.findLines(spectrum,temp_mask,edge,max_box_nchan); 681 705 first_pass=False; … … 688 712 // nothing new - proceed to the next step of averaging, if any 689 713 // (to search for broad lines) 714 if (avg_factor>avg_limit) break; // averaging up to avg_limit 715 // adjacent channels, 716 // stop after that 690 717 avg_factor*=2; // twice as more averaging 718 subtractBaseline(temp_mask,9); 691 719 averageAdjacentChannels(temp_mask,avg_factor); 692 if (avg_factor>8) break; // averaging up to 8 adjacent channels,693 // stop after that694 720 continue; 695 721 } … … 701 727 } 702 728 return int(lines.size()); 729 } 730 731 // auxiliary function to fit and subtract a polynomial from the current 732 // spectrum. It uses the SDFitter class. This action is required before 733 // reducing the spectral resolution if the baseline shape is bad 734 void SDLineFinder::subtractBaseline(const casa::Vector<casa::Bool> &temp_mask, 735 const casa::Int &order) throw(casa::AipsError) 736 { 737 AlwaysAssert(spectrum.nelements(),AipsError); 738 // use the fact that temp_mask excludes channels rejected at the edge 739 SDFitter sdf; 740 std::vector<float> absc(spectrum.nelements()); 741 for (Int i=0;i<absc.size();++i) 742 absc[i]=float(i)/float(spectrum.nelements()); 743 std::vector<float> spec; 744 spectrum.tovector(spec); 745 std::vector<bool> std_mask; 746 temp_mask.tovector(std_mask); 747 sdf.setData(absc,spec,std_mask); 748 sdf.setExpression("poly",order); 749 if (!sdf.fit()) return; // fit failed, use old spectrum 750 spectrum=casa::Vector<casa::Float>(sdf.getResidual()); 703 751 } 704 752 -
trunk/src/SDLineFinder.h
r368 r369 135 135 virtual ~SDLineFinder() throw(casa::AipsError); 136 136 137 // set the parameters controlling algorithm 138 // in_threshold a single channel threshold default is sqrt(3), which 139 // means together with 3 minimum channels at least 3 sigma 140 // detection criterion 141 // For bad baseline shape, in_threshold may need to be 142 // increased 143 // in_min_nchan minimum number of channels above the threshold to report 144 // a detection, default is 3 145 // in_avg_limit perform the averaging of no more than in_avg_limit 146 // adjacent channels to search for broad lines 147 // Default is 8, but for a bad baseline shape this 148 // parameter should be decreased (may be even down to a 149 // minimum of 1 to disable this option) to avoid 150 // confusing of baseline undulations with a real line. 151 // Setting a very large value doesn't usually provide 152 // valid detections. 153 // in_box_size the box size for running mean calculation. Default is 154 // 1./5. of the whole spectrum size 155 void setOptions(const casa::Float &in_threshold=sqrt(3.), 156 const casa::Int &in_min_nchan=3, 157 const casa::Int &in_avg_limit=8, 158 const casa::Float &in_box_size=0.2) throw(); 159 137 160 // set the scan to work with (in_scan parameter), associated mask (in_mask 138 161 // parameter) and the edge channel rejection (in_edge parameter) … … 171 194 const casa::Int &boxsize) 172 195 throw(casa::AipsError); 196 197 // auxiliary function to fit and subtract a polynomial from the current 198 // spectrum. It uses the SDFitter class. This action is required before 199 // reducing the spectral resolution if the baseline shape is bad 200 void subtractBaseline(const casa::Vector<casa::Bool> &temp_mask, 201 const casa::Int &order) throw(casa::AipsError); 173 202 174 203 // an auxiliary function to remove all lines from the list, except the … … 203 232 // the detection criterion, to be 204 233 // a detection 234 casa::Int avg_limit; // perform the averaging of no 235 // more than in_avg_limit 236 // adjacent channels to search 237 // for broad lines. see setOptions 205 238 std::list<std::pair<int, int> > lines; // container of start and stop+1 206 239 // channels of the spectral lines -
trunk/src/python_SDLineFinder.cc
r297 r369 40 40 class_<SDLineFinder>("linefinder") 41 41 .def( init <> () ) 42 .def("setoptions",&SDLineFinder::setOptions) 42 43 .def("setscan",&SDLineFinder::setScan) 43 44 .def("findlines",&SDLineFinder::findLines)
Note:
See TracChangeset
for help on using the changeset viewer.