diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..3599cbe1a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,17 @@ +language: cpp +sudo: required +dist: trusty +compiler: + - clang +os: + - osx +osx_image: xcode9.3 +ruby: 2.2.0 +before_install: + - if [ $TRAVIS_OS_NAME == osx ]; then rm '/usr/local/include/c++' && brew update && brew upgrade python && brew install root hdf5 fftw libmatio ; fi +script: + - if [ $TRAVIS_OS_NAME == osx ]; then source CI/build.sh ; fi + - if [ $TRAVIS_OS_NAME == osx ]; then source CI/test.sh ; fi +notifications: + slack: + secure: iOhvvtns12IDO/t4rV+1WlKNfqJ0bt462OnMASKfA/kCzI11rQvVBLdMt4IMsmkGo7bW3vluBrdJSnidvu8RT78NFRaaTVDvfHGMBvF0J8qHCajTAt1zrqYsQNhK7rAXBiJKj4giqGvocavaCfk7vvcLC9nHfl+tHH6Ez2xZlzysKQ/ZZRVqIr/bkt3QuizrDvdWlKhEl6BRlzS0ZTqCx5/A2BN0vghlGyx/cLOi9SrJg0CenvS/4C5g610zR6c3E2ycQ4rxYln2hc0sjE6tUMfV6oKHodeySTYCjzLFSZXjSQYid9JRy5N4c3fR5UmqICX5NVDid8HjZximSjqcNgMjCnDceobJPJ7p9e7aA+zk67YYKMHS0OC+PoDyO9s50NuCR7zEh3FQL5/wvjFhhaE04AsN6EHe1jOPY7CFOPj1LJYBCRF8FN7Rr8387xviVnuoZjjMaX4aZCZ8E930yi4JtB/4Q4dWCLM4Xouy9I+A9qCqSQf5n2TClF+1oHdkImfZBgLw6QxibhxnlkgpTID50jbN96xd/2hdhe9eTKy1M5IlOKFbLIjfRkFA+r16qIktqbiqJeastzCJJiPMLhncuuNQHIiiFg4YdKtUfFaxCDZAj7FHWpcDlfqJ0cqLvkEKuc0WgtBfA1d99KS1LzRKFvXcKBPXaTRdK2UQcuQ= diff --git a/AUTHORS b/AUTHORS index 3f34e0308..2458c8ff1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -3,26 +3,29 @@ Authors and Copyright Holders for Katydid Individuals ----------- -Christine Claessens [4] -Mathieu Guigue [2] -Jiarui Huang [1]* -Brittney Johnson [1]* -Jared Kofron [5]* -Benjamin LaRoque [3] -Noah S. Oblath [2] -Devyn Rysewyk [1]* -Luis Saldaña [6] -Penny Slocum [6] -Evan Zayas [1] +Nick Buzinsky [2] +Christine Claessens [5] +Laura Gladstone [1] +Mathieu Guigue [3] +Jiarui Huang [2]* +Brittney Johnson [2]* +Jared Kofron [6]* +Benjamin LaRoque [4] +Noah S. Oblath [3] +Devyn Rysewyk [2]* +Luis Saldaña [7] +Penny Slocum [7] +Evan Zayas [2] Institutions ------------ -1. Massachusetts Institute of Technology, Cambridge, MA -2. Pacific Northwest National Laboratory, Richland, WA -3. University of California at Santa Barbara, Santa Barbara, CA -4. University of Mainz, Mainz, Germany -5. University of Washington, Seattle, WA -6. Yale University, New Haven, CT +1. Case Western Reserve University, Cleveland, OH +2. Massachusetts Institute of Technology, Cambridge, MA +3. Pacific Northwest National Laboratory, Richland, WA +4. University of California at Santa Barbara, Santa Barbara, CA +5. University of Mainz, Mainz, Germany +6. University of Washington, Seattle, WA +7. Yale University, New Haven, CT * Former institutional association \ No newline at end of file diff --git a/CI/build.sh b/CI/build.sh new file mode 100644 index 000000000..2fcaba800 --- /dev/null +++ b/CI/build.sh @@ -0,0 +1,7 @@ +#!/bin/sh +mkdir build +cd build +cmake -DKatydid_ENABLE_TESTING=TRUE -DCMAKE_BUILD_TYPE=STANDARD .. +make -j3 +make install +cd .. diff --git a/CI/test.sh b/CI/test.sh new file mode 100644 index 000000000..0144dfc07 --- /dev/null +++ b/CI/test.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# Miscalleneous +./build/bin/TestRandom + +# Spectrum Analysis +./build/bin/TestTrackProcessing + +# Event Analysis +./build/bin/TestDBScanTrackClustering +./build/bin/TestSequentialTrackFinder +./build/bin/TestSpectrumDiscriminator diff --git a/CMakeLists.txt b/CMakeLists.txt index ac2372bf7..fae853098 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required (VERSION 3.1) # Define the project cmake_policy( SET CMP0048 NEW ) # version in project() -project (Katydid VERSION 2.11.1) +project (Katydid VERSION 2.12.0) list( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/Nymph/Scarab/cmake ) include( PackageBuilder ) diff --git a/Cicada b/Cicada index 2b401ef5b..d982b5cb3 160000 --- a/Cicada +++ b/Cicada @@ -1 +1 @@ -Subproject commit 2b401ef5baba533452588c2828c8abc48cd012eb +Subproject commit d982b5cb30a23f5bbc3e4f37082cdc2c5ec4ea22 diff --git a/Documentation/validation_log.rst b/Documentation/validation_log.rst index db0f2416d..5f841602d 100644 --- a/Documentation/validation_log.rst +++ b/Documentation/validation_log.rst @@ -12,7 +12,7 @@ Guidelines * Indicate in this log what tests were performed, and where to find a writeup of the results. * Fixes to existing features should also be validated. * Perform tests to show that the fix solves the problem that had been indicated. - * Perform tests to shwo that the fix does not cause other problems. + * Perform tests to show that the fix does not cause other problems. * Indicate in this log what tests were performed and how you know the problem was fixed. Template @@ -43,6 +43,41 @@ Fixes: Log --- +Version: 2.12.0 +~~~~~~~~~~~~~~~ + +Release Date: July 5, 2018 +''''''''''''''''''''''''''''''' + +New Features +'''''''''''' + +* Moving the default object name from the Katydid Writer into Cicada: + * TMultiTrackEventData + * TProcessedTrackData + * TProcessedMPTData + * TClassifierResultsData +* Continuous Integration with Travis: + * Automatic build of libraries and validation executable + * Test of one executable (TestRandom) + * Slack message upon success or failure +* Track SNR and NUP: + * Adding a KTDiscriminatedPoint structure that would be common to data objects using points obtained by discrimination. + * Propagating the new structure to SparseWaterfallCandidateData and related classes (tested with TestDBScanTrackClustering) + * KTSpectrumDiscriminator and KTVariableSpectrumDiscriminator: new member variables of KTDiscriminatedPoints1DData are calculated and set. + * KTTrackProcessing: split the KTProcessingTrack processor into two processors: KTTrackProcessingDoubleCuts and KTTrackProcessingWeightedSlope. + * KTTrackProcessingWeightedSlope handles both SequentialLineData and SparseWaterfallCandidateData; while KTTrackProcessingDoubleCuts only connects to SparseWaterfallCandidateData (with HoughData). + * Adding new track properties to the KTProcessedTrackData result (Tested with TestTrackProcessing). + * KTMultiTrackEventData and KTProcessedTrackData: added member variables for SNR and NUP quantities. + * KTSequentialLineData: new version of KTSeqLine. Has SNR and NUP member variables. LineTrimming now uses SNR instead of Power. + * KTSequentialTrackFinder: new slot for KTDiscriminatedPoints1DData only. Signal is now KTSequentialLineData. + * KTOverlappingTrackClustering and KTIterativeTrrackClustering: new slot and singal for KTSequentialLineData. Both Processors can no longer apply cuts. + * KTSequentialLineSNRCut and KTSequentialLineNUPCut: can be used to apply cuts on total and average SNR and NUP of KTSequentialLineData. + * KTEventFirstTrackSNR and KTEventFirstTrackNUPCut: can be used to apply cuts on total and average SNR and NUP of KTMultiTrackEventData. +* Writers update: + * KTSparseWaterfallCandidateData objects: TDiscriminatedPoint and TSparseWaterfallCandidateData classes have been added. + + Version: 2.11.1 ~~~~~~~~~~~~~~~ @@ -55,7 +90,6 @@ Fixes: * Nymph upgraded to v1.4.5 * Commented out incorrect calculation of variance in KTGainVariationProcessor. - Version: 2.11.0 ~~~~~~~~~~~~~~~ diff --git a/Source/Data/CMakeLists.txt b/Source/Data/CMakeLists.txt index 940c8a01a..95e1e30f1 100644 --- a/Source/Data/CMakeLists.txt +++ b/Source/Data/CMakeLists.txt @@ -7,6 +7,7 @@ set (DATA_HEADERFILES SpectrumAnalysis/KTCluster1DData.hh SpectrumAnalysis/KTCorrelationData.hh SpectrumAnalysis/KTCorrelationTSData.hh + SpectrumAnalysis/KTDiscriminatedPoint.hh SpectrumAnalysis/KTDiscriminatedPoints1DData.hh SpectrumAnalysis/KTDiscriminatedPoints2DData.hh SpectrumAnalysis/KTGainVarChi2Data.hh @@ -16,7 +17,7 @@ set (DATA_HEADERFILES SpectrumAnalysis/KTKDTreeData.hh SpectrumAnalysis/KTNormalizedFSData.hh SpectrumAnalysis/KTPointCloud.hh - SpectrumAnalysis/KTSeqLine.hh + SpectrumAnalysis/KTSequentialLineData.hh SpectrumAnalysis/KTTimeSeriesDist.hh SpectrumAnalysis/KTTimeSeriesDistData.hh SpectrumAnalysis/KTWV2DData.hh @@ -80,7 +81,7 @@ set (DATA_SOURCEFILES SpectrumAnalysis/KTHoughData.cc SpectrumAnalysis/KTKDTreeData.cc SpectrumAnalysis/KTNormalizedFSData.cc - SpectrumAnalysis/KTSeqLine.cc + SpectrumAnalysis/KTSequentialLineData.cc SpectrumAnalysis/KTTimeSeriesDist.cc SpectrumAnalysis/KTTimeSeriesDistData.cc SpectrumAnalysis/KTWV2DData.cc diff --git a/Source/Data/EventAnalysis/KTMultiTrackEventData.cc b/Source/Data/EventAnalysis/KTMultiTrackEventData.cc index 81ac57539..bcc260514 100644 --- a/Source/Data/EventAnalysis/KTMultiTrackEventData.cc +++ b/Source/Data/EventAnalysis/KTMultiTrackEventData.cc @@ -45,6 +45,13 @@ namespace Katydid fFirstTrackSlope(0.), fFirstTrackIntercept(0.), fFirstTrackTotalPower(0.), + fFirstTrackNTrackBins(0), + fFirstTrackTotalSNR(0.), + fFirstTrackMaxSNR(0.), + fFirstTrackTotalNUP(0.), + fFirstTrackMaxNUP(0.), + fFirstTrackTotalWideSNR(0.), + fFirstTrackTotalWideNUP(0.), fUnknownEventTopology(false), fTracks() { @@ -77,6 +84,13 @@ namespace Katydid fFirstTrackSlope(orig.fFirstTrackSlope), fFirstTrackIntercept(orig.fFirstTrackIntercept), fFirstTrackTotalPower(orig.fFirstTrackTotalPower), + fFirstTrackNTrackBins(orig.fFirstTrackNTrackBins), + fFirstTrackTotalSNR(orig.fFirstTrackTotalSNR), + fFirstTrackMaxSNR(orig.fFirstTrackMaxSNR), + fFirstTrackTotalNUP(orig.fFirstTrackTotalNUP), + fFirstTrackMaxNUP(orig.fFirstTrackMaxNUP), + fFirstTrackTotalWideSNR(orig.fFirstTrackTotalWideSNR), + fFirstTrackTotalWideNUP(orig.fFirstTrackTotalWideNUP), fUnknownEventTopology(orig.fUnknownEventTopology), fTracks() { @@ -253,6 +267,14 @@ namespace Katydid fFirstTrackIntercept = trackIt->fProcTrack.GetIntercept(); fFirstTrackTotalPower = trackIt->fProcTrack.GetTotalPower(); + fFirstTrackNTrackBins = trackIt->fProcTrack.GetNTrackBins(); + fFirstTrackTotalSNR = trackIt->fProcTrack.GetTotalTrackSNR(); + fFirstTrackMaxSNR = trackIt->fProcTrack.GetMaxTrackSNR(); + fFirstTrackTotalNUP = trackIt->fProcTrack.GetTotalTrackNUP(); + fFirstTrackMaxNUP = trackIt->fProcTrack.GetMaxTrackNUP(); + fFirstTrackTotalWideSNR = trackIt->fProcTrack.GetTotalWideTrackSNR(); + fFirstTrackTotalWideNUP = trackIt->fProcTrack.GetTotalWideTrackNUP(); + for (++trackIt; trackIt != fTracks.end(); ++trackIt) { KTDEBUG(evlog, "Track " << trackIt->fProcTrack.GetTrackID()); @@ -271,6 +293,13 @@ namespace Katydid fFirstTrackSlope = trackIt->fProcTrack.GetSlope(); fFirstTrackIntercept = trackIt->fProcTrack.GetIntercept(); fFirstTrackTotalPower = trackIt->fProcTrack.GetTotalPower(); + fFirstTrackNTrackBins = trackIt->fProcTrack.GetNTrackBins(); + fFirstTrackTotalSNR = trackIt->fProcTrack.GetTotalTrackSNR(); + fFirstTrackTotalNUP = trackIt->fProcTrack.GetTotalTrackNUP(); + fFirstTrackMaxSNR = trackIt->fProcTrack.GetMaxTrackSNR(); + fFirstTrackMaxNUP = trackIt->fProcTrack.GetMaxTrackNUP(); + fFirstTrackTotalWideSNR = trackIt->fProcTrack.GetTotalWideTrackSNR(); + fFirstTrackTotalWideNUP = trackIt->fProcTrack.GetTotalWideTrackNUP(); } if (trackIt->fProcTrack.GetEndTimeInRunC() > fEndTimeInRunC) @@ -330,6 +359,13 @@ namespace Katydid fFirstTrackSlope = 0.; fFirstTrackIntercept = 0.; fFirstTrackTotalPower = 0.; + fFirstTrackNTrackBins = 0; + fFirstTrackTotalSNR = 0.; + fFirstTrackTotalNUP = 0.; + fFirstTrackMaxSNR = 0.; + fFirstTrackMaxNUP = 0.; + fFirstTrackTotalWideSNR = 0.; + fFirstTrackTotalWideNUP = 0.; return; } diff --git a/Source/Data/EventAnalysis/KTMultiTrackEventData.hh b/Source/Data/EventAnalysis/KTMultiTrackEventData.hh index b0be724b1..ea777c518 100644 --- a/Source/Data/EventAnalysis/KTMultiTrackEventData.hh +++ b/Source/Data/EventAnalysis/KTMultiTrackEventData.hh @@ -64,6 +64,13 @@ namespace Katydid MEMBERVARIABLE(double, FirstTrackSlope); MEMBERVARIABLE(double, FirstTrackIntercept); MEMBERVARIABLE(double, FirstTrackTotalPower); + MEMBERVARIABLE(int, FirstTrackNTrackBins); + MEMBERVARIABLE(double, FirstTrackTotalSNR); + MEMBERVARIABLE(double, FirstTrackMaxSNR); + MEMBERVARIABLE(double, FirstTrackTotalNUP); + MEMBERVARIABLE(double, FirstTrackMaxNUP); + MEMBERVARIABLE(double, FirstTrackTotalWideSNR); + MEMBERVARIABLE(double, FirstTrackTotalWideNUP); // this member variable is set by event building MEMBERVARIABLE(bool, UnknownEventTopology); // if True, indicates that the reconstruction was unable to deal with the event diff --git a/Source/Data/EventAnalysis/KTProcessedTrackData.cc b/Source/Data/EventAnalysis/KTProcessedTrackData.cc index 65dba7b67..0f53d56e8 100644 --- a/Source/Data/EventAnalysis/KTProcessedTrackData.cc +++ b/Source/Data/EventAnalysis/KTProcessedTrackData.cc @@ -31,6 +31,13 @@ namespace Katydid fSlope(0.), fIntercept(0.), fTotalPower(0.), + fNTrackBins(0.), + fTotalTrackSNR(0.), + fMaxTrackSNR(0.), + fTotalTrackNUP(0.), + fMaxTrackNUP(0.), + fTotalWideTrackSNR(0.), + fTotalWideTrackNUP(0.), fStartTimeInRunCSigma(0.), fEndTimeInRunCSigma(0.), fTimeLengthSigma(0.), @@ -63,6 +70,13 @@ namespace Katydid fSlope(orig.fSlope), fIntercept(orig.fIntercept), fTotalPower(orig.fTotalPower), + fNTrackBins(orig.fNTrackBins), + fTotalTrackSNR(orig.fTotalTrackSNR), + fMaxTrackSNR(orig.fMaxTrackSNR), + fTotalTrackNUP(orig.fTotalTrackNUP), + fMaxTrackNUP(orig.fMaxTrackNUP), + fTotalWideTrackSNR(orig.fTotalWideTrackSNR), + fTotalWideTrackNUP(orig.fTotalWideTrackNUP), fStartTimeInRunCSigma(orig.fStartTimeInRunCSigma), fEndTimeInRunCSigma(orig.fEndTimeInRunCSigma), fTimeLengthSigma(orig.fTimeLengthSigma), @@ -98,6 +112,13 @@ namespace Katydid fSlope = rhs.fSlope; fIntercept = rhs.fIntercept; fTotalPower = rhs.fTotalPower; + fNTrackBins = rhs.fNTrackBins, + fTotalTrackSNR = rhs.fTotalTrackSNR; + fMaxTrackSNR = rhs.fMaxTrackSNR; + fTotalTrackNUP = rhs.fTotalTrackNUP; + fMaxTrackNUP = rhs.fMaxTrackNUP; + fTotalWideTrackSNR = rhs.fTotalWideTrackSNR; + fTotalWideTrackNUP = rhs.fTotalWideTrackNUP; fStartTimeInRunCSigma = rhs.fStartTimeInRunCSigma; fEndTimeInRunCSigma = rhs.fEndTimeInRunCSigma; fTimeLengthSigma = rhs.fTimeLengthSigma; diff --git a/Source/Data/EventAnalysis/KTProcessedTrackData.hh b/Source/Data/EventAnalysis/KTProcessedTrackData.hh index 0e1bbd3ee..7604966c8 100644 --- a/Source/Data/EventAnalysis/KTProcessedTrackData.hh +++ b/Source/Data/EventAnalysis/KTProcessedTrackData.hh @@ -46,6 +46,13 @@ namespace Katydid MEMBERVARIABLE(double, Slope); MEMBERVARIABLE(double, Intercept); MEMBERVARIABLE(double, TotalPower); + MEMBERVARIABLE(unsigned, NTrackBins); + MEMBERVARIABLE(double, TotalTrackSNR); + MEMBERVARIABLE(double, MaxTrackSNR); + MEMBERVARIABLE(double, TotalTrackNUP); + MEMBERVARIABLE(double, MaxTrackNUP); + MEMBERVARIABLE(double, TotalWideTrackSNR); + MEMBERVARIABLE(double, TotalWideTrackNUP); MEMBERVARIABLE(double, StartTimeInRunCSigma); MEMBERVARIABLE(double, EndTimeInRunCSigma); diff --git a/Source/Data/EventAnalysis/KTSparseWaterfallCandidateData.cc b/Source/Data/EventAnalysis/KTSparseWaterfallCandidateData.cc index 2894ca220..d154dd57d 100644 --- a/Source/Data/EventAnalysis/KTSparseWaterfallCandidateData.cc +++ b/Source/Data/EventAnalysis/KTSparseWaterfallCandidateData.cc @@ -24,8 +24,8 @@ namespace Katydid fTimeInAcq(0.), //fFirstSliceNumber(0), //fLastSliceNumber(0), - fMinimumFrequency(0.), - fMaximumFrequency(0.), + fMinFrequency(0.), + fMaxFrequency(0.), //fMeanStartFrequency(0.), //fMeanEndFrequency(0.), fFrequencyWidth(0.) @@ -40,7 +40,7 @@ namespace Katydid { } - void KTSparseWaterfallCandidateData::AddPoint(const Point& point) + void KTSparseWaterfallCandidateData::AddPoint(const KTDiscriminatedPoint& point) { fPoints.insert(point); return; diff --git a/Source/Data/EventAnalysis/KTSparseWaterfallCandidateData.hh b/Source/Data/EventAnalysis/KTSparseWaterfallCandidateData.hh index 3f42b600b..e06a29c8b 100644 --- a/Source/Data/EventAnalysis/KTSparseWaterfallCandidateData.hh +++ b/Source/Data/EventAnalysis/KTSparseWaterfallCandidateData.hh @@ -9,6 +9,7 @@ #define KTSPARSEWATERFALLCANDIDATEDATA_HH_ #include "KTData.hh" +#include "KTDiscriminatedPoint.hh" #include "KTMemberVariable.hh" @@ -18,32 +19,13 @@ namespace Katydid { class KTSparseWaterfallCandidateData : public Nymph::KTExtensibleData< KTSparseWaterfallCandidateData > { - public: - struct Point - { - double fTimeInRunC; - double fFrequency; - double fAmplitude; - double fTimeInAcq; - Point(double tirc, double freq, double amp, double tiacq) : fTimeInRunC(tirc), fFrequency(freq), fAmplitude(amp), fTimeInAcq(tiacq) {} - }; - - struct PointCompare - { - bool operator() (const Point& lhs, const Point& rhs) const - { - return lhs.fTimeInRunC < rhs.fTimeInRunC || (lhs.fTimeInRunC == rhs.fTimeInRunC && lhs.fFrequency < rhs.fFrequency); - } - }; - - typedef std::set< Point, PointCompare > Points; public: KTSparseWaterfallCandidateData(); virtual ~KTSparseWaterfallCandidateData(); - const Points& GetPoints() const; - Points& GetPoints(); + const KTDiscriminatedPoints& GetPoints() const; + KTDiscriminatedPoints& GetPoints(); MEMBERVARIABLE(unsigned, Component); MEMBERVARIABLE(uint64_t, AcquisitionID); @@ -60,8 +42,8 @@ namespace Katydid MEMBERVARIABLE(double, TimeInAcq); //MEMBERVARIABLE(uint64_t, FirstSliceNumber); //MEMBERVARIABLE(uint64_t, LastSliceNumber); - MEMBERVARIABLE(double, MinimumFrequency); - MEMBERVARIABLE(double, MaximumFrequency); + MEMBERVARIABLE(double, MinFrequency); + MEMBERVARIABLE(double, MaxFrequency); //MEMBERVARIABLE(double, MeanStartFrequency); //MEMBERVARIABLE(double, MeanEndFrequency); MEMBERVARIABLE(double, FrequencyWidth); @@ -71,22 +53,22 @@ namespace Katydid //MEMBERVARIABLE(unsigned, EndRecordNumber); //MEMBERVARIABLE(unsigned, EndSampleNumber); - void AddPoint(const Point& point); + void AddPoint(const KTDiscriminatedPoint& point); private: - Points fPoints; + KTDiscriminatedPoints fPoints; public: static const std::string sName; }; - inline const KTSparseWaterfallCandidateData::Points& KTSparseWaterfallCandidateData::GetPoints() const + inline const KTDiscriminatedPoints& KTSparseWaterfallCandidateData::GetPoints() const { return fPoints; } - inline KTSparseWaterfallCandidateData::Points& KTSparseWaterfallCandidateData::GetPoints() + inline KTDiscriminatedPoints& KTSparseWaterfallCandidateData::GetPoints() { return fPoints; } diff --git a/Source/Data/EventAnalysis/KTWaterfallCandidateData.hh b/Source/Data/EventAnalysis/KTWaterfallCandidateData.hh index 30c3de9b1..da0b4a397 100644 --- a/Source/Data/EventAnalysis/KTWaterfallCandidateData.hh +++ b/Source/Data/EventAnalysis/KTWaterfallCandidateData.hh @@ -13,6 +13,7 @@ #include "KTData.hh" #include "KTTimeFrequency.hh" +#include "KTMemberVariable.hh" #include @@ -26,248 +27,30 @@ namespace Katydid KTWaterfallCandidateData(); virtual ~KTWaterfallCandidateData(); - KTTimeFrequency* GetCandidate() const; - unsigned GetComponent() const; - - unsigned GetNTimeBins() const; - double GetTimeBinWidth() const; - - unsigned GetNFreqBins() const; - double GetFreqBinWidth() const; - - double GetTimeInRun() const; - double GetTimeLength() const; - uint64_t GetFirstSliceNumber() const; - uint64_t GetLastSliceNumber() const; - double GetMinimumFrequency() const; - double GetMaximumFrequency() const; - double GetMeanStartFrequency() const; - double GetMeanEndFrequency() const; - double GetFrequencyWidth() const; - - unsigned GetStartRecordNumber() const; - unsigned GetStartSampleNumber() const; - unsigned GetEndRecordNumber() const; - unsigned GetEndSampleNumber() const; - - void SetCandidate(KTTimeFrequency* candidate); - void SetComponent(unsigned component); - - void SetTimeInRun(double tir); - void SetTimeLength(double length); - void SetFirstSliceNumber(uint64_t slice); - void SetLastSliceNumber(uint64_t slice); - void SetMinimumFrequency(double freq); - void SetMaximumFrequency(double freq); - void SetMeanStartFrequency(double freq); - void SetMeanEndFrequency(double freq); - void SetFrequencyWidth(double width); - - void SetStartRecordNumber(unsigned rec); - void SetStartSampleNumber(unsigned sample); - void SetEndRecordNumber(unsigned rec); - void SetEndSampleNumber(unsigned sample); - - private: - KTTimeFrequency* fCandidate; - unsigned fComponent; - - double fTimeInRun; - double fTimeLength; - uint64_t fFirstSliceNumber; - uint64_t fLastSliceNumber; - double fMinFrequency; - double fMaxFrequency; - double fMeanStartFrequency; - double fMeanEndFrequency; - double fFrequencyWidth; - - unsigned fStartRecordNumber; - unsigned fStartSampleNumber; - unsigned fEndRecordNumber; - unsigned fEndSampleNumber; - - public: static const std::string sName; -}; - - inline KTTimeFrequency* KTWaterfallCandidateData::GetCandidate() const - { - return fCandidate; - } - - inline unsigned KTWaterfallCandidateData::GetComponent() const - { - return fComponent; - } - - inline unsigned KTWaterfallCandidateData::GetNTimeBins() const - { - return fCandidate->GetNTimeBins(); - } - - inline unsigned KTWaterfallCandidateData::GetNFreqBins() const - { - return fCandidate->GetNFrequencyBins(); - } - - inline double KTWaterfallCandidateData::GetTimeBinWidth() const - { - return fCandidate->GetTimeBinWidth(); - } - - inline double KTWaterfallCandidateData::GetFreqBinWidth() const - { - return fCandidate->GetFrequencyBinWidth(); - } - - inline double KTWaterfallCandidateData::GetTimeInRun() const - { - return fTimeInRun; - } - - inline double KTWaterfallCandidateData::GetTimeLength() const - { - return fTimeLength; - } - - inline uint64_t KTWaterfallCandidateData::GetFirstSliceNumber() const - { - return fFirstSliceNumber; - } - - inline uint64_t KTWaterfallCandidateData::GetLastSliceNumber() const - { - return fLastSliceNumber; - } - - inline double KTWaterfallCandidateData::GetMinimumFrequency() const - { - return fMinFrequency; - } - - inline double KTWaterfallCandidateData::GetMaximumFrequency() const - { - return fMaxFrequency; - } - inline double KTWaterfallCandidateData::GetMeanStartFrequency() const - { - return fMeanStartFrequency; - } - - inline double KTWaterfallCandidateData::GetMeanEndFrequency() const - { - return fMeanEndFrequency; - } - - inline double KTWaterfallCandidateData::GetFrequencyWidth() const - { - return fFrequencyWidth; - } + MEMBERVARIABLE_NOSET(KTTimeFrequency*, Candidate); + MEMBERVARIABLE(unsigned, Component); - inline unsigned KTWaterfallCandidateData::GetStartRecordNumber() const - { - return fStartRecordNumber; - } + MEMBERVARIABLE(double, TimeInRun); + MEMBERVARIABLE(double, TimeLength); + MEMBERVARIABLE(uint64_t, FirstSliceNumber); + MEMBERVARIABLE(uint64_t, LastSliceNumber); + MEMBERVARIABLE(double, MinFrequency); + MEMBERVARIABLE(double, MaxFrequency); + MEMBERVARIABLE(double, MeanStartFrequency); + MEMBERVARIABLE(double, MeanEndFrequency); + MEMBERVARIABLE(double, FrequencyWidth); - inline unsigned KTWaterfallCandidateData::GetStartSampleNumber() const - { - return fStartSampleNumber; - } + MEMBERVARIABLE(unsigned, StartRecordNumber); + MEMBERVARIABLE(unsigned, StartSampleNumber); + MEMBERVARIABLE(unsigned, EndRecordNumber); + MEMBERVARIABLE(unsigned, EndSampleNumber); - inline unsigned KTWaterfallCandidateData::GetEndRecordNumber() const - { - return fEndRecordNumber; - } - - inline unsigned KTWaterfallCandidateData::GetEndSampleNumber() const - { - return fEndSampleNumber; - } + public: + void SetCandidate(KTTimeFrequency* candidate); - inline void KTWaterfallCandidateData::SetComponent(unsigned component) - { - fComponent = component; - return; - } - - inline void KTWaterfallCandidateData::SetTimeInRun(double tir) - { - fTimeInRun = tir; - return; - } - - inline void KTWaterfallCandidateData::SetTimeLength(double length) - { - fTimeLength = length; - return; - } - - inline void KTWaterfallCandidateData::SetFirstSliceNumber(uint64_t slice) - { - fFirstSliceNumber = slice; - return; - } - - inline void KTWaterfallCandidateData::SetLastSliceNumber(uint64_t slice) - { - fLastSliceNumber = slice; - return; - } - - inline void KTWaterfallCandidateData::SetMinimumFrequency(double freq) - { - fMinFrequency = freq; - return; - } - - inline void KTWaterfallCandidateData::SetMaximumFrequency(double freq) - { - fMaxFrequency = freq; - return; - } - - inline void KTWaterfallCandidateData::SetMeanStartFrequency(double freq) - { - fMeanStartFrequency = freq; - return; - } - - inline void KTWaterfallCandidateData::SetMeanEndFrequency(double freq) - { - fMeanEndFrequency = freq; - return; - } - - inline void KTWaterfallCandidateData::SetFrequencyWidth(double width) - { - fFrequencyWidth = width; - return; - } - - inline void KTWaterfallCandidateData::SetStartRecordNumber(unsigned rec) - { - fStartRecordNumber = rec; - return; - } - - inline void KTWaterfallCandidateData::SetStartSampleNumber(unsigned sample) - { - fStartSampleNumber = sample; - return; - } - - inline void KTWaterfallCandidateData::SetEndRecordNumber(unsigned rec) - { - fEndRecordNumber = rec; - return; - } +}; - inline void KTWaterfallCandidateData::SetEndSampleNumber(unsigned sample) - { - fEndSampleNumber = sample; - return; - } } /* namespace Katydid */ #endif /* KTWATERFALLCANDIDATEDATA_HH_ */ diff --git a/Source/Data/SpectrumAnalysis/KTDiscriminatedPoint.hh b/Source/Data/SpectrumAnalysis/KTDiscriminatedPoint.hh new file mode 100644 index 000000000..5f34898b3 --- /dev/null +++ b/Source/Data/SpectrumAnalysis/KTDiscriminatedPoint.hh @@ -0,0 +1,41 @@ +/** + @file KTDiscriminatedPoint.hh + @brief Defines the point structure + @details Defines the basic point structure used for any discriminated point: used in KTSparseWaterfallCandidateData, KTTrackProcessing + @author: M. Guigue + @date: May 31, 2018 + */ + +#ifndef KTDISCRIMINATEDPOINT_HH_ +#define KTDISCRIMINATEDPOINT_HH_ + +#include + +namespace Katydid +{ + struct KTDiscriminatedPoint + { + double fTimeInRunC; + double fFrequency; + double fAmplitude; + double fTimeInAcq; + double fMean; + double fVariance; + double fNeighborhoodAmplitude; + // The SequentialTrackFinder Processor uses BinInSlice when it sums over adjacent bins in the power spectrum slice + // Once that slow is deleted we no longer need this variable + unsigned fBinInSlice; + KTDiscriminatedPoint(double tirc, double freq, double amp, double tiacq, double mean, double variance, double neighborhoodAmplitude) : fTimeInRunC(tirc), fFrequency(freq), fAmplitude(amp), fTimeInAcq(tiacq), fMean(mean), fVariance(variance), fNeighborhoodAmplitude(neighborhoodAmplitude) {} + + }; + struct KTDiscriminatedPointCompare + { + bool operator() (const KTDiscriminatedPoint& lhs, const KTDiscriminatedPoint& rhs) const + { + return lhs.fTimeInRunC < rhs.fTimeInRunC || (lhs.fTimeInRunC == rhs.fTimeInRunC && lhs.fFrequency < rhs.fFrequency); + } + }; + + typedef std::set< KTDiscriminatedPoint, KTDiscriminatedPointCompare > KTDiscriminatedPoints; +} +#endif diff --git a/Source/Data/SpectrumAnalysis/KTDiscriminatedPoints1DData.hh b/Source/Data/SpectrumAnalysis/KTDiscriminatedPoints1DData.hh index 0818e4e99..877ca927c 100644 --- a/Source/Data/SpectrumAnalysis/KTDiscriminatedPoints1DData.hh +++ b/Source/Data/SpectrumAnalysis/KTDiscriminatedPoints1DData.hh @@ -10,6 +10,8 @@ #include "KTData.hh" +#include "KTMemberVariable.hh" + #include #include #include @@ -26,7 +28,10 @@ namespace Katydid double fAbscissa; double fOrdinate; double fThreshold; - Point(double abscissa, double ordinate, double threshold) : fAbscissa(abscissa), fOrdinate(ordinate), fThreshold(threshold) {} + double fMean; + double fVariance; + double fNeighborhoodAmplitude; + Point(double abscissa, double ordinate, double threshold, double mean, double variance, double neighborhoodAmplitude) : fAbscissa(abscissa), fOrdinate(ordinate), fThreshold(threshold), fMean(mean), fVariance(variance), fNeighborhoodAmplitude(neighborhoodAmplitude) {} }; typedef std::map< unsigned, Point > SetOfPoints; @@ -48,17 +53,11 @@ namespace Katydid KTDiscriminatedPoints1DData& SetNComponents(unsigned channels); - unsigned GetNBins() const; - double GetBinWidth() const; - - void SetNBins(unsigned nBins); - void SetBinWidth(double binWidth); - private: std::vector< PerComponentData > fComponentData; - unsigned fNBins; - double fBinWidth; + MEMBERVARIABLE(unsigned, NBins); + MEMBERVARIABLE(double, BinWidth); public: static const std::string sName; @@ -86,27 +85,6 @@ namespace Katydid return *this; } - inline unsigned KTDiscriminatedPoints1DData::GetNBins() const - { - return fNBins; - } - - inline double KTDiscriminatedPoints1DData::GetBinWidth() const - { - return fBinWidth; - } - - inline void KTDiscriminatedPoints1DData::SetNBins(unsigned nBins) - { - fNBins = nBins; - return; - } - - inline void KTDiscriminatedPoints1DData::SetBinWidth(double binWidth) - { - fBinWidth = binWidth; - return; - } } /* namespace Katydid */ diff --git a/Source/Data/SpectrumAnalysis/KTDiscriminatedPoints2DData.hh b/Source/Data/SpectrumAnalysis/KTDiscriminatedPoints2DData.hh index c0b805ba1..e7538b489 100644 --- a/Source/Data/SpectrumAnalysis/KTDiscriminatedPoints2DData.hh +++ b/Source/Data/SpectrumAnalysis/KTDiscriminatedPoints2DData.hh @@ -34,7 +34,10 @@ namespace Katydid double fOrdinate; double fApplicate; double fThreshold; - Point(double abscissa, double ordinate, double applicate, double threshold) : fAbscissa(abscissa), fOrdinate(ordinate), fApplicate(applicate), fThreshold(threshold) {} + double fMean; + double fVariance; + double fNeighborhoodAmplitude; + Point(double abscissa, double ordinate, double applicate, double threshold, double mean, double variance, double neighborhoodAmplitude) : fAbscissa(abscissa), fOrdinate(ordinate), fApplicate(applicate), fThreshold(threshold), fMean(mean), fVariance(variance), fNeighborhoodAmplitude(neighborhoodAmplitude) {} }; typedef std::map< std::pair< unsigned, unsigned >, Point > SetOfPoints; @@ -57,23 +60,13 @@ namespace Katydid KTDiscriminatedPoints2DData& SetNComponents(unsigned channels); - unsigned GetNBinsX() const; - unsigned GetNBinsY() const; - double GetBinWidthX() const; - double GetBinWidthY() const; - - void SetNBinsX(unsigned nBins); - void SetNBinsY(unsigned nBins); - void SetBinWidthX(double binWidth); - void SetBinWidthY(double binWidth); - private: std::vector< PerComponentData > fComponentData; - unsigned fNBinsX; - unsigned fNBinsY; - double fBinWidthX; - double fBinWidthY; + MEMBERVARIABLE(unsigned, NBinsX); + MEMBERVARIABLE(unsigned, NBinsY); + MEMBERVARIABLE(double, BinWidthX); + MEMBERVARIABLE(double, BinWidthY); public: static const std::string sName; @@ -106,50 +99,6 @@ namespace Katydid return *this; } - inline unsigned KTDiscriminatedPoints2DData::GetNBinsX() const - { - return fNBinsX; - } - - inline unsigned KTDiscriminatedPoints2DData::GetNBinsY() const - { - return fNBinsY; - } - - inline double KTDiscriminatedPoints2DData::GetBinWidthX() const - { - return fBinWidthX; - } - - inline double KTDiscriminatedPoints2DData::GetBinWidthY() const - { - return fBinWidthY; - } - - inline void KTDiscriminatedPoints2DData::SetNBinsX(unsigned nBins) - { - fNBinsX = nBins; - return; - } - - inline void KTDiscriminatedPoints2DData::SetNBinsY(unsigned nBins) - { - fNBinsY = nBins; - return; - } - - inline void KTDiscriminatedPoints2DData::SetBinWidthX(double binWidth) - { - fBinWidthX = binWidth; - return; - } - - inline void KTDiscriminatedPoints2DData::SetBinWidthY(double binWidth) - { - fBinWidthY = binWidth; - return; - } - } /* namespace Katydid */ #endif /* KTDISCRIMINATEDPOINTS2DDATA_HH_ */ diff --git a/Source/Data/SpectrumAnalysis/KTKDTreeData.hh b/Source/Data/SpectrumAnalysis/KTKDTreeData.hh index 72e09628b..5e4197c26 100644 --- a/Source/Data/SpectrumAnalysis/KTKDTreeData.hh +++ b/Source/Data/SpectrumAnalysis/KTKDTreeData.hh @@ -39,6 +39,9 @@ namespace Katydid double fTimeInAcq; bool fNoiseFlag; uint64_t fSliceNumber; + double fMean; + double fVariance; + double fNeighborhoodAmplitude; //uint64_t fAcquisitionID; }; diff --git a/Source/Data/SpectrumAnalysis/KTSeqLine.cc b/Source/Data/SpectrumAnalysis/KTSeqLine.cc deleted file mode 100644 index 836a74265..000000000 --- a/Source/Data/SpectrumAnalysis/KTSeqLine.cc +++ /dev/null @@ -1,202 +0,0 @@ -/* - * KTScoredSpectrum.cc - * - * Created on: Mar 10, 2016 - * Author: Christine - */ - -#include - -#include "KTLogger.hh" - -#include -#include -#include - -namespace Katydid -{ - KTLOGGER(seqlog, "KTSeqLine"); - - - - LineRef::LineRef(const double& initialSlope): - fStartTimeInRunC(0.0), - fStartTimeInAcq(0.0), - fEndTimeInRunC(0.0), - fEndTimeInAcq(0.0), - fStartFrequency(0.0), - fEndFrequency(0.0), - fLineWidth(0.0), - fInitialSlope(initialSlope), - fSlope(0.0), - fNPoints(0), - fComponent(0), - fAmplitudeSum(0.0), - fAcquisitionID(0), - fProcTrackMinPoints(0), - fProcTrackAssError(0.), - fIntercept(0.), - fSlopeSigma(0.), - fInterceptSigma(0.), - fStartFrequencySigma(0.), - fEndFrequencySigma(0.), - fSumX(0.), - fSumY(0.), - fSumXY(0.), - fSumXX(0.) - { - /* - if (slopeMethod == slope_method::weighted_first_point_ref) - { - f_calc_slope_func = &LineRef::CalculateSlope(); - } - if (slopeMethod == slope_method::weighted) - { - f_calc_slope_func = &LineRef::CalculateNewSlope(); - } - if (slopeMethod == slope_method::unweighted) - { - f_calc_slope_func = &LineRef::CalculateUnweightedSlope(); - }*/ - } - - LineRef::~LineRef() - {} - - void LineRef::InsertPoint(const Point& point) - { - - fTrimmingLimits.push_back(point.fThreshold); //new_trimming_limits); - fAmplitudeList.push_back(point.fAmplitude); - - fLinePoints.emplace_back(point.fBinInSlice, point.fPointFreq, point.fTimeInAcq, point.fTimeInRunC, point.fAmplitude, point.fThreshold, point.fAcquisitionID, point.fComponent); - //KTINFO(seqlog, "Adding point line "<UpdateLineProperties(); - //this->*f_calc_slope_func(); - } - - - /*inline void LineRef::CalculateUnweightedSlope() - { - fSumX = 0.0; - fSumY = 0.0; - fSumXY = 0.0; - fSumXX = 0.0; - - //KTDEBUG(seqlog, "Calculating line slope"); - double weightedSlope = 0.0; - double weight = 0.0; - double wSum = 0.0; - fNPoints = fLinePoints.size(); - - if (fNPoints > 1) - { - for(std::vector::iterator pointIt = fLinePoints.begin(); pointIt != fLinePoints.end(); ++pointIt) - { - weight = pointIt->fAmplitude/fAmplitudeSum*fNPoints; - - fSumX += fLinePoints.back().fTimeInRunC * weight; - fSumY += fLinePoints.back().fPointFreq * weight; - fSumXY += fLinePoints.back().fTimeInRunC * fLinePoints.back().fPointFreq * weight; - fSumXX += fLinePoints.back().fTimeInRunC * fLinePoints.back().fTimeInRunC *weight; - } - fSlope = (fNPoints * fSumXY - fSumX * fSumY)/(fSumXX * fNPoints - fSumX * fSumX); - KTDEBUG( seqlog, "New slope "< 1) - { - for(std::vector::iterator pointIt = fLinePoints.begin(); pointIt != fLinePoints.end(); ++pointIt) - { - if (pointIt->fPointFreq > fStartFrequency) - { - weightedSlope += (pointIt->fPointFreq - fStartFrequency)/(pointIt->fTimeInAcq - fStartTimeInAcq) * pointIt->fAmplitude; - wSum += pointIt->fAmplitude; - } - } - fSlope = weightedSlope/wSum; - } - - if (fNPoints <= 1) - { - fSlope = fInitialSlope; - } - }*/ - - void LineRef::LineTrimming(const double& trimmingFactor, const unsigned& minPoints) - { - KTDEBUG(seqlog, "Trimming line edges. Trimming factor is "<= minPoints) - { - KTDEBUG(seqlog, "Amplitude is "<= minPoints) - { - fAmplitudeList.erase(fAmplitudeList.begin()); - fTrimmingLimits.erase(fTrimmingLimits.begin()); - fLinePoints.erase(fLinePoints.begin()); - fNPoints = fLinePoints.size(); - } - } - fAcquisitionID = fLinePoints.front().fAcquisitionID; - fComponent = fLinePoints.front().fComponent; - fStartTimeInRunC = fLinePoints.front().fTimeInRunC; - fStartFrequency = fLinePoints.front().fPointFreq; - fStartTimeInAcq = fLinePoints.front().fTimeInAcq; - - for(std::vector::iterator pointIt = fLinePoints.begin(); pointIt != fLinePoints.end(); ++pointIt) - { - fAmplitudeSum += pointIt->fAmplitude; - } - - this->UpdateLineProperties(); - //this->CalculateSlope(); - } - - - inline void LineRef::UpdateLineProperties() - { - //KTDEBUG(seqlog, "Updating line parameters"); - fNPoints = fLinePoints.size(); - if (fNPoints == 1) - { - fAcquisitionID = fLinePoints.front().fAcquisitionID; - fComponent = fLinePoints.front().fComponent; - fStartTimeInRunC = fLinePoints.front().fTimeInRunC; - fStartFrequency = fLinePoints.front().fPointFreq; - fStartTimeInAcq = fLinePoints.front().fTimeInAcq; - } - fEndTimeInRunC = fLinePoints.back().fTimeInRunC; - fEndTimeInAcq = fLinePoints.back().fTimeInAcq; - fEndFrequency = fLinePoints.back().fPointFreq; - //fAmplitudeSum += fLinePoints.back().fAmplitude; - } -} /* namespace Katydid */ - diff --git a/Source/Data/SpectrumAnalysis/KTSeqLine.hh b/Source/Data/SpectrumAnalysis/KTSeqLine.hh deleted file mode 100644 index 278275211..000000000 --- a/Source/Data/SpectrumAnalysis/KTSeqLine.hh +++ /dev/null @@ -1,138 +0,0 @@ -/* - * KTSeqLine.hh - * - * Created on: Sep 8, 2016 - * Author: Christine - */ - -#ifndef KTSEQLINE_HH_ -#define KTSEQLINE_HH_ - -#include "KTMemberVariable.hh" -//#include "KTSeqTrackCreator.hh" - - -#include -#include - -namespace Katydid { - - // this is a point from a power spectrum slice - // sorting it will sort it by power - struct Point - { - double fBinInSlice; - double fPointFreq; - double fTimeInAcq; - double fTimeInRunC; - double fAmplitude; - double fThreshold; - uint64_t fAcquisitionID; - double fComponent; - - Point(unsigned binInSclice, double pointFreq, double timeInAcq, double timeInRunC, double amplitude, double threshold, uint64_t acqID, unsigned iComponent) : fBinInSlice(binInSclice), fPointFreq(pointFreq), - fTimeInAcq(timeInAcq), fTimeInRunC(timeInRunC), fAmplitude(amplitude), fThreshold(threshold), fAcquisitionID(acqID), fComponent(iComponent) {} - - void Clear(); - bool operator > (const Point& str) const - { - return (fAmplitude > str.fAmplitude); - } - bool operator < (const Point& str) const - { - return (fAmplitude < str.fAmplitude); - } - }; - - // this is a line point. Its amplitude is the sum of all bins in the power slice of its frequency +/- the line width - // sort by time - struct LinePoint - { - double fBinInSlice; - double fPointFreq; - double fTimeInAcq; - double fTimeInRunC; - double fAmplitude; - double fThreshold; - uint64_t fAcquisitionID; - double fComponent; - - LinePoint(unsigned binInSclice, double pointFreq, double timeInAcq, double timeInRunC, double amplitude, double threshold, uint64_t acqID, unsigned iComponent) : fBinInSlice(binInSclice), fPointFreq(pointFreq), - fTimeInAcq(timeInAcq), fTimeInRunC(timeInRunC), fAmplitude(amplitude), fThreshold(threshold), fAcquisitionID(acqID), fComponent(iComponent) {} - void Clear(); - - bool operator > (const Point& str) const - { - return (fTimeInRunC > str.fTimeInRunC); - } - bool operator < (const Point& str) const - { - return (fTimeInRunC < str.fTimeInRunC); - } - }; - - - struct LineRef - { - /*enum class slope_method - { - weighted_first_point_ref, - weighted, - unweighted - };*/ - - std::vector fTrimmingLimits; - std::vector fLinePoints; - std::vector fAmplitudeList; - - double fStartTimeInRunC; - double fEndTimeInRunC; - double fStartTimeInAcq; - double fEndTimeInAcq; - double fStartFrequency; - double fEndFrequency; - unsigned fLineWidth; - double fInitialSlope; - double fSlope; - unsigned fComponent; - double fAmplitudeSum; - unsigned fNPoints; - uint64_t fAcquisitionID; - unsigned fProcTrackMinPoints; - double fProcTrackAssError; - double fIntercept; - double fSlopeSigma; - double fInterceptSigma; - double fStartFrequencySigma; - double fEndFrequencySigma; - - double fSumX; - double fSumY; - double fSumXY; - double fSumXX; - - - LineRef(const double& initialSlope); - void InsertPoint(const Point& point); - void LineTrimming(const double& trimminFactor, const unsigned& minPoints); - //void (LineRef::*f_calc_slope_func)(); - //void CalculateSlope(); - //void CalculateNewSlope(); - void UpdateLineProperties(); - void FinishTrack(); - void Clear(); - virtual ~LineRef(); - - bool operator < (const LineRef& str) const - { - return (fStartTimeInRunC < str.fStartTimeInRunC); - } - }; - - - -} /* namespace Katydid */ - -#endif /* SOURCE_DATA_SPECTRUM_ANALYSIS_KTSEQLINE_HH_ */ - - diff --git a/Source/Data/SpectrumAnalysis/KTSequentialLineData.cc b/Source/Data/SpectrumAnalysis/KTSequentialLineData.cc new file mode 100644 index 000000000..33a3310c9 --- /dev/null +++ b/Source/Data/SpectrumAnalysis/KTSequentialLineData.cc @@ -0,0 +1,146 @@ +/** + @file KTSequentialLineData.cc + @brief Contains KTSequentialLineData + @details KTDiscriminatedPoint cluster with some track properties + @author: C. Claessens + @date: May 31, 2018 + */ +#include + +#include "KTLogger.hh" + +#include +#include +#include + +namespace Katydid +{ + const std::string KTSequentialLineData::sName("sequential-line"); + KTLOGGER(seqlog, "KTSeqLine"); + + KTSequentialLineData::KTSequentialLineData(): + fLinePoints(), + fSNRList(), + fStartTimeInRunC(0.0), + fStartTimeInAcq(0.0), + fEndTimeInRunC(0.0), + fEndTimeInAcq(0.0), + fStartFrequency(0.0), + fEndFrequency(0.0), + fWeightedSlopeSum(0.0), + fSlope(0.0), + fNPoints(0), + fComponent(0), + fAcquisitionID(0), + fCandidateID(0), + fTotalPower(0.0), + fTotalSNR(0.0), + fTotalNUP(0.0), + fTotalWidePower(0.0), + fTotalWideSNR(0.0), + fTotalWideNUP(0.0), + fSumX(0.), + fSumY(0.), + fSumXY(0.), + fSumXX(0.) + {} + + KTSequentialLineData::~KTSequentialLineData() + {} + + void KTSequentialLineData::AddPoint( const KTDiscriminatedPoint& point ) + { + fSNRList.push_back(point.fNeighborhoodAmplitude/point.fMean); + fTotalWideSNR += point.fNeighborhoodAmplitude/point.fMean; + fLinePoints.insert(point); + //KTINFO(seqlog, "Adding point line "<UpdateLineProperties(); + } + + void KTSequentialLineData::LineSNRTrimming( const double& trimmingThreshold, const unsigned& minPoints ) + { + //KTDEBUG( seqlog, "Trimming line edges. Trimming SNR threshold is "<= minPoints ) + { + KTDEBUG( seqlog, "SNR is "<= minPoints ) + { + KTDEBUG( seqlog, "SNR is "<fTimeInRunC); + SetStartFrequency( fLinePoints.begin()->fFrequency); + SetStartTimeInAcq( fLinePoints.begin()->fTimeInAcq); + + SetEndTimeInRunC( fLinePoints.rbegin()->fTimeInRunC); + SetEndTimeInAcq( fLinePoints.rbegin()->fTimeInAcq); + SetEndFrequency( fLinePoints.rbegin()->fFrequency); + } + + + void KTSequentialLineData::UpdateLineProperties() + { + //KTDEBUG(seqlog, "Updating line parameters"); + SetNPoints( fLinePoints.size() ); + if ( fNPoints == 1 or fLinePoints.begin()->fTimeInRunC < GetStartTimeInRunC()) + { + SetStartTimeInRunC( fLinePoints.begin()->fTimeInRunC ); + SetStartFrequency( fLinePoints.begin()->fFrequency ); + SetStartTimeInAcq( fLinePoints.begin()->fTimeInAcq ); + } + // This shouldn't actually be possible because fLinePoints are of tape KTDiscriminatedPoints + if (fLinePoints.rbegin()->fTimeInRunC < GetStartTimeInRunC() ) + { + SetStartTimeInRunC( fLinePoints.rbegin()->fTimeInRunC ); + SetStartFrequency( fLinePoints.rbegin()->fFrequency ); + SetStartTimeInAcq( fLinePoints.rbegin()->fTimeInAcq ); + } + if ( fLinePoints.rbegin()->fTimeInRunC > GetEndTimeInRunC() ) + { + SetEndTimeInRunC( fLinePoints.rbegin()->fTimeInRunC); + SetEndTimeInAcq( fLinePoints.rbegin()->fTimeInAcq); + SetEndFrequency( fLinePoints.rbegin()->fFrequency); + } + } + void KTSequentialLineData::CalculateTotalPower() + { + fTotalPower = 0.; + fTotalWidePower = 0.; + for(KTDiscriminatedPoints::iterator pointIt = fLinePoints.begin(); pointIt != fLinePoints.end(); ++pointIt) + { + fTotalPower += pointIt->fAmplitude; + fTotalWidePower += pointIt->fNeighborhoodAmplitude; + } + } + void KTSequentialLineData::CalculateTotalSNR() + { + fTotalSNR = 0.; + fTotalWideSNR = 0.; + for(KTDiscriminatedPoints::iterator pointIt = fLinePoints.begin(); pointIt != fLinePoints.end(); ++pointIt) + { + fTotalSNR += pointIt->fAmplitude/pointIt->fMean; + fTotalWideSNR += pointIt->fNeighborhoodAmplitude/pointIt->fMean; + } + } + void KTSequentialLineData::CalculateTotalNUP() + { + fTotalNUP = 0.; + fTotalWideNUP = 0.; + for(KTDiscriminatedPoints::iterator pointIt = fLinePoints.begin(); pointIt != fLinePoints.end(); ++pointIt) + { + fTotalNUP += ( pointIt->fAmplitude - pointIt->fMean ) / sqrt( pointIt->fVariance ); + fTotalWideNUP += ( pointIt->fNeighborhoodAmplitude - pointIt->fMean ) / sqrt( pointIt->fVariance ); + } + } +} /* namespace Katydid */ + diff --git a/Source/Data/SpectrumAnalysis/KTSequentialLineData.hh b/Source/Data/SpectrumAnalysis/KTSequentialLineData.hh new file mode 100644 index 000000000..80d88fdc4 --- /dev/null +++ b/Source/Data/SpectrumAnalysis/KTSequentialLineData.hh @@ -0,0 +1,94 @@ +/** + @file KTSequentialLineData.hh + @brief Contains KTSequentialLineData + @details KTDiscriminatedPoint cluster with some track properties + @author: C. Claessens + @date: May 31, 2018 + */ + +#ifndef KTSEQUENTIALLINEDATA_HH_ +#define KTSEQUENTIALLINEDATA_HH_ + +#include "KTMemberVariable.hh" +#include "KTData.hh" +#include "KTDiscriminatedPoint.hh" + +#include +#include +#include + +namespace Katydid +{ + class KTSequentialLineData : public Nymph::KTExtensibleData< KTSequentialLineData > + { + + private: + + MEMBERVARIABLE(KTDiscriminatedPoints, LinePoints); + MEMBERVARIABLE(std::vector, SNRList); + + MEMBERVARIABLE(double, StartTimeInRunC); + MEMBERVARIABLE(double, EndTimeInRunC); + MEMBERVARIABLE(double, StartTimeInAcq); + MEMBERVARIABLE(double, EndTimeInAcq); + MEMBERVARIABLE(double, StartFrequency); + MEMBERVARIABLE(double, EndFrequency); + MEMBERVARIABLE(double, Slope); + MEMBERVARIABLE(double, WeightedSlopeSum); + MEMBERVARIABLE(unsigned, Component); + MEMBERVARIABLE(uint64_t, AcquisitionID); + MEMBERVARIABLE(unsigned, CandidateID) + MEMBERVARIABLE(double, TotalPower); + MEMBERVARIABLE(double, TotalSNR); + MEMBERVARIABLE(double, TotalNUP); + MEMBERVARIABLE(double, TotalWidePower); + MEMBERVARIABLE(double, TotalWideSNR); + MEMBERVARIABLE(double, TotalWideNUP); + MEMBERVARIABLE(unsigned, NPoints); + MEMBERVARIABLE(double, SumX); + MEMBERVARIABLE(double, SumY); + MEMBERVARIABLE(double, SumXY); + MEMBERVARIABLE(double, SumXX); + + + + public: + + static const std::string sName; + + + KTSequentialLineData(); + virtual ~KTSequentialLineData(); + + const KTDiscriminatedPoints& GetPoints() const; + KTDiscriminatedPoints& GetPoints(); + //LineRef(const double& initialSlope); + void AddPoint(const KTDiscriminatedPoint& point); + void LineSNRTrimming(const double& trimmingThreshold, const unsigned& minPoints); + void UpdateLineProperties(); + void CalculateTotalPower(); + void CalculateTotalSNR(); + void CalculateTotalNUP(); + + bool operator() (const KTSequentialLineData& lhs, const KTSequentialLineData& rhs) const + { + return lhs.GetStartTimeInRunC() < rhs.GetStartTimeInRunC() || (lhs.GetStartTimeInRunC() == rhs.GetStartTimeInRunC() && lhs.GetStartFrequency() < rhs.fStartFrequency); + } + + }; + + inline const KTDiscriminatedPoints& KTSequentialLineData::GetPoints() const + { + return fLinePoints; + } + + inline KTDiscriminatedPoints& KTSequentialLineData::GetPoints() + { + return fLinePoints; + } + +} /* namespace Katydid */ + +#endif /* KTSEQUENTIALLINEDATA_HH_ */ + + diff --git a/Source/EventAnalysis/CMakeLists.txt b/Source/EventAnalysis/CMakeLists.txt index 8cb7b85d6..6c99d94cb 100644 --- a/Source/EventAnalysis/CMakeLists.txt +++ b/Source/EventAnalysis/CMakeLists.txt @@ -11,7 +11,9 @@ set (EVENTANALYSIS_HEADERFILES KTDistanceMatrix.hh KTDBScanEventClustering.hh KTDBScanTrackClustering.hh + KTEventFirstTrackNUPCut.hh KTEventFirstTrackPowerCut.hh + KTEventFirstTrackSNRCut.hh KTEventTimeCut.hh KTFrequencyCandidateIdentifier.hh KTIterativeTrackClustering.hh @@ -27,11 +29,14 @@ set (EVENTANALYSIS_HEADERFILES KTProcessedTrackCut.hh KTQuadraticPhaseShift.hh KTRPClassifier.hh + KTSequentialLineNUPCut.hh + KTSequentialLineSNRCut.hh KTSidebandCorrection.hh KTSpectrogramCollector.hh KTTrackMainbandCut.hh KTTrackMVACut.hh - KTTrackProcessing.hh + KTTrackProcessingDoubleCuts.hh + KTTrackProcessingWeightedSlope.hh KTTrackFreqCut.hh KTTrackTimeCut.hh ) @@ -41,7 +46,9 @@ set (EVENTANALYSIS_SOURCEFILES KTDataCutter.cc KTDBScanEventClustering.cc KTDBScanTrackClustering.cc + KTEventFirstTrackNUPCut.cc KTEventFirstTrackPowerCut.cc + KTEventFirstTrackSNRCut.cc KTEventTimeCut.cc KTFrequencyCandidateIdentifier.cc KTIterativeTrackClustering.cc @@ -57,11 +64,14 @@ set (EVENTANALYSIS_SOURCEFILES KTProcessedTrackCut.cc KTRPClassifier.cc KTQuadraticPhaseShift.cc + KTSequentialLineNUPCut.cc + KTSequentialLineSNRCut.cc KTSidebandCorrection.cc KTSpectrogramCollector.cc KTTrackMainbandCut.cc KTTrackMVACut.cc - KTTrackProcessing.cc + KTTrackProcessingDoubleCuts.cc + KTTrackProcessingWeightedSlope.cc KTTrackFreqCut.cc KTTrackTimeCut.cc ) diff --git a/Source/EventAnalysis/KTDBScanTrackClustering.cc b/Source/EventAnalysis/KTDBScanTrackClustering.cc index c25625764..992ece2dd 100644 --- a/Source/EventAnalysis/KTDBScanTrackClustering.cc +++ b/Source/EventAnalysis/KTDBScanTrackClustering.cc @@ -14,6 +14,7 @@ #include "KTSliceHeader.hh" #include "KTSparseWaterfallCandidateData.hh" #include "KTTimeFrequencyPolar.hh" +#include "KTDiscriminatedPoint.hh" using std::set; using std::vector; @@ -202,7 +203,10 @@ namespace Katydid double minTime = time; double minTimeInAcq = timeInAcq; double maxTime = minTime; - cand.AddPoint(KTSparseWaterfallCandidateData::Point(time, freq, points[*pointIdIt].fAmplitude, timeInAcq)); + double mean = points[*pointIdIt].fMean; + double variance = points[*pointIdIt].fVariance; + double neighborhoodAmplitude = points[*pointIdIt].fNeighborhoodAmplitude; + cand.AddPoint(KTDiscriminatedPoint(time, freq, points[*pointIdIt].fAmplitude, timeInAcq, mean, variance, neighborhoodAmplitude)); KTDEBUG(tclog, "Added point #" << *pointIdIt << ": " << time << ", " << freq) for (++pointIdIt; pointIdIt != clustIt->end(); ++pointIdIt) @@ -210,7 +214,10 @@ namespace Katydid time = points[*pointIdIt].fCoords[0] * data.GetXScaling(); freq = points[*pointIdIt].fCoords[1] * data.GetYScaling(); timeInAcq = points[*pointIdIt].fTimeInAcq * data.GetXScaling();; - cand.AddPoint(KTSparseWaterfallCandidateData::Point(time, freq, points[*pointIdIt].fAmplitude, timeInAcq)); + mean = points[*pointIdIt].fMean; + variance = points[*pointIdIt].fVariance; + neighborhoodAmplitude = points[*pointIdIt].fNeighborhoodAmplitude; + cand.AddPoint(KTDiscriminatedPoint(time, freq, points[*pointIdIt].fAmplitude, timeInAcq, mean, variance, neighborhoodAmplitude)); KTDEBUG(tclog, "Added point #" << *pointIdIt << ": " << time << ", " << freq << ", " << points[*pointIdIt].fAmplitude) if (time > maxTime) @@ -245,8 +252,8 @@ namespace Katydid cand.SetTimeInAcq(minTimeInAcq); cand.SetTimeLength(maxTime - minTime); - cand.SetMinimumFrequency(minFreq); - cand.SetMaximumFrequency(maxFreq); + cand.SetMinFrequency(minFreq); + cand.SetMaxFrequency(maxFreq); cand.SetFrequencyWidth(maxFreq - minFreq); diff --git a/Source/EventAnalysis/KTDBScanTrackClustering.hh b/Source/EventAnalysis/KTDBScanTrackClustering.hh index 50cd2960f..e22008ae5 100644 --- a/Source/EventAnalysis/KTDBScanTrackClustering.hh +++ b/Source/EventAnalysis/KTDBScanTrackClustering.hh @@ -72,6 +72,7 @@ namespace Katydid MEMBERVARIABLE(unsigned, MinPoints); MEMBERVARIABLE(double, Radius); + MEMBERVARIABLE_NOSET(unsigned, DataCount); //MEMBERVARIABLEREF(Point, Radii); public: @@ -92,7 +93,6 @@ namespace Katydid //bool DoClustering(); const std::set< Nymph::KTDataPtr >& GetCandidates() const; - unsigned GetDataCount() const; private: @@ -102,7 +102,6 @@ namespace Katydid //std::vector< Points > fCompPoints; // points vectors for each component std::set< Nymph::KTDataPtr > fCandidates; - unsigned fDataCount; //*************** // Signals @@ -140,10 +139,6 @@ namespace Katydid { return fCandidates; } - inline unsigned KTDBScanTrackClustering::GetDataCount() const - { - return fDataCount; - } } diff --git a/Source/EventAnalysis/KTEventFirstTrackNUPCut.cc b/Source/EventAnalysis/KTEventFirstTrackNUPCut.cc new file mode 100644 index 000000000..8a709c75a --- /dev/null +++ b/Source/EventAnalysis/KTEventFirstTrackNUPCut.cc @@ -0,0 +1,88 @@ +/* + * KTEventFirstTrackNUPCut.cc + * + * Created on: June 14, 2018 + * Author: C. Claessens + */ + +#include "KTEventFirstTrackNUPCut.hh" +#include "KTMultiTrackEventData.hh" + +#include "KTLogger.hh" + +namespace Katydid +{ + KTLOGGER(ecnuplog, "KTEventFirstTrackNUPCut"); + + const std::string KTEventFirstTrackNUPCut::Result::sName = "event-first-track-nup-cut"; + + KT_REGISTER_CUT(KTEventFirstTrackNUPCut); + + KTEventFirstTrackNUPCut::KTEventFirstTrackNUPCut(const std::string& name) : + KTCutOneArg(name), + fMinTotalNUP(0.), + fMinAverageNUP(0.), + fWideOrNarrow( wide_or_narrow::wide ) + {} + + KTEventFirstTrackNUPCut::~KTEventFirstTrackNUPCut() + {} + + bool KTEventFirstTrackNUPCut::Configure(const scarab::param_node* node) + { + if (node == NULL) return true; + + SetMinTotalNUP( node->get_value< double >( "min-total-nup", GetMinTotalNUP() ) ); + SetMinAverageNUP( node->get_value< double >( "min-average-nup", GetMinAverageNUP() ) ); + + if (node->has("wide-or-narrow")) + { + if (node->get_value("wide-or-narrow") == "wide") + { + SetWideOrNarrow(wide_or_narrow::wide); + } + else if (node->get_value("wide-or-narrow") == "narrow") + { + SetWideOrNarrow(wide_or_narrow::narrow); + } + else + { + KTERROR(ecnuplog, "Invalid string for fWideOrNarrow"); + return false; + } + } + return true; + } + + bool KTEventFirstTrackNUPCut::Apply( Nymph::KTData& data, KTMultiTrackEventData& eventData ) + { + bool isCut = false; + if ( fWideOrNarrow == wide_or_narrow::narrow ) + { + if( eventData.GetFirstTrackTotalNUP() < fMinTotalNUP ) + { + isCut = true; + } + if( eventData.GetFirstTrackTotalNUP() / eventData.GetFirstTrackTimeLength() < fMinAverageNUP ) + { + isCut = true; + } + } + else + { + if( eventData.GetFirstTrackTotalWideNUP() < fMinTotalNUP ) + { + isCut = true; + } + if( eventData.GetFirstTrackTotalWideNUP() / eventData.GetFirstTrackTimeLength() < fMinAverageNUP ) + { + isCut = true; + } + } + + data.GetCutStatus().AddCutResult< KTEventFirstTrackNUPCut::Result >(isCut); + + return isCut; + } + +} // namespace Katydid diff --git a/Source/EventAnalysis/KTEventFirstTrackNUPCut.hh b/Source/EventAnalysis/KTEventFirstTrackNUPCut.hh new file mode 100644 index 000000000..186c3c476 --- /dev/null +++ b/Source/EventAnalysis/KTEventFirstTrackNUPCut.hh @@ -0,0 +1,67 @@ +/* + * KTEventFirstTrackNUPCut.hh + * + * Created on: June 14, 2018 + * Author: C. Claessens + */ + +#ifndef KTEVENTFIRSTTRACKNUPCUT_HH_ +#define KTEVENTFIRSTTRACKNUPCUT_HH_ + +#include "KTCut.hh" + +namespace Katydid +{ + + class KTMultiTrackEventData; + + /* + @class KTEventFirstTrackNUPCut + @author C. Claessens + + @brief Cut on the total NUP and the NUP per unit length of the first track in KTMultiTrackEventData + + @details + + + Configuration name: "event-first-track-nup-cut" + + Available configuration values: + - "min-average-nup": double -- minimum nup per unit length in the first track for the event to pass the cut + - "min-total-nup": double -- minimum total nup in the first track for the event to pass the cut + - "wide-or-narrow": string -- decides whether to use "wide" NUP or "narrow" NUP (default: "wide") + */ + + class KTEventFirstTrackNUPCut : public Nymph::KTCutOneArg< KTMultiTrackEventData > + { + + public: + struct Result : Nymph::KTExtensibleCutResult< Result > + { + static const std::string sName; + }; + + private: + enum class wide_or_narrow + { + wide, + narrow + }; + + public: + KTEventFirstTrackNUPCut(const std::string& name = "event-first-track-nup-cut"); + ~KTEventFirstTrackNUPCut(); + + bool Configure(const scarab::param_node* node); + + MEMBERVARIABLE(double, MinTotalNUP); + MEMBERVARIABLE(double, MinAverageNUP); + MEMBERVARIABLE(wide_or_narrow, WideOrNarrow); + + public: + bool Apply(Nymph::KTData& data, KTMultiTrackEventData& eventData); + + }; +} // namespace Katydid + +#endif /* KTEVENTFIRSTTRACKNUPCUT_HH_ */ diff --git a/Source/EventAnalysis/KTEventFirstTrackPowerCut.hh b/Source/EventAnalysis/KTEventFirstTrackPowerCut.hh index 396fe24ac..2b1ff7c71 100644 --- a/Source/EventAnalysis/KTEventFirstTrackPowerCut.hh +++ b/Source/EventAnalysis/KTEventFirstTrackPowerCut.hh @@ -24,7 +24,7 @@ namespace Katydid @details - Configuration name: "event-first-time-power-cut" + Configuration name: "event-first-track-power-cut" Available configuration values: - "min-power": double -- minimum power per unit length in the first track for the event to pass the cut diff --git a/Source/EventAnalysis/KTEventFirstTrackSNRCut.cc b/Source/EventAnalysis/KTEventFirstTrackSNRCut.cc new file mode 100644 index 000000000..2efec754d --- /dev/null +++ b/Source/EventAnalysis/KTEventFirstTrackSNRCut.cc @@ -0,0 +1,88 @@ +/* + * KTEventFirstTrackSNRCut.cc + * + * Created on: June 14, 2018 + * Author: C. Claessens + */ + +#include "KTEventFirstTrackSNRCut.hh" +#include "KTMultiTrackEventData.hh" + +#include "KTLogger.hh" + +namespace Katydid +{ + KTLOGGER(ecsnrlog, "KTEventFirstTrackSNRCut"); + + const std::string KTEventFirstTrackSNRCut::Result::sName = "event-first-track-snr-cut"; + + KT_REGISTER_CUT(KTEventFirstTrackSNRCut); + + KTEventFirstTrackSNRCut::KTEventFirstTrackSNRCut(const std::string& name) : + KTCutOneArg(name), + fMinTotalSNR(0.), + fMinAverageSNR(0.), + fWideOrNarrow( wide_or_narrow::wide ) + {} + + KTEventFirstTrackSNRCut::~KTEventFirstTrackSNRCut() + {} + + bool KTEventFirstTrackSNRCut::Configure(const scarab::param_node* node) + { + if (node == NULL) return true; + + SetMinTotalSNR( node->get_value< double >( "min-total-snr", GetMinTotalSNR() ) ); + SetMinAverageSNR( node->get_value< double >( "min-average-snr", GetMinAverageSNR() ) ); + if (node->has("wide-or-narrow")) + { + if (node->get_value("wide-or-narrow") == "wide") + { + SetWideOrNarrow(wide_or_narrow::wide); + } + else if (node->get_value("wide-or-narrow") == "narrow") + { + SetWideOrNarrow(wide_or_narrow::narrow); + } + else + { + KTERROR(ecsnrlog, "Invalid string for fWideOrNarrow"); + return false; + } + } + + return true; + } + + bool KTEventFirstTrackSNRCut::Apply( Nymph::KTData& data, KTMultiTrackEventData& eventData ) + { + bool isCut = false; + if ( fWideOrNarrow == wide_or_narrow::narrow ) + { + if( eventData.GetFirstTrackTotalSNR() < fMinTotalSNR ) + { + isCut = true; + } + if( eventData.GetFirstTrackTotalSNR() / eventData.GetFirstTrackTimeLength() < fMinAverageSNR ) + { + isCut = true; + } + } + else + { + if( eventData.GetFirstTrackTotalWideSNR() < fMinTotalSNR ) + { + isCut = true; + } + if( eventData.GetFirstTrackTotalWideSNR() / eventData.GetFirstTrackTimeLength() < fMinAverageSNR ) + { + isCut = true; + } + } + + data.GetCutStatus().AddCutResult< KTEventFirstTrackSNRCut::Result >(isCut); + + return isCut; + } + +} // namespace Katydid diff --git a/Source/EventAnalysis/KTEventFirstTrackSNRCut.hh b/Source/EventAnalysis/KTEventFirstTrackSNRCut.hh new file mode 100644 index 000000000..be0145b48 --- /dev/null +++ b/Source/EventAnalysis/KTEventFirstTrackSNRCut.hh @@ -0,0 +1,67 @@ +/* + * KTEventFirstTrackSNRCut.hh + * + * Created on: June 14, 2018 + * Author: C. Claessens + */ + +#ifndef KTEVENTFIRSTTRACKSNRCUT_HH_ +#define KTEVENTFIRSTTRACKSNRCUT_HH_ + +#include "KTCut.hh" + +namespace Katydid +{ + + class KTMultiTrackEventData; + + /* + @class KTEventFirstTrackSNRCut + @author C. Claessens + + @brief Cut on the total SNR and the SNR per unit length of the first track in KTMultiTrackEventData + + @details + + + Configuration name: "event-first-track-snr-cut" + + Available configuration values: + - "min-average-snr": double -- minimum snr per unit length in the first track for the event to pass the cut + - "min-total-snr": double -- minimum total snr in the first track for the event to pass the cut + - "wide-or-narrow": string -- decides whether to use "wide" SNR or "narrow" SNR (default: "wide") + */ + + class KTEventFirstTrackSNRCut : public Nymph::KTCutOneArg< KTMultiTrackEventData > + { + + private: + enum class wide_or_narrow + { + wide, + narrow + }; + + public: + struct Result : Nymph::KTExtensibleCutResult< Result > + { + static const std::string sName; + }; + + public: + KTEventFirstTrackSNRCut(const std::string& name = "event-first-track-snr-cut"); + ~KTEventFirstTrackSNRCut(); + + bool Configure(const scarab::param_node* node); + + MEMBERVARIABLE(double, MinTotalSNR); + MEMBERVARIABLE(double, MinAverageSNR); + MEMBERVARIABLE(wide_or_narrow, WideOrNarrow); + + public: + bool Apply(Nymph::KTData& data, KTMultiTrackEventData& eventData); + + }; +} // namespace Katydid + +#endif /* KTEVENTFIRSTTRACKSNRCUT_HH_ */ diff --git a/Source/EventAnalysis/KTIterativeTrackClustering.cc b/Source/EventAnalysis/KTIterativeTrackClustering.cc index 95d68c146..ba8199030 100644 --- a/Source/EventAnalysis/KTIterativeTrackClustering.cc +++ b/Source/EventAnalysis/KTIterativeTrackClustering.cc @@ -1,8 +1,9 @@ -/* - * KTIterativeTrackClustering.cc - * - * Created on: August 7, 2017 - * Author: C. Claessens +/** + @file KTIterativeTrackClustering.cc + @brief Contains KTIterativeTrackClustering + @details Groups collinear tracks into one + @author: C. Claessens + @date: August 7, 2017 */ #include "KTIterativeTrackClustering.hh" @@ -28,16 +29,17 @@ namespace Katydid fTimeGapTolerance(0.005), fFrequencyAcceptance(185000.0), fMaxTrackWidth(50000.0), + fLargeMaxTrackWidth(250000.0), fCompTracks(), fNewTracks(), + fNewSeqLineCands(), + fCompSeqLineCands(), fNTracks(0), - fApplyPowerCut(false), - fApplyDensityCut(false), - fPowerThreshold(0.0), - fDensityThreshold(0.0), fTrackSignal("track", this), - fDoneSignal("tracks-done", this), - fTakeTrackSlot("track", this, &KTIterativeTrackClustering::TakeTrack) + fSeqLineCandSignal("seq-cand", this), + fDoneSignal("clustering-done", this), + fTakeTrackSlot("track", this, &KTIterativeTrackClustering::TakeTrack), + fTakeSeqLineCandSlot("seq-cand", this, &KTIterativeTrackClustering::TakeSeqLineCandidate) { RegisterSlot("do-clustering", this, &KTIterativeTrackClustering::DoClusteringSlot); } @@ -57,17 +59,10 @@ namespace Katydid { SetMaxTrackWidth(node->get_value("max-track-width")); } - if (node->has("apply-power-cut")) + if (node->has("large-max-track-width")) { - SetApplyPowerCut(node->get_value("apply-power-cut", GetApplyPowerCut())); - SetPowerThreshold(node->get_value("power-threshold", GetPowerThreshold())); + SetLargeMaxTrackWidth(node->get_value("large-max-track-width")); } - if (node->has("apply-power-density-cut")) - { - SetApplyDensityCut(node->get_value("apply-power-density-cut", GetApplyDensityCut())); - SetDensityThreshold(node->get_value("power-density-threshold", GetDensityThreshold())); - } - return true; } @@ -84,7 +79,16 @@ namespace Katydid return true; } + bool KTIterativeTrackClustering::TakeSeqLineCandidate(KTSequentialLineData& SeqLineCand) + { + + KTDEBUG(itclog, "Taking SeqLine candidate: (" << SeqLineCand.GetStartTimeInRunC() << ", " << SeqLineCand.GetStartFrequency() << ", " << SeqLineCand.GetEndTimeInRunC() << ", " << SeqLineCand.GetEndFrequency() << ")"); + // copy the full track data + fCompSeqLineCands.push_back(SeqLineCand); + + return true; + } void KTIterativeTrackClustering::DoClusteringSlot() { if (! Run()) @@ -96,96 +100,22 @@ namespace Katydid bool KTIterativeTrackClustering::Run() { - return DoClustering(); - } - - bool KTIterativeTrackClustering::DoClustering() - { - if (! FindMatchingTracks()) + if (fCompTracks.size() != 0 ) { - KTERROR(itclog, "An error occurred while identifying extrapolated tracks"); - return false; + KTINFO( itclog, "Clustering procTracks"); + return DoCandidateClustering(fCompTracks, fNewTracks); } - - KTDEBUG(itclog, "Track building complete"); - fDoneSignal(); - - return true; - } - - bool KTIterativeTrackClustering::FindMatchingTracks() - { - KTINFO(itclog, "Finding extrapolated tracks"); - KTDEBUG(itclog, "TimeGapTolerance FrequencyAcceptance and MaxTrackWidth are: "< 1) + else { - while (numberOfTracks!=numberOfNewTracks) - { - numberOfTracks = fCompTracks.size(); - KTDEBUG(itclog, "Number of tracks to cluster: "<< numberOfTracks); - this->ExtrapolateClustering(); - - // Update number of tracks - numberOfNewTracks = fNewTracks.size(); - - KTDEBUG(itclog, "Number of new tracks: "<< numberOfNewTracks); - - fCompTracks.clear(); - fCompTracks = fNewTracks; - fNewTracks.clear(); - } + KTINFO( itclog, "Clustering SeqLine Candidates"); + return DoCandidateClustering(fCompSeqLineCands, fNewSeqLineCands); } - - this->EmitTrackCandidates(); - - return true; } - - bool KTIterativeTrackClustering::ExtrapolateClustering() + const void KTIterativeTrackClustering::CombineCandidates(const KTProcessedTrackData& oldTrack, KTProcessedTrackData& newTrack) { - bool match = false; - for (std::vector::iterator compIt = fCompTracks.begin(); compIt != fCompTracks.end(); ++compIt) - { - match = false; - for (std::vector::iterator newIt = fNewTracks.begin(); newIt != fNewTracks.end(); ++newIt) - { - if (this->DoTheyMatch(*compIt, *newIt)) - { - match = true; - KTDEBUG(itclog, "Found matching tracks"); - this->CombineTracks(*compIt, *newIt); - break; - } - // it is possible that the segments that get combined first are not direct neighbors in time - // in that case there can be a track segment very close to an already combined track - if (this->DoTheyOverlap(*compIt, *newIt)) - { - match = true; - KTDEBUG(itclog, "Found overlapping tracks"); - this->CombineTracks(*compIt, *newIt); - break; - } - } - - if (match == false) - { - KTProcessedTrackData newTrack(*compIt); - fNewTracks.push_back(newTrack); - } - } - return true; - } - + KTDEBUG(itclog, "Matching candidates are: "<< oldTrack.GetTrackID()<<" - "< newTrack.GetEndTimeInRunC()) { @@ -202,151 +130,147 @@ namespace Katydid newTrack.SetEndFrequency( oldTrack.GetEndFrequency()); newTrack.SetEndTimeInRunCSigma( oldTrack.GetEndTimeInRunCSigma()); newTrack.SetEndFrequencySigma( oldTrack.GetEndFrequencySigma()); - newTrack.SetSlope( (newTrack.GetEndFrequency() - newTrack.GetStartFrequency())/(newTrack.GetEndTimeInRunC() - newTrack.GetStartTimeInRunC())); - } - + newTrack.SetSlope( (newTrack.GetEndFrequency() - newTrack.GetStartFrequency())/(newTrack.GetEndTimeInRunC() - newTrack.GetStartTimeInRunC())); + + newTrack.SetNTrackBins( newTrack.GetNTrackBins() + oldTrack.GetNTrackBins() ); + newTrack.SetTotalTrackSNR( newTrack.GetTotalTrackSNR() + oldTrack.GetTotalTrackSNR() ); + newTrack.SetMaxTrackSNR( std::max( newTrack.GetMaxTrackSNR(), oldTrack.GetMaxTrackSNR() ) ); + newTrack.SetTotalTrackNUP( newTrack.GetTotalTrackNUP() + oldTrack.GetTotalTrackNUP() ); + newTrack.SetMaxTrackNUP( std::max( newTrack.GetMaxTrackNUP(), oldTrack.GetMaxTrackNUP() ) ); + newTrack.SetTotalWideTrackSNR( newTrack.GetTotalWideTrackSNR() + oldTrack.GetTotalWideTrackSNR() ); + newTrack.SetTotalWideTrackNUP( newTrack.GetTotalWideTrackNUP() + oldTrack.GetTotalWideTrackNUP() ); newTrack.SetTotalPower( newTrack.GetTotalPower() + oldTrack.GetTotalPower()); - newTrack.SetTimeLength( newTrack.GetEndTimeInRunC() - newTrack.GetStartTimeInRunC()); + + newTrack.SetTotalPowerSigma( sqrt(newTrack.GetTotalPowerSigma()*newTrack.GetTotalPowerSigma() + oldTrack.GetTotalPowerSigma()*oldTrack.GetTotalPowerSigma()) ); + //newTrack.SetTimeLength( newTrack.GetEndTimeInRunC() - newTrack.GetStartTimeInRunC()); + newTrack.SetTimeLengthSigma( sqrt(newTrack.GetTimeLengthSigma()*newTrack.GetTimeLengthSigma() + oldTrack.GetTimeLengthSigma()*oldTrack.GetTimeLengthSigma()) ); + //newTrack.SetFrequencyWidth( newTrack.GetEndFrequency() - newTrack.GetStartFrequency() ); + newTrack.SetFrequencyWidthSigma( sqrt(newTrack.GetFrequencyWidthSigma()*newTrack.GetFrequencyWidthSigma() + oldTrack.GetFrequencyWidthSigma()*oldTrack.GetFrequencyWidthSigma()) ); newTrack.SetSlopeSigma( sqrt(newTrack.GetSlopeSigma()*newTrack.GetSlopeSigma() + oldTrack.GetSlopeSigma()*oldTrack.GetSlopeSigma())); + newTrack.SetInterceptSigma( sqrt(newTrack.GetInterceptSigma()*newTrack.GetInterceptSigma() + oldTrack.GetInterceptSigma()*oldTrack.GetInterceptSigma())); } - - - bool KTIterativeTrackClustering::DoTheyMatch(KTProcessedTrackData& track1, KTProcessedTrackData& track2) + const void KTIterativeTrackClustering::CombineCandidates(const KTSequentialLineData& oldSeqLineCand, KTSequentialLineData& newSeqLineCand) { - bool slopeCondition1 = std::abs(track1.GetEndFrequency()+track1.GetSlope()*(track2.GetStartTimeInRunC()-track1.GetEndTimeInRunC()) - track2.GetStartFrequency()) newSeqLineCand.GetEndTimeInRunC()) { - return true; + newSeqLineCand.SetEndTimeInRunC( oldSeqLineCand.GetEndTimeInRunC()); + newSeqLineCand.SetEndFrequency( oldSeqLineCand.GetEndFrequency()); } + newSeqLineCand.SetSlope( (newSeqLineCand.GetEndFrequency() - newSeqLineCand.GetStartFrequency())/(newSeqLineCand.GetEndTimeInRunC() - newSeqLineCand.GetStartTimeInRunC()) ); - return false; - } - - bool KTIterativeTrackClustering::DoTheyOverlap(KTProcessedTrackData& track1, KTProcessedTrackData& track2) - { - // if the start time of track 2 is between start and end time of track 1 - bool condition1 = track2.GetStartTimeInRunC() < track1.GetEndTimeInRunC() and track2.GetStartTimeInRunC() >= track1.GetStartTimeInRunC(); - - // and the start and end frequency of track 2 are close to track 1 (or an extrapolated track 1) - bool condition2 = std::abs(track2.GetStartFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetStartTimeInRunC() - track1.GetStartTimeInRunC()))) < fMaxTrackWidth; - - // and the other end is nearby too - bool condition3 = std::abs(track2.GetEndFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetEndTimeInRunC() - track1.GetStartTimeInRunC()))) < fMaxTrackWidth * 5.0; - // This condition doesn't need to be as strict and just makes sure this isn't a new track after all (instead one could compare slopes) - - if (condition1 and condition2 and condition3) + KTDiscriminatedPoints points = oldSeqLineCand.GetPoints(); + for(KTDiscriminatedPoints::const_iterator pointIt = points.begin(); pointIt != points.end(); ++pointIt ) { - return true; + //KTDEBUG( itclog, "Adding points from oldSeqLineCand to newSeqLineCand: "<fTimeInRunC<<" "<fFrequency<<" "<fAmplitude<<" "<fNeighborhoodAmplitude ); + newSeqLineCand.AddPoint(*pointIt); } + } - // the other way around - bool condition4 = track1.GetStartTimeInRunC() < track2.GetEndTimeInRunC() and track1.GetStartTimeInRunC() >= track2.GetStartTimeInRunC(); - bool condition5 = std::abs(track1.GetStartFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetStartTimeInRunC() - track2.GetStartTimeInRunC()))) < fMaxTrackWidth; - bool condition6 = std::abs(track1.GetEndFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetEndTimeInRunC() - track2.GetStartTimeInRunC()))) < fMaxTrackWidth * 5.0; - - if (condition4 and condition5 and condition6) - { - return true; - } - - // same for endpoints overlapping in time - condition1 = track2.GetEndTimeInRunC() <= track1.GetEndTimeInRunC() and track2.GetEndTimeInRunC() > track1.GetStartTimeInRunC(); - condition2 = std::abs(track2.GetEndFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetEndTimeInRunC() - track1.GetStartTimeInRunC()))) < fMaxTrackWidth; - condition3 = std::abs(track2.GetStartFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetStartTimeInRunC() - track1.GetStartTimeInRunC()))) < fMaxTrackWidth * 5.0; - - if (condition1 and condition2 and condition2) - { - return true; - } + void KTIterativeTrackClustering::EmitCandidates(std::vector& compCands) + { + KTDEBUG(itclog, "Number of tracks to emit: "< track2.GetStartTimeInRunC(); - condition5 = std::abs(track1.GetEndFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetEndTimeInRunC() - track2.GetStartTimeInRunC()))) < fMaxTrackWidth; - condition6 = std::abs(track1.GetStartFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetStartTimeInRunC() - track2.GetStartTimeInRunC()))) < fMaxTrackWidth * 5.0; + std::vector::iterator trackIt = compCands.begin(); - if (condition4 and condition5 and condition6) + while(trackIt!=compCands.end()) { - return true; + // Set up new data object + Nymph::KTDataPtr data( new Nymph::KTData() ); + KTProcessedTrackData& newTrack = data->Of< KTProcessedTrackData >(); + newTrack.SetComponent( trackIt->GetComponent() ); + newTrack.SetAcquisitionID( trackIt->GetAcquisitionID() ); + newTrack.SetTrackID( fNTracks ); + fNTracks++; + + newTrack.SetStartTimeInRunC( trackIt->GetStartTimeInRunC() ); + newTrack.SetStartTimeInRunCSigma( trackIt->GetStartTimeInRunCSigma() ); + newTrack.SetEndTimeInRunC( trackIt->GetEndTimeInRunC() ); + newTrack.SetEndTimeInRunCSigma( trackIt->GetEndTimeInRunCSigma() ); + newTrack.SetStartTimeInAcq( trackIt->GetStartTimeInAcq() ); + newTrack.SetTimeLength( trackIt->GetTimeLength() ); + newTrack.SetTimeLengthSigma( trackIt->GetTimeLengthSigma() ); + newTrack.SetStartFrequency( trackIt->GetStartFrequency() ); + newTrack.SetStartFrequency( trackIt->GetStartFrequencySigma() ); + newTrack.SetEndFrequency( trackIt->GetEndFrequency() ); + newTrack.SetEndFrequencySigma( trackIt->GetEndFrequencySigma() ); + newTrack.SetSlope( trackIt->GetSlope() ); + newTrack.SetSlopeSigma( trackIt->GetSlopeSigma() ); + newTrack.SetTotalPower( trackIt->GetTotalPower() ); + newTrack.SetTotalPowerSigma( trackIt->GetTotalPowerSigma() ); + newTrack.SetFrequencyWidth( trackIt->GetFrequencyWidth() ); + newTrack.SetFrequencyWidthSigma( trackIt->GetFrequencyWidthSigma() ); + newTrack.SetIntercept( trackIt->GetFrequencyWidth() ); + newTrack.SetInterceptSigma( trackIt->GetInterceptSigma() ); + + newTrack.SetNTrackBins( trackIt->GetNTrackBins() ); + newTrack.SetTotalTrackSNR( trackIt->GetTotalTrackSNR() ); + newTrack.SetMaxTrackSNR( trackIt->GetMaxTrackSNR() ); + newTrack.SetTotalTrackNUP( trackIt->GetTotalTrackNUP() ); + newTrack.SetMaxTrackNUP( trackIt->GetMaxTrackNUP() ); + newTrack.SetTotalWideTrackSNR( trackIt->GetTotalWideTrackSNR() ); + newTrack.SetTotalWideTrackNUP( trackIt->GetTotalWideTrackNUP() ); + + + // Process & emit new track + + KTINFO(itclog, "Now processing tracksCandidates"); + ProcessNewTrack( newTrack ); + + //KTDEBUG(itclog, "Emitting track signal"); + fCandidates.insert( data ); + fTrackSignal( data ); + + trackIt = compCands.erase(trackIt); } - return false; } - - - void KTIterativeTrackClustering::EmitTrackCandidates() + void KTIterativeTrackClustering::EmitCandidates(std::vector& compCands) { - KTDEBUG(itclog, "Number of tracks to emit: "<::iterator trackIt = fCompTracks.begin(); - while(trackIt!=fCompTracks.end()) - { - lineIsTrack = true; + std::vector::iterator candIt = compCands.begin(); - if (fApplyPowerCut) - { - if (trackIt->GetTotalPower() <= fPowerThreshold) - { - KTDEBUG(itclog, "track power below threshold: "<GetTotalPower()<<" "<Of< KTSequentialLineData >(); + newSeqLineCand.SetComponent( candIt->GetComponent() ); + newSeqLineCand.SetAcquisitionID( candIt->GetAcquisitionID() ); + newSeqLineCand.SetCandidateID( fNTracks ); + fNTracks++; + + newSeqLineCand.SetSlope(candIt->GetSlope()); + + KTDiscriminatedPoints& points = candIt->GetPoints(); + for(KTDiscriminatedPoints::const_iterator pointIt = points.begin(); pointIt != points.end(); ++pointIt ) { - if (trackIt->GetTotalPower()/(trackIt->GetEndTimeInRunC()-trackIt->GetStartTimeInRunC()) <= fDensityThreshold) - { - KTDEBUG(itclog, "track power density below threshold: "<GetTotalPower()/(trackIt->GetEndTimeInRunC()-trackIt->GetStartTimeInRunC()) <<" "<< fDensityThreshold); - lineIsTrack = false; - } + //KTDEBUG( itclog, "Adding points to newSeqLineCand: "<fTimeInRunC<<" "<fFrequency<<" "<fAmplitude<<" "<fNeighborhoodAmplitude ); + newSeqLineCand.AddPoint( *pointIt ); } + newSeqLineCand.CalculateTotalPower(); + newSeqLineCand.CalculateTotalSNR(); + newSeqLineCand.CalculateTotalNUP(); - if (lineIsTrack == true) - { - // Set up new data object - Nymph::KTDataPtr data( new Nymph::KTData() ); - KTProcessedTrackData& newTrack = data->Of< KTProcessedTrackData >(); - newTrack.SetComponent( trackIt->GetComponent() ); - newTrack.SetAcquisitionID( trackIt->GetAcquisitionID()); - newTrack.SetTrackID(fNTracks); - fNTracks++; - - newTrack.SetStartTimeInRunC( trackIt->GetStartTimeInRunC()); - newTrack.SetEndTimeInRunC( trackIt->GetEndTimeInRunC()); - newTrack.SetStartTimeInAcq( trackIt->GetStartTimeInAcq()); - newTrack.SetStartFrequency( trackIt->GetStartFrequency()); - newTrack.SetEndFrequency( trackIt->GetEndFrequency()); - newTrack.SetSlope(trackIt->GetSlope()); - newTrack.SetTotalPower(trackIt->GetTotalPower()); - - - // Process & emit new track - - KTINFO(itclog, "Now processing tracksCandidates"); - ProcessNewTrack( newTrack ); - - KTDEBUG(itclog, "Emitting track signal"); - fTrackSignal( data ); - } - trackIt = fCompTracks.erase(trackIt); + fCandidates.insert( data ); + fSeqLineCandSignal( data ); + + candIt = compCands.erase(candIt); } } - const void KTIterativeTrackClustering::ProcessNewTrack( KTProcessedTrackData& myNewTrack ) { myNewTrack.SetTimeLength( myNewTrack.GetEndTimeInRunC() - myNewTrack.GetStartTimeInRunC() ); diff --git a/Source/EventAnalysis/KTIterativeTrackClustering.hh b/Source/EventAnalysis/KTIterativeTrackClustering.hh index 85e928f0a..182df0dda 100644 --- a/Source/EventAnalysis/KTIterativeTrackClustering.hh +++ b/Source/EventAnalysis/KTIterativeTrackClustering.hh @@ -15,8 +15,11 @@ #include "KTData.hh" #include "KTMemberVariable.hh" #include "KTProcessedTrackData.hh" +#include "KTSequentialLineData.hh" +#include "KTDiscriminatedPoint.hh" #include +#include namespace Katydid { @@ -25,31 +28,33 @@ namespace Katydid @class KTIterativeLineClustering @author C. Claessens - @brief merges track segments until number of lines stops decreasing + @brief merges track segments until number of tracks stops decreasing @details - Checks whether track start/ends matches another track's extrapolation + Checks whether track start/ends match another track's extrapolation. + Can work with KTProcessedTracksData or KTSequentialLineData Configuration name: "iterative-track-clustering" Available configuration values: - "time-gap-tolerance": maximum time gap between tracks - "frequency-acceptance": maximum allowed distance from the slope extrapolation - - "max-track-width": radius around a track where there cannot be another track - - "apply-power-cut": default is false - - "apply-power-density-cut": default is false - - "power-threshold": total track power must be above this threshold - - "power-density-threshold": total power per second threshold + - "max-track-width": if the start- or end point of a track is closer than this value (in frequency) the tracks are combined to one... + - "large-max-track-width": if their largest distance in frequency is not greater than this Slots: - - "track": void (shared_ptr) -- If this is a new acquisition; Adds tracks to the internally-stored set of points; Requires KTProcessedTrackData. + - "track": void (KTDataPtr) -- Collects incoming KTProcessedTrackData objects. Clustering will produces new data pointer with KTProcessedTrackData + - "sql-cand": void (KTDataPtr) -- Collects incoming KTSequentialLineData objects. Clustering will produced new data pointer with KTSequentialLineData - "do-clustering": void () -- Triggers clustering algorithm Signals: - - "track": void (shared_ptr) -- Emitted for each group found; Guarantees KTProcessedTrackData. - - "clustering-done": void () -- Emitted when track clustering is complete + - "track": void (KTDataPtr) -- Created and emitted for each group found; Guarantees KTProcessedTrackData. + - "sql-cand: void (KTDataPtr) -- Created and emitted for each group found; Guarantees KTSequentialLineData. + - "clustering-done": void () -- Emitted when clustering is complete */ + KTLOGGER(itchlog, "KTIterativeTrackClustering"); + class KTIterativeTrackClustering : public Nymph::KTPrimaryProcessor { public: @@ -57,39 +62,52 @@ namespace Katydid virtual ~KTIterativeTrackClustering(); bool Configure(const scarab::param_node* node); + bool TakeTrack(KTProcessedTrackData& track); + bool TakeSeqLineCandidate(KTSequentialLineData& SeqLineCand); + bool Run(); + const std::set< Nymph::KTDataPtr >& GetCandidates() const; + + private: MEMBERVARIABLE(double, TimeGapTolerance); MEMBERVARIABLE(double, FrequencyAcceptance); MEMBERVARIABLE(double, MaxTrackWidth); - MEMBERVARIABLE(bool, ApplyPowerCut); - MEMBERVARIABLE(bool, ApplyDensityCut); - MEMBERVARIABLE(double, PowerThreshold); - MEMBERVARIABLE(double, DensityThreshold); + MEMBERVARIABLE(double, LargeMaxTrackWidth); MEMBERVARIABLE(unsigned, NTracks); + private: + template + bool DoCandidateClustering(std::vector compCands, std::vector newCands); + + template + bool FindMatchingCandidates(std::vector compCands, std::vector newCands); - public: - // Store point information locally - bool TakeTrack(KTProcessedTrackData& track); + template + bool ExtrapolateClustering(std::vector& compCands, std::vector& newCands); - //void SetNComponents(unsigned nComps); - bool DoClustering(); - bool Run(); + template + bool DoTheyMatch(TracklikeCandidate& track1, TracklikeCandidate& track2); + + template + bool DoTheyOverlap(TracklikeCandidate& track1, TracklikeCandidate& track2); private: - bool ExtrapolateClustering(); - bool DoTheyMatch(KTProcessedTrackData& track1, KTProcessedTrackData& track2); - bool DoTheyOverlap(KTProcessedTrackData& track1, KTProcessedTrackData& track2); - const void CombineTracks(const KTProcessedTrackData& track1, KTProcessedTrackData& track2); - bool FindMatchingTracks(); - void EmitTrackCandidates(); + const void CombineCandidates(const KTProcessedTrackData& track1, KTProcessedTrackData& track2); + const void CombineCandidates(const KTSequentialLineData& oldSeqLineCand, KTSequentialLineData& newSeqLineCand); + void EmitCandidates(std::vector& compCands); + void EmitCandidates(std::vector& compCands); const void ProcessNewTrack( KTProcessedTrackData& myNewTrack ); std::vector fCompTracks; std::vector fNewTracks; + std::vector fCompSeqLineCands; + std::vector fNewSeqLineCands; + + std::set< Nymph::KTDataPtr > fCandidates; + //*************** // Signals @@ -97,6 +115,7 @@ namespace Katydid private: Nymph::KTSignalData fTrackSignal; + Nymph::KTSignalData fSeqLineCandSignal; Nymph::KTSignalOneArg< void > fDoneSignal; //*************** @@ -105,11 +124,175 @@ namespace Katydid private: Nymph::KTSlotDataOneType< KTProcessedTrackData > fTakeTrackSlot; + Nymph::KTSlotDataOneType< KTSequentialLineData > fTakeSeqLineCandSlot; void DoClusteringSlot(); }; + inline const std::set< Nymph::KTDataPtr >& KTIterativeTrackClustering::GetCandidates() const + { + return fCandidates; + } + + template + bool KTIterativeTrackClustering::DoCandidateClustering(std::vector compCands, std::vector newCands) + { + if (! FindMatchingCandidates(compCands, newCands)) + { + KTERROR(itchlog, "An error occurred while identifying extrapolated tracks"); + return false; + } + + KTDEBUG(itchlog, "Candidate building complete"); + fDoneSignal(); + + return true; + } + + template + bool KTIterativeTrackClustering::FindMatchingCandidates(std::vector compCands, std::vector newCands) + { + KTINFO(itchlog, "Finding extrapolated candidates"); + KTDEBUG(itchlog, "TimeGapTolerance FrequencyAcceptance and MaxTrackWidth are: "< 1) + { + while (numberOfCandidates!=numberOfNewCandidates) + { + numberOfCandidates = compCands.size(); + KTDEBUG(itchlog, "Number of candidates to cluster: "<< numberOfCandidates); + this->ExtrapolateClustering(compCands, newCands); + + // Update number of tracks + numberOfNewCandidates = newCands.size(); + + KTDEBUG(itchlog, "Number of candidates after clustering: "<< numberOfNewCandidates); + + compCands.clear(); + compCands = newCands; + newCands.clear(); + } + } + + this->EmitCandidates(compCands); + + return true; + } + + template + bool KTIterativeTrackClustering::ExtrapolateClustering(std::vector& compCands, std::vector& newCands) + { + bool match = false; + for (typename std::vector::iterator compIt = compCands.begin(); compIt != compCands.end(); ++compIt) + { + match = false; + for (typename std::vector::iterator newIt = newCands.begin(); newIt != newCands.end(); ++newIt) + { + if (this->DoTheyMatch(*compIt, *newIt)) + { + match = true; + KTDEBUG(itchlog, "Found matching candidates"); + this->CombineCandidates(*compIt, *newIt); + break; + } + // it is possible that the segments that get combined first are not direct neighbors in time + // in that case there can be a track segment very close to an already combined track + if (this->DoTheyOverlap(*compIt, *newIt)) + { + match = true; + KTDEBUG(itchlog, "Found overlapping candidates"); + this->CombineCandidates(*compIt, *newIt); + break; + } + } + + if (match == false) + { + newCands.push_back(*compIt); + } + } + return true; + } + + template + bool KTIterativeTrackClustering::DoTheyMatch(TracklikeCandidate& track1, TracklikeCandidate& track2) + { + bool slopeCondition1 = std::abs(track1.GetEndFrequency()+track1.GetSlope()*(track2.GetStartTimeInRunC()-track1.GetEndTimeInRunC()) - track2.GetStartFrequency()) + bool KTIterativeTrackClustering::DoTheyOverlap(TracklikeCandidate& track1, TracklikeCandidate& track2) + { + // if the start time of track 2 is between start and end time of track 1 + bool condition1 = track2.GetStartTimeInRunC() < track1.GetEndTimeInRunC() and track2.GetStartTimeInRunC() >= track1.GetStartTimeInRunC(); + + // and the start and end frequency of track 2 are close to track 1 (or an extrapolated track 1) + bool condition2 = std::abs(track2.GetStartFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetStartTimeInRunC() - track1.GetStartTimeInRunC()))) < fMaxTrackWidth; + + // and the other end is nearby too + bool condition3 = std::abs(track2.GetEndFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetEndTimeInRunC() - track1.GetStartTimeInRunC()))) < fLargeMaxTrackWidth; + // This condition doesn't need to be as strict and just makes sure this isn't a new track after all (instead one could compare slopes) + + if (condition1 and condition2 and condition3) + { + return true; + } + + // the other way around + bool condition4 = track1.GetStartTimeInRunC() < track2.GetEndTimeInRunC() and track1.GetStartTimeInRunC() >= track2.GetStartTimeInRunC(); + bool condition5 = std::abs(track1.GetStartFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetStartTimeInRunC() - track2.GetStartTimeInRunC()))) < fMaxTrackWidth; + bool condition6 = std::abs(track1.GetEndFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetEndTimeInRunC() - track2.GetStartTimeInRunC()))) < fLargeMaxTrackWidth; + + if (condition4 and condition5 and condition6) + { + return true; + } + + // same for endpoints overlapping in time + condition1 = track2.GetEndTimeInRunC() <= track1.GetEndTimeInRunC() and track2.GetEndTimeInRunC() > track1.GetStartTimeInRunC(); + condition2 = std::abs(track2.GetEndFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetEndTimeInRunC() - track1.GetStartTimeInRunC()))) < fMaxTrackWidth; + condition3 = std::abs(track2.GetStartFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetStartTimeInRunC() - track1.GetStartTimeInRunC()))) < fLargeMaxTrackWidth; + + if (condition1 and condition2 and condition2) + { + return true; + } + + // again the other way around + condition4 = track1.GetEndTimeInRunC() <= track2.GetEndTimeInRunC() and track1.GetEndTimeInRunC() > track2.GetStartTimeInRunC(); + condition5 = std::abs(track1.GetEndFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetEndTimeInRunC() - track2.GetStartTimeInRunC()))) < fMaxTrackWidth; + condition6 = std::abs(track1.GetStartFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetStartTimeInRunC() - track2.GetStartTimeInRunC()))) < fLargeMaxTrackWidth; + if (condition4 and condition5 and condition6) + { + return true; + } + return false; + } } /* namespace Katydid */ #endif /* KTITERATIVETRACKCLUSTERING_HH_ */ diff --git a/Source/EventAnalysis/KTMultiSliceClustering.cc b/Source/EventAnalysis/KTMultiSliceClustering.cc index 252cb3872..d215a69af 100644 --- a/Source/EventAnalysis/KTMultiSliceClustering.cc +++ b/Source/EventAnalysis/KTMultiSliceClustering.cc @@ -715,8 +715,8 @@ namespace Katydid for (; ! spectra[i]; ++i); // get the first spectrum that is definitely there (since sometimes spectra are missing) if (i != spectra.size()) { - wfcData.SetMinimumFrequency(spectra[i]->GetBinLowEdge(firstFreqBin)); - wfcData.SetMaximumFrequency(spectra[i]->GetBinLowEdge(lastFreqBin) + freqBinWidth); + wfcData.SetMinFrequency(spectra[i]->GetBinLowEdge(firstFreqBin)); + wfcData.SetMaxFrequency(spectra[i]->GetBinLowEdge(lastFreqBin) + freqBinWidth); } #ifndef NDEBUG printStream << "\tTime in run: " << wfcData.GetTimeInRun() << " s\n"; @@ -726,13 +726,13 @@ namespace Katydid printStream << "\tMean start freq: " << wfcData.GetMeanStartFrequency() << " Hz\n"; printStream << "\tMean end freq: " << wfcData.GetMeanEndFrequency() << " Hz\n"; printStream << "\tFreq width: " << wfcData.GetFrequencyWidth() << " Hz\n"; - printStream << "\tMinimum frequency: " << wfcData.GetMinimumFrequency() << " Hz\n"; - printStream << "\tMaximum frequency: " << wfcData.GetMaximumFrequency() << " Hz\n"; + printStream << "\tMinimum frequency: " << wfcData.GetMinFrequency() << " Hz\n"; + printStream << "\tMaximum frequency: " << wfcData.GetMaxFrequency() << " Hz\n"; #endif double tfStartTime = wfcData.GetTimeInRun() + endTimeBinShift - double(fNFramingTimeBins) * timeBinWidth; - double tfStartFreq = wfcData.GetMinimumFrequency() - double(fNFramingTimeBins) * freqBinWidth; + double tfStartFreq = wfcData.GetMinFrequency() - double(fNFramingTimeBins) * freqBinWidth; KTTimeFrequency* tf = new KTTimeFrequencyPolar(nTimeBinsWithFrame, tfStartTime, tfStartTime + double(nTimeBinsWithFrame)*timeBinWidth, nFreqBinsWithFrame, tfStartFreq, tfStartFreq + double(nFreqBinsWithFrame)*freqBinWidth); //KTDEBUG(sclog, "tf freq dims: " << tfStartFreq << " - " << tfStartFreq + double(nFreqBinsWithFrame)*freqBinWidth); for (int iTBin=firstTimeBinWithFrame; iTBin <= lastTimeBinWithFrame; ++iTBin) diff --git a/Source/EventAnalysis/KTOverlappingTrackClustering.cc b/Source/EventAnalysis/KTOverlappingTrackClustering.cc index 64922a0b0..646cc2f4b 100644 --- a/Source/EventAnalysis/KTOverlappingTrackClustering.cc +++ b/Source/EventAnalysis/KTOverlappingTrackClustering.cc @@ -1,8 +1,9 @@ -/* - * KTOverlappingTrackClustering.cc - * - * Created on: August 7, 2017 - * Author: C. Claessens +/** + @file KTOverlappingTrackClustering.cc + @brief Contains KTOverlappingTrackClustering + @details Groups overlapping or crossing tracks into one + @author: C. Claessens + @date: August 7, 2017 */ #include "KTOverlappingTrackClustering.hh" @@ -28,16 +29,18 @@ namespace Katydid KTOverlappingTrackClustering::KTOverlappingTrackClustering(const std::string& name) : KTPrimaryProcessor(name), fMaxTrackWidth(200000.), + fLargeMaxTrackWidth(1e6), fCompTracks(), fNewTracks(), + fNewSeqLineCands(), + fCompSeqLineCands(), + fCandidates(), fNTracks(0), - fApplyPowerCut(false), - fApplyDensityCut(false), - fPowerThreshold(0.0), - fDensityThreshold(0.0), fTrackSignal("track", this), - fDoneSignal("tracks-done", this), - fTakeTrackSlot("track", this, &KTOverlappingTrackClustering::TakeTrack) + fSeqLineCandSignal("seq-cand", this), + fDoneSignal("clustering-done", this), + fTakeTrackSlot("track", this, &KTOverlappingTrackClustering::TakeTrack), + fTakeSeqLineCandSlot("seq-cand", this, &KTOverlappingTrackClustering::TakeSeqLineCandidate) { RegisterSlot("do-clustering", this, &KTOverlappingTrackClustering::DoClusteringSlot); } @@ -54,15 +57,9 @@ namespace Katydid { SetMaxTrackWidth(node->get_value("max-track-width")); } - if (node->has("apply-power-cut")) + if (node->has("large-max-track-width")) { - SetApplyPowerCut(node->get_value("apply-power-cut", GetApplyPowerCut())); - SetPowerThreshold(node->get_value("power-threshold", GetPowerThreshold())); - } - if (node->has("apply-power-density-cut")) - { - SetApplyDensityCut(node->get_value("apply-power-density-cut", GetApplyDensityCut())); - SetDensityThreshold(node->get_value("power-density-threshold", GetDensityThreshold())); + SetLargeMaxTrackWidth(node->get_value("large-max-track-width")); } return true; } @@ -80,6 +77,16 @@ namespace Katydid return true; } + bool KTOverlappingTrackClustering::TakeSeqLineCandidate(KTSequentialLineData& SeqLineCand) + { + + KTDEBUG(otclog, "Taking SeqLine candidate: (" << SeqLineCand.GetStartTimeInRunC() << ", " << SeqLineCand.GetStartFrequency() << ", " << SeqLineCand.GetEndTimeInRunC() << ", " << SeqLineCand.GetEndFrequency() << ")"); + + // copy the full track data + fCompSeqLineCands.push_back(SeqLineCand); + + return true; + } void KTOverlappingTrackClustering::DoClusteringSlot() { @@ -92,96 +99,23 @@ namespace Katydid bool KTOverlappingTrackClustering::Run() { - return DoClustering(); - } - - bool KTOverlappingTrackClustering::DoClustering() - { - if (! FindMatchingTracks()) + if (fCompTracks.size() != 0 ) { - KTERROR(otclog, "An error occurred while identifying overlapping tracks"); - return false; + KTINFO( otclog, "Clustering procTracks"); + return DoCandidateClustering(fCompTracks, fNewTracks); } - - KTDEBUG(otclog, "Track building complete"); - fDoneSignal(); - - return true; - } - - bool KTOverlappingTrackClustering::FindMatchingTracks() - { - KTINFO(otclog, "Finding overlapping tracks"); - KTDEBUG(otclog, "FrequencyAcceptance is: "< 1) + else { - while (numberOfTracks!=numberOfNewTracks) - { - numberOfTracks = fCompTracks.size(); - KTDEBUG(otclog, "Number of tracks to cluster: "<< numberOfTracks); - this->OverlapClustering(); - - // Update number of tracks - numberOfNewTracks = fNewTracks.size(); - - KTDEBUG(otclog, "Number of new tracks: "<< numberOfNewTracks); - - fCompTracks.clear(); - fCompTracks = fNewTracks; - fNewTracks.clear(); - } + KTINFO( otclog, "Clustering SeqLine Candidates"); + return DoCandidateClustering(fCompSeqLineCands, fNewSeqLineCands); } - - this->EmitTrackCandidates(); - - return true; } - bool KTOverlappingTrackClustering::OverlapClustering() - { - bool match = false; - for (std::vector::iterator compIt = fCompTracks.begin(); compIt != fCompTracks.end(); ++compIt) - { - match = false; - for (std::vector::iterator newIt = fNewTracks.begin(); newIt != fNewTracks.end(); ++newIt) - { - if (this->DoTheyOverlap(*compIt, *newIt)) - { - match = true; - KTDEBUG(otclog, "Found overlapping tracks") - this->CombineTracks(*compIt, *newIt); - break; - } - - // since there appear to be real tracks crossing each other this check is removed here - /*if (this->DoTheyCross(*compIt, *newIt)) - { - match = true; - KTDEBUG(otclog, "Found crossing tracks") - this->CombineTracks(*compIt, *newIt); - break; - }*/ - } - if (match == false) - { - KTProcessedTrackData newTrack(*compIt); - fNewTracks.push_back(newTrack); - } - } - return true; - } - - - const void KTOverlappingTrackClustering::CombineTracks(const KTProcessedTrackData& oldTrack, KTProcessedTrackData& newTrack) + const void KTOverlappingTrackClustering::CombineCandidates(const KTProcessedTrackData& oldTrack, KTProcessedTrackData& newTrack) { + KTDEBUG(otclog, "Matching candidates are: "<< oldTrack.GetTrackID()<<" - "< newTrack.GetEndTimeInRunC()) { @@ -198,64 +130,53 @@ namespace Katydid newTrack.SetEndFrequency( oldTrack.GetEndFrequency()); newTrack.SetEndTimeInRunCSigma( oldTrack.GetEndTimeInRunCSigma()); newTrack.SetEndFrequencySigma( oldTrack.GetEndFrequencySigma()); - newTrack.SetSlope( (newTrack.GetEndFrequency() - newTrack.GetStartFrequency())/(newTrack.GetEndTimeInRunC() - newTrack.GetStartTimeInRunC())); - } - //newTrack.SetSlope( (newTrack.GetEndFrequency() - newTrack.GetStartFrequency())/(newTrack.GetEndTimeInRunC() - newTrack.GetStartTimeInRunC())); + newTrack.SetSlope( (newTrack.GetEndFrequency() - newTrack.GetStartFrequency())/(newTrack.GetEndTimeInRunC() - newTrack.GetStartTimeInRunC())); + + newTrack.SetNTrackBins( newTrack.GetNTrackBins() + oldTrack.GetNTrackBins() ); + newTrack.SetTotalTrackSNR( newTrack.GetTotalTrackSNR() + oldTrack.GetTotalTrackSNR() ); + newTrack.SetMaxTrackSNR( std::max( newTrack.GetMaxTrackSNR(), oldTrack.GetMaxTrackSNR() ) ); + newTrack.SetTotalTrackNUP( newTrack.GetTotalTrackNUP() + oldTrack.GetTotalTrackNUP() ); + newTrack.SetMaxTrackNUP( std::max( newTrack.GetMaxTrackNUP(), oldTrack.GetMaxTrackNUP() ) ); + newTrack.SetTotalWideTrackSNR( newTrack.GetTotalWideTrackSNR() + oldTrack.GetTotalWideTrackSNR() ); + newTrack.SetTotalWideTrackNUP( newTrack.GetTotalWideTrackNUP() + oldTrack.GetTotalWideTrackNUP() ); newTrack.SetTotalPower( newTrack.GetTotalPower() + oldTrack.GetTotalPower()); - newTrack.SetTimeLength( newTrack.GetEndTimeInRunC() - newTrack.GetStartTimeInRunC()); + newTrack.SetTotalPowerSigma( sqrt(newTrack.GetTotalPowerSigma()*newTrack.GetTotalPowerSigma() + oldTrack.GetTotalPowerSigma()*oldTrack.GetTotalPowerSigma()) ); + //newTrack.SetTimeLength( newTrack.GetEndTimeInRunC() - newTrack.GetStartTimeInRunC()); + newTrack.SetTimeLengthSigma( sqrt(newTrack.GetTimeLengthSigma()*newTrack.GetTimeLengthSigma() + oldTrack.GetTimeLengthSigma()*oldTrack.GetTimeLengthSigma()) ); + //newTrack.SetFrequencyWidth( newTrack.GetEndFrequency() - newTrack.GetStartFrequency() ); + newTrack.SetFrequencyWidthSigma( sqrt(newTrack.GetFrequencyWidthSigma()*newTrack.GetFrequencyWidthSigma() + oldTrack.GetFrequencyWidthSigma()*oldTrack.GetFrequencyWidthSigma()) ); newTrack.SetSlopeSigma( sqrt(newTrack.GetSlopeSigma()*newTrack.GetSlopeSigma() + oldTrack.GetSlopeSigma()*oldTrack.GetSlopeSigma())); + newTrack.SetInterceptSigma( sqrt(newTrack.GetInterceptSigma()*newTrack.GetInterceptSigma() + oldTrack.GetInterceptSigma()*oldTrack.GetInterceptSigma())); } - bool KTOverlappingTrackClustering::DoTheyOverlap(KTProcessedTrackData& track1, KTProcessedTrackData& track2) + const void KTOverlappingTrackClustering::CombineCandidates(const KTSequentialLineData& oldSeqLineCand, KTSequentialLineData& newSeqLineCand) { - // if there are two tracks that should be just one, any point of the track will be close to the other track (extrapolated) - // therefore it is enough to check start and endpoint of a track. one should overlap in time, both should be close in frequency - - // if the start time of track 2 is between start and end time of track 1 - bool condition1 = track2.GetStartTimeInRunC() < track1.GetEndTimeInRunC() and track2.GetStartTimeInRunC() >= track1.GetStartTimeInRunC(); - - // and the start frequency of track 2 is too close to track 1 - bool condition2 = std::abs(track2.GetStartFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetStartTimeInRunC() - track1.GetStartTimeInRunC()))) < fMaxTrackWidth; - - // same for endpoint - bool condition3 = std::abs(track2.GetEndFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetEndTimeInRunC() - track1.GetStartTimeInRunC()))) < fMaxTrackWidth*5.0; - - if (condition1 and condition2 and condition3) + KTDEBUG(otclog, "Matching candidates are: "<< oldSeqLineCand.GetCandidateID()<<" - "<= track2.GetStartTimeInRunC(); - bool condition5 = std::abs(track1.GetStartFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetStartTimeInRunC() - track2.GetStartTimeInRunC()))) < fMaxTrackWidth; - bool condition6 = std::abs(track1.GetEndFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetEndTimeInRunC() - track2.GetStartTimeInRunC()))) < fMaxTrackWidth*5.0; - - if (condition4 and condition5 and condition6) + if (oldSeqLineCand.GetEndTimeInRunC() > newSeqLineCand.GetEndTimeInRunC()) { - return true; + newSeqLineCand.SetEndTimeInRunC( oldSeqLineCand.GetEndTimeInRunC()); + newSeqLineCand.SetEndFrequency( oldSeqLineCand.GetEndFrequency()); } - // same for end point of track2 - condition1 = track2.GetEndTimeInRunC() <= track1.GetEndTimeInRunC() and track2.GetEndTimeInRunC() > track1.GetStartTimeInRunC(); - condition2 = std::abs(track2.GetEndFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetEndTimeInRunC() - track1.GetStartTimeInRunC()))) < fMaxTrackWidth; - condition3 = std::abs(track2.GetStartFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetStartTimeInRunC() - track1.GetStartTimeInRunC()))) < fMaxTrackWidth*5.0; + newSeqLineCand.SetSlope( (newSeqLineCand.GetEndFrequency() - newSeqLineCand.GetStartFrequency())/(newSeqLineCand.GetEndTimeInRunC() - newSeqLineCand.GetStartTimeInRunC()) ); - if (condition1 and condition2 and condition3) + KTDiscriminatedPoints points = oldSeqLineCand.GetPoints(); + for(KTDiscriminatedPoints::const_iterator pointIt = points.begin(); pointIt != points.end(); ++pointIt ) { - return true; - } - // the other way around - condition4 = track1.GetEndTimeInRunC() <= track2.GetEndTimeInRunC() and track1.GetEndTimeInRunC() > track2.GetStartTimeInRunC(); - condition5 = std::abs(track1.GetEndFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetEndTimeInRunC() - track2.GetStartTimeInRunC()))) < fMaxTrackWidth; - condition6 = std::abs(track1.GetStartFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetStartTimeInRunC() - track2.GetStartTimeInRunC()))) < fMaxTrackWidth*5.0; + KTDEBUG( otclog, "Adding points from oldSeqLineCand to newSeqLineCand: "<fTimeInRunC<<" "<fFrequency<<" "<fAmplitude<<" "<fAmplitude ); - if (condition4 and condition5 and condition6) - { - return true; + newSeqLineCand.AddPoint(*pointIt); } - - return false; } /* @@ -301,63 +222,100 @@ namespace Katydid return false; }*/ - void KTOverlappingTrackClustering::EmitTrackCandidates() + void KTOverlappingTrackClustering::EmitCandidates(std::vector& compTracks) { - KTDEBUG(otclog, "Number of tracks to emit: "<::iterator trackIt = fCompTracks.begin(); + std::vector::iterator trackIt = compTracks.begin(); - while(trackIt!=fCompTracks.end()) + while(trackIt!=compTracks.end()) { - lineIsTrack = true; + // Set up new data object + Nymph::KTDataPtr data( new Nymph::KTData() ); + KTProcessedTrackData& newTrack = data->Of< KTProcessedTrackData >(); + newTrack.SetComponent( trackIt->GetComponent() ); + newTrack.SetAcquisitionID( trackIt->GetAcquisitionID() ); + newTrack.SetTrackID( fNTracks ); + fNTracks++; + + newTrack.SetStartTimeInRunC( trackIt->GetStartTimeInRunC() ); + newTrack.SetStartTimeInRunCSigma( trackIt->GetStartTimeInRunCSigma() ); + newTrack.SetEndTimeInRunC( trackIt->GetEndTimeInRunC() ); + newTrack.SetEndTimeInRunCSigma( trackIt->GetEndTimeInRunCSigma() ); + newTrack.SetStartTimeInAcq( trackIt->GetStartTimeInAcq() ); + newTrack.SetTimeLength( trackIt->GetTimeLength() ); + newTrack.SetTimeLengthSigma( trackIt->GetTimeLengthSigma() ); + newTrack.SetStartFrequency( trackIt->GetStartFrequency() ); + newTrack.SetStartFrequency( trackIt->GetStartFrequencySigma() ); + newTrack.SetEndFrequency( trackIt->GetEndFrequency() ); + newTrack.SetEndFrequencySigma( trackIt->GetEndFrequencySigma() ); + newTrack.SetSlope( trackIt->GetSlope() ); + newTrack.SetSlopeSigma( trackIt->GetSlopeSigma() ); + newTrack.SetTotalPower( trackIt->GetTotalPower() ); + newTrack.SetTotalPowerSigma( trackIt->GetTotalPowerSigma() ); + newTrack.SetFrequencyWidth( trackIt->GetFrequencyWidth() ); + newTrack.SetFrequencyWidthSigma( trackIt->GetFrequencyWidthSigma() ); + newTrack.SetIntercept( trackIt->GetFrequencyWidth() ); + newTrack.SetInterceptSigma( trackIt->GetInterceptSigma() ); + + newTrack.SetNTrackBins( trackIt->GetNTrackBins() ); + newTrack.SetTotalTrackSNR( trackIt->GetTotalTrackSNR() ); + newTrack.SetMaxTrackSNR( trackIt->GetMaxTrackSNR() ); + newTrack.SetTotalTrackNUP( trackIt->GetTotalTrackNUP() ); + newTrack.SetMaxTrackNUP( trackIt->GetMaxTrackNUP() ); + newTrack.SetTotalWideTrackSNR( trackIt->GetTotalWideTrackSNR() ); + newTrack.SetTotalWideTrackNUP( trackIt->GetTotalWideTrackNUP() ); + + // Process & emit new track + + KTINFO(otclog, "Now processing tracksCandidates"); + ProcessNewTrack( newTrack ); + + //KTDEBUG(otclog, "Emitting track signal"); + fCandidates.insert( data ); + fTrackSignal( data ); + + trackIt = compTracks.erase(trackIt); + } + } - if (fApplyPowerCut) - { - if (trackIt->GetTotalPower() <= fPowerThreshold) - { - KTDEBUG(otclog, "Track total power below threshold: "<GetTotalPower()<<" "<GetTotalPower()/(trackIt->GetEndTimeInRunC()-trackIt->GetStartTimeInRunC()) <= fDensityThreshold) - { - KTDEBUG(otclog, "Track power density below threshold: "<GetTotalPower()/(trackIt->GetEndTimeInRunC()-trackIt->GetStartTimeInRunC()) <<" "<< fDensityThreshold); - lineIsTrack = false; - } - } + void KTOverlappingTrackClustering::EmitCandidates(std::vector& compCands) + { + KTDEBUG(otclog, "Number of sequential line candidates to emit: "<()); + + std::vector::iterator candIt = compCands.begin(); + + while( candIt!=compCands.end() ) + { + + // Set up new data object + Nymph::KTDataPtr data( new Nymph::KTData() ); + KTSequentialLineData& newSeqLineCand = data->Of< KTSequentialLineData >(); + newSeqLineCand.SetComponent( candIt->GetComponent() ); + newSeqLineCand.SetAcquisitionID( candIt->GetAcquisitionID() ); + newSeqLineCand.SetCandidateID( fNTracks ); - if (lineIsTrack == true) + fNTracks++; + + newSeqLineCand.SetSlope(candIt->GetSlope()); + + KTDiscriminatedPoints& points = candIt->GetPoints(); + for(KTDiscriminatedPoints::const_iterator pointIt = points.begin(); pointIt != points.end(); ++pointIt ) { - // Set up new data object - Nymph::KTDataPtr data( new Nymph::KTData() ); - KTProcessedTrackData& newTrack = data->Of< KTProcessedTrackData >(); - newTrack.SetComponent( trackIt->GetComponent() ); - newTrack.SetAcquisitionID( trackIt->GetAcquisitionID()); - newTrack.SetTrackID(fNTracks); - fNTracks++; - - newTrack.SetStartTimeInRunC( trackIt->GetStartTimeInRunC()); - newTrack.SetEndTimeInRunC( trackIt->GetEndTimeInRunC()); - newTrack.SetStartTimeInAcq( trackIt->GetStartTimeInAcq()); - newTrack.SetStartFrequency( trackIt->GetStartFrequency()); - newTrack.SetEndFrequency( trackIt->GetEndFrequency()); - newTrack.SetSlope(trackIt->GetSlope()); - newTrack.SetTotalPower(trackIt->GetTotalPower()); - - - // Process & emit new track - - KTINFO(otclog, "Now processing tracksCandidates"); - ProcessNewTrack( newTrack ); - - KTDEBUG(otclog, "Emitting track signal"); - fTrackSignal( data ); + //KTDEBUG( otclog, "Adding points to newSeqLineCand: "<fTimeInRunC<<" "<fFrequency<<" "<fAmplitude<<" "<fNeighborhoodAmplitude ); + newSeqLineCand.AddPoint( *pointIt ); } - trackIt = fCompTracks.erase(trackIt); + newSeqLineCand.CalculateTotalPower(); + newSeqLineCand.CalculateTotalSNR(); + newSeqLineCand.CalculateTotalNUP(); + + fCandidates.insert( data ); + fSeqLineCandSignal( data ); + + candIt = compCands.erase(candIt); } } diff --git a/Source/EventAnalysis/KTOverlappingTrackClustering.hh b/Source/EventAnalysis/KTOverlappingTrackClustering.hh index 5746a4e43..ac4dd28e7 100644 --- a/Source/EventAnalysis/KTOverlappingTrackClustering.hh +++ b/Source/EventAnalysis/KTOverlappingTrackClustering.hh @@ -15,8 +15,11 @@ #include "KTData.hh" #include "KTMemberVariable.hh" #include "KTProcessedTrackData.hh" +#include "KTSequentialLineData.hh" +#include "KTDiscriminatedPoint.hh" #include +#include namespace Katydid { @@ -25,29 +28,29 @@ namespace Katydid @class KTOverlappingLineClustering @author C. Claessens - @brief Clusters tracks together until number of lines stops decreasing + @brief Clusters tracks together until number of tracks stops decreasing. @details Checks whether tracks start/ends are very close to another track or whether tracks cross. - This step is necessary for dans algorithm, because for a wide of slightly curved track it often finds several parallel track segments + Can work with KTProcessedTrackData or KTSequentialLineData Configuration name: "overlapping-track-clustering" Available configuration values: - - "max-track-width": tracks that are not further apart than this value in frequency will be grouped together to a combined track - - "apply-power-cut": default is false - - "apply-power-density-cut": default is false - - "power-threshold": total track power must be above this threshold - - "power-density-threshold": total power/second threshold + - "max-track-width": if the start- or end point of a track is closer than this value (in frequency) the tracks are combined to one... + - "large-max-track-width": if their largest distance in frequency is not greater than this Slots: - - "track": void (shared_ptr) -- If this is a new acquisition; Adds tracks to the internally-stored set of points; Requires KTProcessedTrackData. + - "track": void (KTDataPtr) -- Collects incoming KTProcessedTrackData objects. Clustering will produces new data pointer with KTProcessedTrackData + - "swf-cand": void (KTDataPtr) -- Collects incoming KTSequentialLineData objects. Clustering will produced new data pointer with KTSequentialLineData - "do-clustering": void () -- Triggers clustering algorithm Signals: - - "track": void (shared_ptr) -- Emitted for each group found; Guarantees KTProcessedTrackData. - - "clustering-done": void () -- Emitted when track clustering is complete + - "track": void (KTDataPtr) -- Created and emitted for each group found; Guarantees KTProcessedTrackData. + - "swf-cand: void (KTDataPtr) -- Created and emitted for each group found; Guarantees KTSequentialLineData. + - "clustering-done": void () -- Emitted when clustering is complete */ + KTLOGGER(otchlog, "KTOverlappingTrackClusteringHeader"); class KTOverlappingTrackClustering : public Nymph::KTPrimaryProcessor { @@ -56,39 +59,45 @@ namespace Katydid virtual ~KTOverlappingTrackClustering(); bool Configure(const scarab::param_node* node); + bool TakeTrack(KTProcessedTrackData& track); + bool TakeSeqLineCandidate(KTSequentialLineData& swfCand); + bool Run(); + const std::set< Nymph::KTDataPtr >& GetCandidates() const; + + private: MEMBERVARIABLE(double, MaxTrackWidth); - MEMBERVARIABLE(bool, ApplyPowerCut); - MEMBERVARIABLE(bool, ApplyDensityCut); - MEMBERVARIABLE(double, PowerThreshold); - MEMBERVARIABLE(double, DensityThreshold); + MEMBERVARIABLE(double, LargeMaxTrackWidth); MEMBERVARIABLE(unsigned, NTracks); - public: - // Store point information locally - bool TakeTrack(KTProcessedTrackData& track); + private: + template + bool DoCandidateClustering(std::vector& compCands, std::vector& newCands); - //void SetNComponents(unsigned nComps); - bool DoClustering(); - bool Run(); + template + bool FindMatchingCandidates(std::vector& compCands, std::vector& newCands); + template + bool OverlapClustering(std::vector& compCands, std::vector& newCands); - private: - bool OverlapClustering(); - bool DoTheyOverlap(KTProcessedTrackData& track1, KTProcessedTrackData& track2); - bool DoTheyCross(KTProcessedTrackData& track1, KTProcessedTrackData& track2); - const void CombineTracks(const KTProcessedTrackData& track1, KTProcessedTrackData& track2); - bool FindMatchingTracks(); - void EmitTrackCandidates(); + template + bool DoTheyOverlap(TracklikeCandidate& track1, TracklikeCandidate& track2); + + const void CombineCandidates(const KTProcessedTrackData& track1, KTProcessedTrackData& track2); + const void CombineCandidates(const KTSequentialLineData& track1, KTSequentialLineData& track2); + void EmitCandidates(std::vector& compTracks); + void EmitCandidates(std::vector& compCands); const void ProcessNewTrack( KTProcessedTrackData& myNewTrack ); - //std::vector< TrackSet > fCompTracks; // input tracks - //std::vector< TrackSet> fNewTracks; std::vector fCompTracks; std::vector fNewTracks; + std::vector fCompSeqLineCands; + std::vector fNewSeqLineCands; + + std::set< Nymph::KTDataPtr > fCandidates; //*************** // Signals @@ -96,6 +105,7 @@ namespace Katydid private: Nymph::KTSignalData fTrackSignal; + Nymph::KTSignalData fSeqLineCandSignal; Nymph::KTSignalOneArg< void > fDoneSignal; //*************** @@ -104,10 +114,153 @@ namespace Katydid private: Nymph::KTSlotDataOneType< KTProcessedTrackData > fTakeTrackSlot; + Nymph::KTSlotDataOneType< KTSequentialLineData > fTakeSeqLineCandSlot; void DoClusteringSlot(); }; + inline const std::set< Nymph::KTDataPtr >& KTOverlappingTrackClustering::GetCandidates() const + { + return fCandidates; + } + + template + bool KTOverlappingTrackClustering::DoCandidateClustering(std::vector& compCands, std::vector& newCands) + { + if (! FindMatchingCandidates(compCands, newCands)) + { + KTERROR(otchlog, "An error occurred while identifying overlapping tracks"); + return false; + } + + KTDEBUG(otchlog, "Track clustering complete"); + fDoneSignal(); + + return true; + } + + template + bool KTOverlappingTrackClustering::FindMatchingCandidates(std::vector& compCands, std::vector& newCands) + { + KTINFO( otchlog, "Finding overlapping candidates" ); + KTDEBUG( otchlog, "FrequencyAcceptance is: "< 1) + { + while (numberOfCands!=numberOfNewCands) + { + numberOfCands = compCands.size(); + KTDEBUG(otchlog, "Number of candidates to cluster: "<< numberOfCands); + this->OverlapClustering(compCands, newCands); + + // Update number of tracks + numberOfNewCands = newCands.size(); + + KTDEBUG(otchlog, "Number of candidates after clustering: "<< numberOfNewCands); + + compCands.clear(); + compCands = newCands; + newCands.clear(); + } + } + + this->EmitCandidates(compCands); + + return true; + } + + + template + bool KTOverlappingTrackClustering::OverlapClustering(std::vector& compCands, std::vector& newCands) + { + bool match = false; + for (typename std::vector::iterator compIt = compCands.begin(); compIt != compCands.end(); ++compIt) + { + match = false; + for (typename std::vector::iterator newIt = newCands.begin(); newIt != newCands.end(); ++newIt) + { + if (this->DoTheyOverlap(*compIt, *newIt)) + { + match = true; + KTDEBUG(otchlog, "Found overlapping candidates") + this->CombineCandidates(*compIt, *newIt); + break; + } + + // since there appear to be real tracks crossing each other this check is removed here + /*if (this->DoTheyCross(*compIt, *newIt)) + { + match = true; + KTDEBUG(otchlog, "Found crossing tracks") + this->CombineTracks(*compIt, *newIt); + break; + }*/ + } + + if (match == false) + { + //T newTrack(*compIt); + newCands.push_back(*compIt); + } + } + return true; + } + + template + bool KTOverlappingTrackClustering::DoTheyOverlap(TracklikeCandidate& track1, TracklikeCandidate& track2) + { + // if there are two tracks that should be just one, any point of the track will be close to the other track (extrapolated) + // therefore it is enough to check start and endpoint of a track. one should overlap in time, both should be close in frequency + + // if the start time of track 2 is between start and end time of track 1 + bool condition1 = track2.GetStartTimeInRunC() < track1.GetEndTimeInRunC() and track2.GetStartTimeInRunC() >= track1.GetStartTimeInRunC(); + + // and the start frequency of track 2 is too close to track 1 + bool condition2 = std::abs(track2.GetStartFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetStartTimeInRunC() - track1.GetStartTimeInRunC()))) < fMaxTrackWidth; + + // same for endpoint + bool condition3 = std::abs(track2.GetEndFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetEndTimeInRunC() - track1.GetStartTimeInRunC()))) < fLargeMaxTrackWidth; + + if (condition1 and condition2 and condition3) + { + return true; + } + // the other way around + bool condition4 = track1.GetStartTimeInRunC() < track2.GetEndTimeInRunC() and track1.GetStartTimeInRunC() >= track2.GetStartTimeInRunC(); + bool condition5 = std::abs(track1.GetStartFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetStartTimeInRunC() - track2.GetStartTimeInRunC()))) < fMaxTrackWidth; + bool condition6 = std::abs(track1.GetEndFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetEndTimeInRunC() - track2.GetStartTimeInRunC()))) < fLargeMaxTrackWidth; + + if (condition4 and condition5 and condition6) + { + return true; + } + // same for end point of track2 + condition1 = track2.GetEndTimeInRunC() <= track1.GetEndTimeInRunC() and track2.GetEndTimeInRunC() > track1.GetStartTimeInRunC(); + condition2 = std::abs(track2.GetEndFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetEndTimeInRunC() - track1.GetStartTimeInRunC()))) < fMaxTrackWidth; + condition3 = std::abs(track2.GetStartFrequency() - (track1.GetStartFrequency() + track1.GetSlope() * (track2.GetStartTimeInRunC() - track1.GetStartTimeInRunC()))) < fLargeMaxTrackWidth; + + if (condition1 and condition2 and condition3) + { + return true; + } + // the other way around + condition4 = track1.GetEndTimeInRunC() <= track2.GetEndTimeInRunC() and track1.GetEndTimeInRunC() > track2.GetStartTimeInRunC(); + condition5 = std::abs(track1.GetEndFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetEndTimeInRunC() - track2.GetStartTimeInRunC()))) < fMaxTrackWidth; + condition6 = std::abs(track1.GetStartFrequency() - (track2.GetStartFrequency() + track2.GetSlope() * (track1.GetStartTimeInRunC() - track2.GetStartTimeInRunC()))) < fLargeMaxTrackWidth; + + if (condition4 and condition5 and condition6) + { + return true; + } + + return false; + } } /* namespace Katydid */ diff --git a/Source/EventAnalysis/KTSequentialLineNUPCut.cc b/Source/EventAnalysis/KTSequentialLineNUPCut.cc new file mode 100644 index 000000000..054209db1 --- /dev/null +++ b/Source/EventAnalysis/KTSequentialLineNUPCut.cc @@ -0,0 +1,89 @@ +/* + * KTSequentialLineNUPCut.cc + * + * Created on: June 13, 2018 + * Author: C. Claessens + */ + +#include "KTSequentialLineNUPCut.hh" +#include "KTSequentialLineData.hh" + +#include "KTLogger.hh" + +namespace Katydid +{ + KTLOGGER(sqlcutlog, "KTSequentialLineNUPCut"); + + const std::string KTSequentialLineNUPCut::Result::sName = "seq-line-nup-cut"; + + KT_REGISTER_CUT(KTSequentialLineNUPCut); + + KTSequentialLineNUPCut::KTSequentialLineNUPCut(const std::string& name) : + KTCutOneArg(name), + fMinTotalNUP(0.0), + fMinAverageNUP(0.0), + fWideOrNarrowLine( wide_or_narrow::wide ) + {} + + KTSequentialLineNUPCut::~KTSequentialLineNUPCut() + {} + + bool KTSequentialLineNUPCut::Configure(const scarab::param_node* node) + { + if (node == NULL) return true; + + SetMinTotalNUP( node->get_value< double >( "min-total-nup", GetMinTotalNUP() ) ); + SetMinAverageNUP( node->get_value< double >( "min-average-nup", GetMinAverageNUP() ) ); + if (node->has("wide-or-narrow")) + { + if (node->get_value("wide-or-narrow") == "wide") + { + SetWideOrNarrowLine(wide_or_narrow::wide); + } + else if (node->get_value("wide-or-narrow") == "narrow") + { + SetWideOrNarrowLine(wide_or_narrow::narrow); + } + else + { + KTERROR(sqlcutlog, "Invalid string for fWideOrNarrow"); + return false; + } + } + return true; + } + + bool KTSequentialLineNUPCut::Apply( Nymph::KTData& data, KTSequentialLineData& seqLineData ) + { + bool isCut = false; + //seqLineData.CalculateTotalNUP(); + + if (fWideOrNarrowLine == wide_or_narrow::narrow) + { + if( seqLineData.GetTotalNUP() < GetMinTotalNUP() ) + { + isCut = true; + } + if( seqLineData.GetTotalNUP() / ( seqLineData.GetEndTimeInRunC() - seqLineData.GetStartTimeInRunC() ) < GetMinAverageNUP() ) + { + isCut = true; + } + } + else + { + if( seqLineData.GetTotalWideNUP() < GetMinTotalNUP() ) + { + isCut = true; + } + if( seqLineData.GetTotalWideNUP() / ( seqLineData.GetEndTimeInRunC() - seqLineData.GetStartTimeInRunC() ) < GetMinAverageNUP() ) + { + isCut = true; + } + } + + data.GetCutStatus().AddCutResult< KTSequentialLineNUPCut::Result >(isCut); + + return isCut; + } + +} // namespace Katydid diff --git a/Source/EventAnalysis/KTSequentialLineNUPCut.hh b/Source/EventAnalysis/KTSequentialLineNUPCut.hh new file mode 100644 index 000000000..d4e51aa09 --- /dev/null +++ b/Source/EventAnalysis/KTSequentialLineNUPCut.hh @@ -0,0 +1,67 @@ +/* + * KTSequentialLineNUPCut.hh + * + * Created on: June 13, 2018 + * Author: C. Claessens + */ + +#ifndef KTSEQUENTIALLINENUPCUT_HH_ +#define KTSEQUENTIALLINENUPCUT_HH_ + +#include "KTCut.hh" + +namespace Katydid +{ + + class KTSequentialLineData; + + /* + @class KTSequentialLineNUPCut + @author C. Claessens + + @brief Cuts on total and average NUP of KTSequentialLineData + + @details + KTSequentialLineData objects must have an NUP and average NUP above a set value to pass the cut + + Configuration name: "sq-line-nup-cut" + + Available configuration values: + - "min-total-nup": double -- minimum summed NUP to accept + - "min-average-nup": double -- minimum average NUP to accept + - "wide-or-narrow": string -- decides whether to use "wide" NUP or "narrow" NUP (default: "wide") + */ + + class KTSequentialLineNUPCut : public Nymph::KTCutOneArg< KTSequentialLineData > + { + + private: + enum class wide_or_narrow + { + wide, + narrow + }; + + public: + struct Result : Nymph::KTExtensibleCutResult< Result > + { + static const std::string sName; + }; + + public: + KTSequentialLineNUPCut(const std::string& name = "seq-line-nup-cut"); + ~KTSequentialLineNUPCut(); + + bool Configure(const scarab::param_node* node); + + MEMBERVARIABLE(double, MinTotalNUP); + MEMBERVARIABLE(double, MinAverageNUP); + MEMBERVARIABLE(wide_or_narrow, WideOrNarrowLine); + + public: + bool Apply(Nymph::KTData& data, KTSequentialLineData& seqLineData); + + }; +} // namespace Katydid + +#endif /* KTSequentialLineNUPCut_HH_ */ diff --git a/Source/EventAnalysis/KTSequentialLineSNRCut.cc b/Source/EventAnalysis/KTSequentialLineSNRCut.cc new file mode 100644 index 000000000..ee0a6fb27 --- /dev/null +++ b/Source/EventAnalysis/KTSequentialLineSNRCut.cc @@ -0,0 +1,89 @@ +/* + * KTSequentialLineSNRCut.cc + * + * Created on: June 13, 2018 + * Author: C. Claessens + */ + +#include "KTSequentialLineSNRCut.hh" +#include "KTSequentialLineData.hh" + +#include "KTLogger.hh" + +namespace Katydid +{ + KTLOGGER(sqlcutlog, "KTSequentialLineSNRCut"); + + const std::string KTSequentialLineSNRCut::Result::sName = "seq-line-snr-cut"; + + KT_REGISTER_CUT(KTSequentialLineSNRCut); + + KTSequentialLineSNRCut::KTSequentialLineSNRCut(const std::string& name) : + KTCutOneArg(name), + fMinTotalSNR(0.0), + fMinAverageSNR(0.0), + fWideOrNarrowLine( wide_or_narrow::wide ) + {} + + KTSequentialLineSNRCut::~KTSequentialLineSNRCut() + {} + + bool KTSequentialLineSNRCut::Configure(const scarab::param_node* node) + { + if (node == NULL) return true; + + SetMinTotalSNR( node->get_value< double >( "min-total-snr", GetMinTotalSNR() ) ); + SetMinAverageSNR( node->get_value< double >( "min-average-snr", GetMinAverageSNR() ) ); + if (node->has("wide-or-narrow")) + { + if (node->get_value("wide-or-narrow") == "wide") + { + SetWideOrNarrowLine(wide_or_narrow::wide); + } + else if (node->get_value("wide-or-narrow") == "narrow") + { + SetWideOrNarrowLine(wide_or_narrow::narrow); + } + else + { + KTERROR(sqlcutlog, "Invalid string for fWideOrNarrow"); + return false; + } + } + return true; + } + + bool KTSequentialLineSNRCut::Apply( Nymph::KTData& data, KTSequentialLineData& seqLineData ) + { + bool isCut = false; + //seqLineData.CalculateTotalSNR(); + + if (fWideOrNarrowLine == wide_or_narrow::narrow) + { + if( seqLineData.GetTotalSNR() < GetMinTotalSNR() ) + { + isCut = true; + } + if( seqLineData.GetTotalSNR() / ( seqLineData.GetEndTimeInRunC() - seqLineData.GetStartTimeInRunC() ) < GetMinAverageSNR() ) + { + isCut = true; + } + } + else + { + if( seqLineData.GetTotalWideSNR() < GetMinTotalSNR() ) + { + isCut = true; + } + if( seqLineData.GetTotalWideSNR() / ( seqLineData.GetEndTimeInRunC() - seqLineData.GetStartTimeInRunC() ) < GetMinAverageSNR() ) + { + isCut = true; + } + } + + data.GetCutStatus().AddCutResult< KTSequentialLineSNRCut::Result >(isCut); + + return isCut; + } + +} // namespace Katydid diff --git a/Source/EventAnalysis/KTSequentialLineSNRCut.hh b/Source/EventAnalysis/KTSequentialLineSNRCut.hh new file mode 100644 index 000000000..2ce7da210 --- /dev/null +++ b/Source/EventAnalysis/KTSequentialLineSNRCut.hh @@ -0,0 +1,67 @@ +/* + * KTSequentialLineSNRCut.hh + * + * Created on: June 13, 2018 + * Author: C. Claessens + */ + +#ifndef KTSEQUENTIALLINESNRCUT_HH_ +#define KTSEQUENTIALLINESNRCUT_HH_ + +#include "KTCut.hh" + +namespace Katydid +{ + + class KTSequentialLineData; + + /* + @class KTSequentialLineSNRCut + @author C. Claessens + + @brief Cuts on total and average SNR of KTSequentialLineData + + @details + KTSequentialLineData objects must have an SNR and average SNR above a set value to pass the cut + + Configuration name: "sq-line-snr-cut" + + Available configuration values: + - "min-total-snr": double -- minimum summed SNR to accept + - "min- average-snr": double -- minimum average SNR to accept + - "wide-or-narrow": string -- decides whether to use "wide" SNR or "narrow" SNR (default: "wide") + */ + + class KTSequentialLineSNRCut : public Nymph::KTCutOneArg< KTSequentialLineData > + { + + private: + enum class wide_or_narrow + { + wide, + narrow + }; + + public: + struct Result : Nymph::KTExtensibleCutResult< Result > + { + static const std::string sName; + }; + + public: + KTSequentialLineSNRCut(const std::string& name = "seq-line-snr-cut"); + ~KTSequentialLineSNRCut(); + + bool Configure(const scarab::param_node* node); + + MEMBERVARIABLE(double, MinTotalSNR); + MEMBERVARIABLE(double, MinAverageSNR); + MEMBERVARIABLE(wide_or_narrow, WideOrNarrowLine); + + public: + bool Apply(Nymph::KTData& data, KTSequentialLineData& seqLineData); + + }; +} // namespace Katydid + +#endif /* KTSequentialLineSNRCut_HH_ */ diff --git a/Source/EventAnalysis/KTTrackProcessing.cc b/Source/EventAnalysis/KTTrackProcessing.cc deleted file mode 100644 index 4575218dc..000000000 --- a/Source/EventAnalysis/KTTrackProcessing.cc +++ /dev/null @@ -1,431 +0,0 @@ -/* - * KTTrackProcessing.cc - * - * Created on: July 22, 2013 - * Author: N.S. Oblath & B. LaRoque - */ - -#include "KTTrackProcessing.hh" - -#include "KTHoughData.hh" -#include "KTLogger.hh" - -#include "KTProcessedTrackData.hh" -#include "KTSmooth.hh" -#include "KTSparseWaterfallCandidateData.hh" - -#include -#include -#include - -using boost::shared_ptr; -using std::vector; -using std::string; - -namespace Katydid -{ - KTLOGGER(tlog, "katydid.fft"); - - // Register the processor - KT_REGISTER_PROCESSOR(KTTrackProcessing, "track-proc"); - - KTTrackProcessing::KTTrackProcessing(const std::string& name) : - KTProcessor(name), - fPointLineDistCut1(0.1), - fPointLineDistCut2(0.05), - fSlopeMinimum(-std::numeric_limits< double >::max()), - fProcTrackMinPoints(0), - fProcTrackAssError(0.), - fTrackSignal("track", this), - fTrackProcPtr(&KTTrackProcessing::ProcessTrackDoubleCuts), - fSWFAndHoughSlot("swfc-and-hough", this, &KTTrackProcessing::ProcessTrack, &fTrackSignal) - { - } - - KTTrackProcessing::~KTTrackProcessing() - { - } - - bool KTTrackProcessing::Configure(const scarab::param_node* node) - { - if (node == NULL) return false; - - SetPointLineDistCut1(node->get_value("pl-dist-cut1", GetPointLineDistCut1())); - SetPointLineDistCut2(node->get_value("pl-dist-cut2", GetPointLineDistCut2())); - - SetSlopeMinimum(node->get_value("min-slope", GetSlopeMinimum())); - SetProcTrackMinPoints(node->get_value("min-points", GetProcTrackMinPoints())); - SetProcTrackAssignedError(node->get_value("assigned-error", GetProcTrackAssignedError())); - - if (node->has("algorithm")) - { - KTDEBUG(tlog, "Making track reconstruction"); - - string procTrackAlgorithm(node->get_value("algorithm")); - if (procTrackAlgorithm == "double-cuts") - { - KTDEBUG(tlog, "Making track reconstruction using \"double-cuts\" algorithm"); - fTrackProcPtr = &KTTrackProcessing::ProcessTrackDoubleCuts; - } - else if (procTrackAlgorithm == "weighted-slope") - { - KTDEBUG(tlog, "Setting track reconstruction using \"weighted-slope\" algorithm"); - fTrackProcPtr = &KTTrackProcessing::ProcessTrackWeightedSlope; - } - else - { - KTERROR(tlog, "Invalid value for \"track-slope\": <" << procTrackAlgorithm << ">"); - return false; - } - } - - return true; - } - - bool KTTrackProcessing::ProcessTrack(KTSparseWaterfallCandidateData& swfData, KTHoughData& htData) - { - KTDEBUG(tlog, "Track processing"); - return (this->*fTrackProcPtr)(swfData,htData); - } - - bool KTTrackProcessing::ProcessTrackDoubleCuts(KTSparseWaterfallCandidateData& swfData, KTHoughData& htData) - { - unsigned component = swfData.GetComponent(); - unsigned trackID = swfData.GetCandidateID(); - - typedef KTSparseWaterfallCandidateData::Points Points; - // not const because points will be removed later - Points& points = swfData.GetPoints(); - - // not const because the HT will be smoothed in place - KTPhysicalArray< 2, double >* houghTransform = htData.GetTransform(component); - - // NOTE: smoothes the actual data, not a copy - if (! KTSmooth::Smooth(houghTransform)) - { - KTERROR(tlog, "Error while smoothing Hough Transform"); - return false; - } - - unsigned maxBinX, maxBinY; - houghTransform->GetMaximumBin(maxBinX, maxBinY); - - double htAngle = houghTransform->GetBinCenter(1, maxBinX); - double htRadius = houghTransform->GetBinCenter(2, maxBinY); - - // Hough line: a*x + b*y + c = 0, c = -radius - double htCosAngle = cos(htAngle); // ht_a - double htSinAngle = sin(htAngle); // ht_b - - // scaling for Hough Transform, used throughout for line fits and modifications - // "scaled" means the axis has been scaled to 0-1, as was the case when the Hough Transform was calculated - // "unscaled" means the axis is in the original units - // unscaled = scaled * scale + offset - double xScale = htData.GetXScale(component); - double yScale = htData.GetYScale(component); - double xOffset = htData.GetXOffset(component); - double yOffset = htData.GetYOffset(component); - - double htSlope = -1.0 * (htCosAngle * yScale) / (htSinAngle * xScale); - double htIntercept = (htRadius / htSinAngle) * yScale + yOffset - htSlope * xOffset; // this is r/sin(angle), rescaled, plus extra from the xOffset - - KTDEBUG(tlog, "Hough Transform track processing results:\n" - << "\tmaxBinX: " << maxBinX << "\t maxBinY: " << maxBinY << "\t angle: " << htAngle << "\t radius: " << htRadius << '\n' - << "\ta=cos(angle): " << htCosAngle << "\t b=sin(angle): " << htSinAngle << '\n' - << "\txScale: " << xScale << "\t yScale: " << yScale << '\n' - << "\tSlope: " << htSlope << " Hz/s" << '\n' - << "\tIntercept: " << htIntercept << " Hz"); - - // First loop over points, and first point-line-distance cut - - unsigned nPoints = points.size(); - typedef vector< std::pair< double, double > > SimplePoints2D; - SimplePoints2D pointsScaled, pointsUnscaled, pointsUnscaledInAcq; - pointsScaled.reserve(nPoints); - pointsUnscaledInAcq.reserve(nPoints); - vector< unsigned > pointsCuts; - pointsCuts.reserve(nPoints); - unsigned nPointsUsed = 0; - unsigned nPointsCut1 = 0; - double xScaled, yScaled, distance; - double sumX = 0., sumY = 0., sumX2 = 0., sumXY = 0.; // for least-squares calculation - // first distance cut, plus calculation of the initial least-squares line calculations - for (Points::const_iterator pIt = points.begin(); pIt != points.end(); ++pIt) - { - //cout << "calculating a distance..." << endl; - pointsUnscaled.push_back(SimplePoints2D::value_type(pIt->fTimeInRunC, pIt->fFrequency)); - pointsUnscaledInAcq.push_back(SimplePoints2D::value_type(pIt->fTimeInAcq, pIt->fFrequency)); - xScaled = (pIt->fTimeInRunC - xOffset) / xScale; - yScaled = (pIt->fFrequency - yOffset) / yScale; - pointsScaled.push_back(SimplePoints2D::value_type(xScaled, yScaled)); - //cout << "i: " << iPoint << "\t y_i: " << ys[iPoint] << "\t x_i: " << xs[iPoint] << endl; - //cout << "scaled: y_isc: " << yiscaled << "\t xisc: " << xiscaled << endl; - distance = PointLineDistance(xScaled, yScaled, htCosAngle, htSinAngle, -htRadius); - //cout << "distance: " << distance << endl; - - if (distance < fPointLineDistCut1 ) - { - // point is not cut - ++nPointsUsed; - sumX += xScaled; - sumY += yScaled; - sumX2 += xScaled * xScaled; - sumXY += xScaled * yScaled; - pointsCuts.push_back(0); - } - else - { - // point is cut - ++nPointsCut1; - pointsCuts.push_back(1); - } - } // loop over points - KTDEBUG(tlog, "Points removed with cut 1: " << nPointsCut1); - - // Refine the line with a least-squares line calculation - double xMean = sumX / (double)nPointsUsed; - double yMean = sumY / (double)nPointsUsed; - double lsSlopeScaled = (sumXY - sumX * yMean) / (sumX2 - sumX * xMean); - double lsInterceptScaled = yMean - lsSlopeScaled * xMean; - double lsSlope = lsSlopeScaled * yScale / xScale; - double lsIntercept = lsInterceptScaled * yScale + yOffset - lsSlope * xOffset; - KTDEBUG(tlog, "Least-squares fit result\n" - << "\tSlope: " << lsSlope << " Hz/s\n" - << "\tIntercept: " << lsIntercept << " Hz"); - - // second distance cut based on LS fit - double startTime = std::numeric_limits< double >::max(); - double stopTime = -1.; - double startTimeInAcq = 0; - double startFreq, stopFreq; - nPointsUsed = 0; - unsigned nPointsCut2 = 0; - for (unsigned iPoint = 0; iPoint < nPoints; ++iPoint) - { - distance = PointLineDistance(pointsScaled[iPoint].first, pointsScaled[iPoint].second, lsSlopeScaled, -1., lsInterceptScaled);; - - if (pointsCuts[iPoint] == 0 && distance < fPointLineDistCut2) - { - // point is not cut - ++nPointsUsed; - if (pointsUnscaled[iPoint].first < startTime) //possibly update start time/frequency - { - startTime = pointsUnscaled[iPoint].first; - startFreq = startTime * lsSlope + lsIntercept; - startTimeInAcq = pointsUnscaledInAcq[iPoint].first; - } - if (pointsUnscaled[iPoint].first > stopTime) - { //possibly update stop time/frequency - stopTime = pointsUnscaled[iPoint].first; - stopFreq = stopTime * lsSlope + lsIntercept; - } - } - else if (pointsCuts[iPoint] == 0) - { - // point is cut - ++nPointsCut2; - pointsCuts[iPoint] = 2; - } - } - KTDEBUG(tlog, "Points removed with cut 2: " << nPointsCut2); - - // Remove points and sum amplitudes - Points::iterator pItMaster = points.begin(); - Points::iterator pItCache; - double amplitudeSum = 0.; - for (unsigned iPoint = 0; iPoint < nPoints; ++iPoint) - { - pItCache = pItMaster; - ++pItMaster; - if (pointsCuts[iPoint] == 0) - { - amplitudeSum += pItCache->fAmplitude; - } - else - { - points.erase(pItCache); - } - } - KTDEBUG(tlog, "Points present after cuts: " << points.size()); - - // Add the new data - KTProcessedTrackData& procTrack = htData.Of< KTProcessedTrackData >(); - procTrack.SetComponent(component); - procTrack.SetAcquisitionID(swfData.GetAcquisitionID()); - procTrack.SetTrackID(trackID); - - if (lsSlope < fSlopeMinimum || points.size() < fProcTrackMinPoints) - { - procTrack.SetIsCut(true); - } - - procTrack.SetStartTimeInAcq(startTimeInAcq); - procTrack.SetStartTimeInRunC(startTime); - procTrack.SetEndTimeInRunC(stopTime); - procTrack.SetTimeLength(stopTime - startTime); - procTrack.SetStartFrequency(startFreq); - procTrack.SetEndFrequency(stopFreq); - procTrack.SetFrequencyWidth(std::abs(stopFreq - startFreq)); - procTrack.SetSlope(lsSlope); - procTrack.SetIntercept(lsIntercept); - procTrack.SetTotalPower(amplitudeSum); - //TODO: Add calculation of uncertainties - - return true; - } - - - bool KTTrackProcessing::ProcessTrackWeightedSlope(KTSparseWaterfallCandidateData& swfData, KTHoughData& htData) - { - unsigned component = swfData.GetComponent(); - unsigned trackID = swfData.GetCandidateID(); - - typedef KTSparseWaterfallCandidateData::Points Points; - // not const because points will be removed later - Points& points = swfData.GetPoints(); - - // Makes a first loop over the points to calculate the weighted average in one time slice - vector< double > timeBinInAcq; - vector< double > timeBinInRunC; - vector< double > sumPf; - vector< double > sumP; - vector< double > average; - - for (Points::const_iterator pIt = points.begin(); pIt != points.end(); ++pIt) - { - bool addToList = true; - for (unsigned iTimeBin=0; iTimeBinfTimeInAcq == timeBinInAcq[iTimeBin]) - { - addToList = false; - KTDEBUG(tlog, "Duplicate time: " << pIt->fTimeInAcq << '\t' << pIt->fTimeInRunC); - break; - } - } - if (addToList) - { - KTDEBUG(tlog, "Adding Time: " << pIt->fTimeInAcq << '\t' << pIt->fTimeInRunC); - timeBinInAcq.push_back(pIt->fTimeInAcq); - timeBinInRunC.push_back(pIt->fTimeInRunC); - } - } - - for (unsigned iTimeBin = 0; iTimeBinfTimeInAcq == timeBinInAcq[iTimeBin]) - { - sumPf[iTimeBin] += pIt->fFrequency * pIt->fAmplitude; - sumP[iTimeBin] += pIt->fAmplitude; - } - } - } - - KTDEBUG(tlog, "Averaging"); - for (unsigned iTimeBin = 0; iTimeBin2) - { - KTDEBUG(tlog, "Chi2min : " << chi2min ); - - if (chi2min < 0.1) - { - KTDEBUG(tlog, "Chi2min too small (points are mostlikely aligned): assigning arbitrary errors to the averaged points (" << fProcTrackAssError << ")"); - deltaSlope = 1.52/(sqrt(sumXX)/fProcTrackAssError); - deltaIntercept = 1.52/(sqrt(sumOne)/fProcTrackAssError); - } - else - { - double ndf = timeBinInAcq.size() - 2; // 2: two fitting parameters - deltaSlope = 1.52/sqrt(sumXX*ndf/chi2min); - deltaIntercept = 1.52/sqrt(sumOne*ndf/chi2min); - } - KTDEBUG(tlog, "Error calculations results: \n" << - "\tSlope: " << '\t' << deltaSlope << '\n' << - "\tIntercept: " << '\t' << deltaIntercept << '\n' << - "\tCorrelation coefficifent: " << '\t' << rho); - //Calculating error on the starting frequency and the end frequency - double startTime = *std::min_element(timeBinInAcq.begin(), timeBinInAcq.end()); - double endTime = *std::max_element(timeBinInAcq.begin(), timeBinInAcq.end()); - sigmaStartFreq = sqrt( startTime*startTime * deltaSlope*deltaSlope + deltaIntercept*deltaIntercept + 2 * startTime * rho * deltaSlope * deltaIntercept ); - sigmaEndFreq = sqrt( endTime*endTime * deltaSlope*deltaSlope + deltaIntercept*deltaIntercept + 2 * endTime * rho * deltaSlope * deltaIntercept ); - } - - // TODO: Calculate distance to track and see for a possible alpha [%] rejection of noise. - - // Adding resuts to ProcessedTrackData object - KTProcessedTrackData& procTrack = htData.Of< KTProcessedTrackData >(); - procTrack.SetComponent(component); - procTrack.SetAcquisitionID(swfData.GetAcquisitionID()); - procTrack.SetTrackID(trackID); - - procTrack.SetStartTimeInAcq(*std::min_element(timeBinInAcq.begin(), timeBinInAcq.end())); - procTrack.SetStartTimeInRunC(*std::min_element(timeBinInRunC.begin(), timeBinInRunC.end())); - procTrack.SetEndTimeInRunC(*std::max_element(timeBinInRunC.begin(), timeBinInRunC.end())); - procTrack.SetTimeLength(procTrack.GetEndTimeInRunC() - procTrack.GetStartTimeInRunC()); - procTrack.SetStartFrequency(procTrack.GetStartTimeInAcq() * slope + intercept); - procTrack.SetEndFrequency((procTrack.GetStartTimeInAcq() + procTrack.GetTimeLength()) * slope + intercept); - procTrack.SetFrequencyWidth(std::abs(procTrack.GetEndFrequency() - procTrack.GetStartFrequency())); - procTrack.SetSlope(slope); - procTrack.SetIntercept(intercept); - procTrack.SetTotalPower(amplitudeSum); - if (!(slope > fSlopeMinimum)) - { - procTrack.SetIsCut(true); - } - procTrack.SetSlopeSigma(deltaSlope); - procTrack.SetInterceptSigma(deltaIntercept); - procTrack.SetStartFrequencySigma(sigmaStartFreq); - procTrack.SetEndFrequencySigma(sigmaEndFreq); - - return true; - } -} /* namespace Katydid */ diff --git a/Source/EventAnalysis/KTTrackProcessing.hh b/Source/EventAnalysis/KTTrackProcessing.hh deleted file mode 100644 index 96cc13a64..000000000 --- a/Source/EventAnalysis/KTTrackProcessing.hh +++ /dev/null @@ -1,166 +0,0 @@ -/** - @file KTTrackProcessing.hh - @brief Contains KTTrackProcessing - @details Extracts physics-relevant information about tracks - @author: N.S. Oblath & B. LaRoque - @date: July 22, 2013 - */ - -#ifndef KTTRACKPROCESSING_HH_ -#define KTTRACKPROCESSING_HH_ - -#include "KTProcessor.hh" - -#include "KTSlot.hh" - -#include - - -namespace Katydid -{ - - class KTHoughData; - class KTSparseWaterfallCandidateData; - - /*! - @class KTTrackProcessing - @author N.S. Oblath & B. LaRoque - - @brief Extracts physics-relevant information about tracks - - @details - - Configuration name: "track-proc" - - Available configuration values: - - "algorithm": string -- Select the track processing algorithm: "double-cuts" (default) or "weighted-slope" - - "pl-dist-cut1": double -- Point-line distance cut 1; rough cut - - "pl-dist-cut2": double -- Point-line distance cut 2: fine cut - - "slope-min": double -- Minimum track slope to keep (Hz/s) - - "min-points": unsigned -- Minimum number of points required to keep a processed track - - "assigned-error": double -- Error assigned to the points in case of perfectly aligned points - - Slots: - - "swfc-and-hough": void (KTDataPr) -- [what it does]; Requires KTSparseWaterfallCandidateData and KTHoughData; Adds KTProcessedTrackData; Emits signal "track" - - Signals: - - "track": void (Nymph::KTDataPtr) -- Emitted when a track has been processed; Guarantees KTProcessedTrackData. - */ - - class KTTrackProcessing : public Nymph::KTProcessor - { - public: - KTTrackProcessing(const std::string& name = "track-proc"); - virtual ~KTTrackProcessing(); - - bool Configure(const scarab::param_node* node); - - double GetPointLineDistCut1() const; - void SetPointLineDistCut1(double dist); - - double GetPointLineDistCut2() const; - void SetPointLineDistCut2(double dist); - - double GetSlopeMinimum() const; - void SetSlopeMinimum(double slope); - - unsigned GetProcTrackMinPoints() const; - void SetProcTrackMinPoints(unsigned min); - - double GetProcTrackAssignedError() const; - void SetProcTrackAssignedError(double err); - - private: - double fPointLineDistCut1; - double fPointLineDistCut2; - - double fSlopeMinimum; - - unsigned fProcTrackMinPoints; - double fProcTrackAssError; - - public: - bool ProcessTrack(KTSparseWaterfallCandidateData& swfData, KTHoughData& htData); - bool ProcessTrackDoubleCuts(KTSparseWaterfallCandidateData& swfData, KTHoughData& htData); - bool ProcessTrackWeightedSlope(KTSparseWaterfallCandidateData& swfData, KTHoughData& htData); - - - private: - /// Point-to-line distance: point coordinates (x, y); line equation a*x + b*y + c = 0 - double PointLineDistance(double pointX, double pointY, double lineA, double lineB, double lineC); - typedef bool (KTTrackProcessing::*TrackProcPtr)(KTSparseWaterfallCandidateData& , KTHoughData& ); - TrackProcPtr fTrackProcPtr; - - //*************** - // Signals - //*************** - - private: - Nymph::KTSignalData fTrackSignal; - - //*************** - // Slots - //*************** - - private: - Nymph::KTSlotDataTwoTypes< KTSparseWaterfallCandidateData, KTHoughData > fSWFAndHoughSlot; - - }; - - inline double KTTrackProcessing::GetPointLineDistCut1() const - { - return fPointLineDistCut1; - } - inline void KTTrackProcessing::SetPointLineDistCut1(double dist) - { - fPointLineDistCut1 = dist; - return; - } - - inline double KTTrackProcessing::GetPointLineDistCut2() const - { - return fPointLineDistCut2; - } - inline void KTTrackProcessing::SetPointLineDistCut2(double dist) - { - fPointLineDistCut2 = dist; - return; - } - - inline double KTTrackProcessing::GetSlopeMinimum() const - { - return fSlopeMinimum; - } - inline void KTTrackProcessing::SetSlopeMinimum(double slope) - { - fSlopeMinimum = slope; - return; - } - - inline unsigned KTTrackProcessing::GetProcTrackMinPoints() const - { - return fProcTrackMinPoints; - } - inline void KTTrackProcessing::SetProcTrackMinPoints(unsigned min) - { - fProcTrackMinPoints = min; - return; - } - - inline double KTTrackProcessing::GetProcTrackAssignedError() const - { - return fProcTrackAssError; - } - inline void KTTrackProcessing::SetProcTrackAssignedError(double err) - { - fProcTrackAssError = err; - return; - } - - double KTTrackProcessing::PointLineDistance(double pointX, double pointY, double lineA, double lineB, double lineC) - { - return fabs(lineA * pointX + lineB * pointY + lineC) / sqrt(lineA*lineA + lineB*lineB); - } -} - /* namespace Katydid */ -#endif /* KTTRACKPROCESSING_HH_ */ diff --git a/Source/EventAnalysis/KTTrackProcessingDoubleCuts.cc b/Source/EventAnalysis/KTTrackProcessingDoubleCuts.cc new file mode 100644 index 000000000..68e47f6da --- /dev/null +++ b/Source/EventAnalysis/KTTrackProcessingDoubleCuts.cc @@ -0,0 +1,297 @@ +/** + @file KTTrackProcessingDoubleCuts.cc + @brief Contains KTTrackProcessingDoubleCuts + @details Extracts physics-relevant information about tracks using a double-cuts algorithm + @author: N.S. Oblath, B. LaRoque & M. Guigue + @date: July 22, 2013 + */ + +#include "KTTrackProcessingDoubleCuts.hh" + +#include "KTHoughData.hh" +#include "KTLogger.hh" + +#include "KTProcessedTrackData.hh" +#include "KTSmooth.hh" +#include "KTSparseWaterfallCandidateData.hh" +// #include "KTSequentialLineData.hh" + +#include +#include +#include +#include + +using boost::shared_ptr; +using std::vector; +using std::string; + +namespace Katydid +{ + KTLOGGER(tlog, "KTTrackProcessingDoubleCuts"); + + // Register the processor + KT_REGISTER_PROCESSOR(KTTrackProcessingDoubleCuts, "track-proc-dc"); + + KTTrackProcessingDoubleCuts::KTTrackProcessingDoubleCuts(const std::string& name) : + KTProcessor(name), + fPointLineDistCut1(0.1), + fPointLineDistCut2(0.05), + fSlopeMinimum(-std::numeric_limits< double >::max()), + fProcTrackMinPoints(0), + fProcTrackAssignedError(0.), + fTrackSignal("track", this), + // fTrackProcPtr(&KTTrackProcessingDoubleCuts::ProcessTrackDoubleCuts), + fSWFAndHoughSlot("swfc-and-hough", this, &KTTrackProcessingDoubleCuts::ProcessTrack, &fTrackSignal) + // fSeqAndHoughSlot("seqc-and-hough", this, &KTTrackProcessingDoubleCuts::ProcessTrack, &fTrackSignal) + { + } + + KTTrackProcessingDoubleCuts::~KTTrackProcessingDoubleCuts() + { + } + + bool KTTrackProcessingDoubleCuts::Configure(const scarab::param_node* node) + { + if (node == NULL) return false; + + SetPointLineDistCut1(node->get_value("pl-dist-cut1", GetPointLineDistCut1())); + SetPointLineDistCut2(node->get_value("pl-dist-cut2", GetPointLineDistCut2())); + SetSlopeMinimum(node->get_value("min-slope", GetSlopeMinimum())); + SetProcTrackMinPoints(node->get_value("min-points", GetProcTrackMinPoints())); + SetProcTrackAssignedError(node->get_value("assigned-error", GetProcTrackAssignedError())); + + return true; + } + + template + bool KTTrackProcessingDoubleCuts::ProcessTrack(TracklikeCandidate& tlcData, KTHoughData& htData) + // Method associated with the slot + { + + TrackID trackID = ExtractTrackID(tlcData); + Points& points = tlcData.GetPoints(); + // The & is important!! + KTProcessedTrackData& procTrack = tlcData.template Of< KTProcessedTrackData >(); + + KTDEBUG(tlog, "Setting track reconstruction using \"weighted-slope\" algorithm"); + return KTTrackProcessingDoubleCuts::DoDoubleCutsAlgorithm(points, htData, trackID, &procTrack); + } + + bool KTTrackProcessingDoubleCuts::DoDoubleCutsAlgorithm(Points& points, KTHoughData& htData, TrackID trackID, KTProcessedTrackData* procTrack) + { + // not const because the HT will be smoothed in place + KTPhysicalArray< 2, double >* houghTransform = htData.GetTransform(trackID.fComponent); + + // NOTE: smoothes the actual data, not a copy + if (! KTSmooth::Smooth(houghTransform)) + { + KTERROR(tlog, "Error while smoothing Hough Transform"); + return false; + } + + unsigned maxBinX, maxBinY; + houghTransform->GetMaximumBin(maxBinX, maxBinY); + + double htAngle = houghTransform->GetBinCenter(1, maxBinX); + double htRadius = houghTransform->GetBinCenter(2, maxBinY); + + // Hough line: a*x + b*y + c = 0, c = -radius + double htCosAngle = cos(htAngle); // ht_a + double htSinAngle = sin(htAngle); // ht_b + + // scaling for Hough Transform, used throughout for line fits and modifications + // "scaled" means the axis has been scaled to 0-1, as was the case when the Hough Transform was calculated + // "unscaled" means the axis is in the original units + // unscaled = scaled * scale + offset + double xScale = htData.GetXScale(trackID.fComponent); + double yScale = htData.GetYScale(trackID.fComponent); + double xOffset = htData.GetXOffset(trackID.fComponent); + double yOffset = htData.GetYOffset(trackID.fComponent); + + double htSlope = -1.0 * (htCosAngle * yScale) / (htSinAngle * xScale); + double htIntercept = (htRadius / htSinAngle) * yScale + yOffset - htSlope * xOffset; // this is r/sin(angle), rescaled, plus extra from the xOffset + + KTDEBUG(tlog, "Hough Transform track processing results:\n" + << "\tmaxBinX: " << maxBinX << "\t maxBinY: " << maxBinY << "\t angle: " << htAngle << "\t radius: " << htRadius << '\n' + << "\ta=cos(angle): " << htCosAngle << "\t b=sin(angle): " << htSinAngle << '\n' + << "\txScale: " << xScale << "\t yScale: " << yScale << '\n' + << "\tSlope: " << htSlope << " Hz/s" << '\n' + << "\tIntercept: " << htIntercept << " Hz"); + + // First loop over points, and first point-line-distance cut + + unsigned nPoints = points.size(); + typedef vector< std::pair< double, double > > SimplePoints2D; + SimplePoints2D pointsScaled, pointsUnscaled, pointsUnscaledInAcq; + pointsScaled.reserve(nPoints); + pointsUnscaledInAcq.reserve(nPoints); + vector< unsigned > pointsCuts; + pointsCuts.reserve(nPoints); + unsigned nPointsUsed = 0; + unsigned nPointsCut1 = 0; + double sumX = 0., sumY = 0., sumX2 = 0., sumXY = 0.; // for least-squares calculation + // first distance cut, plus calculation of the initial least-squares line calculations + for (Points::const_iterator pIt = points.begin(); pIt != points.end(); ++pIt) + { + //cout << "calculating a distance..." << endl; + pointsUnscaled.push_back(SimplePoints2D::value_type(pIt->fTimeInRunC, pIt->fFrequency)); + pointsUnscaledInAcq.push_back(SimplePoints2D::value_type(pIt->fTimeInAcq, pIt->fFrequency)); + double xScaled = (pIt->fTimeInRunC - xOffset) / xScale; + double yScaled = (pIt->fFrequency - yOffset) / yScale; + pointsScaled.push_back(SimplePoints2D::value_type(xScaled, yScaled)); + //cout << "i: " << iPoint << "\t y_i: " << ys[iPoint] << "\t x_i: " << xs[iPoint] << endl; + //cout << "scaled: y_isc: " << yiscaled << "\t xisc: " << xiscaled << endl; + double distance = PointLineDistance(xScaled, yScaled, htCosAngle, htSinAngle, -htRadius); + //cout << "distance: " << distance << endl; + + if (distance < fPointLineDistCut1 ) + { + // point is not cut + ++nPointsUsed; + sumX += xScaled; + sumY += yScaled; + sumX2 += xScaled * xScaled; + sumXY += xScaled * yScaled; + pointsCuts.push_back(0); + } + else + { + // point is cut + ++nPointsCut1; + pointsCuts.push_back(1); + } + } // loop over points + KTDEBUG(tlog, "Points removed with cut 1: " << nPointsCut1); + + // Refine the line with a least-squares line calculation + double xMean = sumX / (double)nPointsUsed; + double yMean = sumY / (double)nPointsUsed; + double lsSlopeScaled = (sumXY - sumX * yMean) / (sumX2 - sumX * xMean); + double lsInterceptScaled = yMean - lsSlopeScaled * xMean; + double lsSlope = lsSlopeScaled * yScale / xScale; + double lsIntercept = lsInterceptScaled * yScale + yOffset - lsSlope * xOffset; + KTDEBUG(tlog, "Least-squares fit result\n" + << "\tSlope: " << lsSlope << " Hz/s\n" + << "\tIntercept: " << lsIntercept << " Hz"); + + // second distance cut based on LS fit + double startTime = std::numeric_limits< double >::max(); + double stopTime = -1.; + double startTimeInAcq = 0; + //nPointsUsed = 0; + double startFreq = 0., stopFreq = 0.; + unsigned nPointsCut2 = 0; + for (unsigned iPoint = 0; iPoint < nPoints; ++iPoint) + { + double distance = PointLineDistance(pointsScaled[iPoint].first, pointsScaled[iPoint].second, lsSlopeScaled, -1., lsInterceptScaled);; + + if (pointsCuts[iPoint] == 0 && distance < fPointLineDistCut2) + { + // point is not cut + //++nPointsUsed; + if (pointsUnscaled[iPoint].first < startTime) //possibly update start time/frequency + { + startTime = pointsUnscaled[iPoint].first; + startFreq = startTime * lsSlope + lsIntercept; + startTimeInAcq = pointsUnscaledInAcq[iPoint].first; + } + if (pointsUnscaled[iPoint].first > stopTime) + { //possibly update stop time/frequency + stopTime = pointsUnscaled[iPoint].first; + stopFreq = stopTime * lsSlope + lsIntercept; + } + } + else if (pointsCuts[iPoint] == 0) + { + // point is cut + ++nPointsCut2; + pointsCuts[iPoint] = 2; + } + } + KTDEBUG(tlog, "Points removed with cut 2: " << nPointsCut2); + + // Remove points and sum amplitudes + Points::iterator pItMaster = points.begin(); + Points::iterator pItCache; + + vector amplitude; + vector mean; + vector variance; + vector neighborhoodAmplitude; + + vector trackSNR; + vector trackNUP; + + vector wideTrackSNR; + vector wideTrackNUP; + + //Has to be a better way (remove_if?) + for (unsigned iPoint = 0; iPoint < nPoints; ++iPoint) + { + pItCache = pItMaster; + ++pItMaster; + if (pointsCuts[iPoint] == 0) + { + amplitude.push_back(pItCache->fAmplitude); + mean.push_back(pItCache->fMean); + variance.push_back(pItCache->fVariance); + neighborhoodAmplitude.push_back(pItCache->fNeighborhoodAmplitude); + + trackSNR.push_back(pItCache->fAmplitude / pItCache->fMean); + trackNUP.push_back((pItCache->fAmplitude - pItCache->fMean) / sqrt(pItCache->fVariance)); + + wideTrackSNR.push_back(pItCache->fNeighborhoodAmplitude / pItCache->fMean); + wideTrackNUP.push_back((pItCache->fNeighborhoodAmplitude - pItCache->fMean) / sqrt(pItCache->fVariance)); + } + else + { + points.erase(pItCache); + } + } + KTDEBUG(tlog, "Points present after cuts: " << points.size()); + + // Add the new data + procTrack->SetComponent(trackID.fComponent); + procTrack->SetAcquisitionID(trackID.fAcquisitionID); + procTrack->SetTrackID(trackID.fCandidateID); + + if (lsSlope < fSlopeMinimum || points.size() < fProcTrackMinPoints) + { + procTrack->SetIsCut(true); + } + + procTrack->SetStartTimeInAcq(startTimeInAcq); + procTrack->SetStartTimeInRunC(startTime); + procTrack->SetEndTimeInRunC(stopTime); + procTrack->SetTimeLength(stopTime - startTime); + procTrack->SetStartFrequency(startFreq); + procTrack->SetEndFrequency(stopFreq); + procTrack->SetFrequencyWidth(std::abs(stopFreq - startFreq)); + procTrack->SetSlope(lsSlope); + procTrack->SetIntercept(lsIntercept); + procTrack->SetTotalPower(std::accumulate(amplitude.begin(), amplitude.end(), 0.)); + + procTrack->SetNTrackBins(points.size()); + procTrack->SetTotalTrackSNR(std::accumulate(trackSNR.begin(),trackSNR.end(),0.)); + procTrack->SetMaxTrackSNR(*std::max_element(trackSNR.begin(), trackSNR.end())); + procTrack->SetTotalTrackNUP(std::accumulate(trackNUP.begin(),trackNUP.end(),0.)); + procTrack->SetMaxTrackNUP(*std::max_element(trackNUP.begin(), trackNUP.end())); + procTrack->SetTotalWideTrackSNR(std::accumulate(wideTrackSNR.begin(),wideTrackSNR.end(),0.)); + procTrack->SetTotalWideTrackNUP(std::accumulate(wideTrackNUP.begin(),wideTrackNUP.end(),0.)); + + //TODO: Add calculation of uncertainties + + return true; + } + + template + KTTrackProcessingDoubleCuts::TrackID KTTrackProcessingDoubleCuts::ExtractTrackID(TracklikeCandidate tlcData) + { + TrackID trackID; + trackID.fComponent = tlcData.GetComponent(); + trackID.fAcquisitionID = tlcData.GetAcquisitionID(); + trackID.fCandidateID = tlcData.GetCandidateID(); + return trackID; + } + +} /* namespace Katydid */ diff --git a/Source/EventAnalysis/KTTrackProcessingDoubleCuts.hh b/Source/EventAnalysis/KTTrackProcessingDoubleCuts.hh new file mode 100644 index 000000000..e960deb1c --- /dev/null +++ b/Source/EventAnalysis/KTTrackProcessingDoubleCuts.hh @@ -0,0 +1,116 @@ +/** + @file KTTrackProcessingDoubleCuts.hh + @brief Contains KTTrackProcessingDoubleCuts + @details Extracts physics-relevant information about tracks using a double-cuts algorithm + @author: N.S. Oblath, B. LaRoque & M. Guigue + @date: July 22, 2013 + */ + +#ifndef KTTrackProcessingDoubleCuts_HH_ +#define KTTrackProcessingDoubleCuts_HH_ + +#include "KTProcessor.hh" + +#include "KTMemberVariable.hh" +#include "KTDiscriminatedPoint.hh" +#include "KTProcessedTrackData.hh" + +#include "KTSlot.hh" + +#include + + +namespace Katydid +{ + + class KTHoughData; + class KTSparseWaterfallCandidateData; + // class KTSequentialLineData; + + /*! + @class KTTrackProcessingDoubleCuts + @author N.S. Oblath, B. LaRoque & M. Guigue + + @brief Extracts physics-relevant information about tracks using a double-cuts algorithm + + @details + + Configuration name: "track-proc" + + Available configuration values: + - "pl-dist-cut1": double -- Point-line distance cut 1; rough cut + - "pl-dist-cut2": double -- Point-line distance cut 2: fine cut + - "slope-min": double -- Minimum track slope to keep (Hz/s) + - "min-points": unsigned -- Minimum number of points required to keep a processed track + - "assigned-error": double -- Error assigned to the points in case of perfectly aligned points + + Slots: + - "swfc-and-hough": void (KTDataPr) -- [what it does]; Requires KTSparseWaterfallCandidateData and KTHoughData; Adds KTProcessedTrackData; Emits signal "track" + - "seqc-and-hough": void (KTDataPr) -- [what it does]; Requires KTSequentialLineData and KTHoughData; Adds KTProcessedTrackData; Emits signal "track" + + Signals: + - "track": void (Nymph::KTDataPtr) -- Emitted when a track has been processed; Guarantees KTProcessedTrackData. + */ + + class KTTrackProcessingDoubleCuts : public Nymph::KTProcessor + { + + public: + typedef KTDiscriminatedPoints Points; + struct TrackID + { + unsigned fComponent; + unsigned fCandidateID; + unsigned fAcquisitionID; + }; + + public: + KTTrackProcessingDoubleCuts(const std::string& name = "track-proc-dc"); + virtual ~KTTrackProcessingDoubleCuts(); + + bool Configure(const scarab::param_node* node); + + private: + + MEMBERVARIABLE(std::string, TrackProcAlgorithm); + MEMBERVARIABLE(double, PointLineDistCut1); + MEMBERVARIABLE(double, PointLineDistCut2); + MEMBERVARIABLE(double, SlopeMinimum); + MEMBERVARIABLE(unsigned, ProcTrackMinPoints); + MEMBERVARIABLE(double, ProcTrackAssignedError); + + public: + template + bool ProcessTrack(TracklikeCandidate& tlcData, KTHoughData& htData); + // Core methods for both algorithm + bool DoDoubleCutsAlgorithm(Points& points, KTHoughData& htData, TrackID trackID, KTProcessedTrackData* procTrack); + + private: + double PointLineDistance(double pointX, double pointY, double lineA, double lineB, double lineC); + template + TrackID ExtractTrackID(TracklikeCandidate tlcData); + + //*************** + // Signals + //*************** + + private: + Nymph::KTSignalData fTrackSignal; + + //*************** + // Slots + //*************** + + private: + Nymph::KTSlotDataTwoTypes< KTSparseWaterfallCandidateData, KTHoughData > fSWFAndHoughSlot; + // Nymph::KTSlotDataTwoTypes< KTSequentialLineData, KTHoughData > fSeqAndHoughSlot; + + }; + + double KTTrackProcessingDoubleCuts::PointLineDistance(double pointX, double pointY, double lineA, double lineB, double lineC) + { + return fabs(lineA * pointX + lineB * pointY + lineC) / sqrt(lineA*lineA + lineB*lineB); + } +} + /* namespace Katydid */ +#endif /* KTTrackProcessingDoubleCuts_HH_ */ diff --git a/Source/EventAnalysis/KTTrackProcessingWeightedSlope.cc b/Source/EventAnalysis/KTTrackProcessingWeightedSlope.cc new file mode 100644 index 000000000..9c3f1a115 --- /dev/null +++ b/Source/EventAnalysis/KTTrackProcessingWeightedSlope.cc @@ -0,0 +1,249 @@ +/** + @file KTTrackProcessingWeightedSlope.cc + @brief Contains KTTrackProcessingWeightedSlope + @details Extracts physics-relevant information about tracks using a weighted slope algorithm + @author: N.S. Oblath, B. LaRoque & M. Guigue + @date: July 22, 2013 + */ + +#include "KTTrackProcessingWeightedSlope.hh" + +#include "KTHoughData.hh" +#include "KTLogger.hh" + +#include "KTProcessedTrackData.hh" +#include "KTSmooth.hh" +#include "KTSparseWaterfallCandidateData.hh" +#include "KTSequentialLineData.hh" + +#include +#include +#include +#include + +using boost::shared_ptr; +using std::vector; +using std::string; + +namespace Katydid +{ + KTLOGGER(tlog, "KTTrackProcessingWeightedSlope"); + + // Register the processor + KT_REGISTER_PROCESSOR(KTTrackProcessingWeightedSlope, "track-proc-ws"); + + KTTrackProcessingWeightedSlope::KTTrackProcessingWeightedSlope(const std::string& name) : + KTProcessor(name), + fSlopeMinimum(-std::numeric_limits< double >::max()), + fProcTrackMinPoints(0), + fProcTrackAssignedError(0.), + fTrackSignal("track", this), + fSWFSlot("swfc", this, &KTTrackProcessingWeightedSlope::ProcessTrack, &fTrackSignal), + fSeqSlot("seq-cand", this, &KTTrackProcessingWeightedSlope::ProcessTrack, &fTrackSignal) + { + } + + KTTrackProcessingWeightedSlope::~KTTrackProcessingWeightedSlope() + { + } + + bool KTTrackProcessingWeightedSlope::Configure(const scarab::param_node* node) + { + if (node == NULL) return false; + + SetSlopeMinimum(node->get_value("min-slope", GetSlopeMinimum())); + SetProcTrackMinPoints(node->get_value("min-points", GetProcTrackMinPoints())); + SetProcTrackAssignedError(node->get_value("assigned-error", GetProcTrackAssignedError())); + + return true; + } + + template + bool KTTrackProcessingWeightedSlope::ProcessTrack(TracklikeCandidate& tlcData) + // Method associated with the slot + { + + TrackID trackID = ExtractTrackID(tlcData); + Points& points = tlcData.GetPoints(); + // The & is important!! + KTProcessedTrackData& procTrack = tlcData.template Of< KTProcessedTrackData >(); + + KTDEBUG(tlog, "Setting track reconstruction using \"weighted-slope\" algorithm"); + return KTTrackProcessingWeightedSlope::DoWeightedSlopeAlgorithm(points, trackID, &procTrack); + } + + bool KTTrackProcessingWeightedSlope::DoWeightedSlopeAlgorithm(Points& points, TrackID trackID,KTProcessedTrackData* procTrack) + { + vector< double > timeBinInAcq; + vector< double > timeBinInRunC; + vector< double > averageFrequency; + + // Makes a first loop over the points to calculate the weighted average in one time slice + for (Points::const_iterator pIt = points.begin(); pIt != points.end(); ++pIt) + { + timeBinInAcq.push_back(pIt->fTimeInAcq); + timeBinInRunC.push_back(pIt->fTimeInRunC); + } + //Make these lists duplicate-free + sort( timeBinInAcq.begin(), timeBinInAcq.end() ); + timeBinInAcq.erase( unique( timeBinInAcq.begin(), timeBinInAcq.end() ), timeBinInAcq.end() ); + + sort( timeBinInRunC.begin(), timeBinInRunC.end() ); + timeBinInRunC.erase( unique( timeBinInRunC.begin(), timeBinInRunC.end() ), timeBinInRunC.end() ); + + const int nTimeBins = timeBinInAcq.size(); + //Derived Quantites + vector< double > mean(nTimeBins); + vector< double > variance(nTimeBins); + vector< double > neighborhoodAmplitude(nTimeBins); + vector< double > sumPf(nTimeBins); + vector< double > sumP(nTimeBins); + vector< double > trackSNR(nTimeBins); + vector< double > trackNUP(nTimeBins); + vector< double > wideTrackSNR(nTimeBins); + vector< double > wideTrackNUP(nTimeBins); + int nTrackBins = 0.; + // Calculate the averaged points + for (Points::const_iterator pIt = points.begin(); pIt != points.end(); ++pIt) + { + for (int iTimeBin=0; iTimeBinfTimeInAcq == timeBinInAcq[iTimeBin]) + { + sumPf[iTimeBin] += pIt->fFrequency * pIt->fAmplitude; + sumP[iTimeBin] += pIt->fAmplitude; + mean[iTimeBin] += pIt->fMean; + variance[iTimeBin] += pIt->fVariance; + neighborhoodAmplitude[iTimeBin] += pIt->fNeighborhoodAmplitude; + + trackSNR[iTimeBin] += pIt->fAmplitude/pIt->fMean; + trackNUP[iTimeBin] += (pIt->fAmplitude - pIt->fMean) / sqrt(pIt->fVariance); + + wideTrackSNR[iTimeBin] += pIt->fNeighborhoodAmplitude/pIt->fMean; + wideTrackNUP[iTimeBin] += (pIt->fNeighborhoodAmplitude - pIt->fMean) / sqrt(pIt->fVariance); + + ++nTrackBins; + break; //Since time bins are unique + } + } + } + + KTDEBUG(tlog, "Averaging"); + for (unsigned iTimeBin = 0; iTimeBin2) + { + KTDEBUG(tlog, "Chi2min : " << chi2min ); + + if (chi2min < 0.1) + { + KTDEBUG(tlog, "Chi2min too small (points are mostlikely aligned): assigning arbitrary errors to the averaged Frequency points (" << fProcTrackAssignedError << ")"); + deltaSlope = 1.52/(sqrt(sumXX)/fProcTrackAssignedError); + deltaIntercept = 1.52/(sqrt(sumOne)/fProcTrackAssignedError); + } + else + { + double ndf = nTimeBins - 2; // 2: two fitting parameters + deltaSlope = 1.52/sqrt(sumXX*ndf/chi2min); + deltaIntercept = 1.52/sqrt(sumOne*ndf/chi2min); + } + KTDEBUG(tlog, "Error calculations results: \n" << + "\tSlope: " << '\t' << deltaSlope << '\n' << + "\tIntercept: " << '\t' << deltaIntercept << '\n' << + "\tCorrelation coefficifent: " << '\t' << rho); + //Calculating error on the starting frequency and the end frequency + double startTime = *std::min_element(timeBinInAcq.begin(), timeBinInAcq.end()); + double endTime = *std::max_element(timeBinInAcq.begin(), timeBinInAcq.end()); + sigmaStartFreq = sqrt( startTime*startTime * deltaSlope*deltaSlope + deltaIntercept*deltaIntercept + 2 * startTime * rho * deltaSlope * deltaIntercept ); + sigmaEndFreq = sqrt( endTime*endTime * deltaSlope*deltaSlope + deltaIntercept*deltaIntercept + 2 * endTime * rho * deltaSlope * deltaIntercept ); + } + + // TODO: Calculate distance to track and see for a possible alpha [%] rejection of noise. + + // Adding resuts to ProcessedTrackData object + procTrack->SetComponent(trackID.fComponent); + procTrack->SetAcquisitionID(trackID.fAcquisitionID); + procTrack->SetTrackID(trackID.fCandidateID); + + procTrack->SetStartTimeInAcq(*std::min_element(timeBinInAcq.begin(), timeBinInAcq.end())); + procTrack->SetStartTimeInRunC(*std::min_element(timeBinInRunC.begin(), timeBinInRunC.end())); + procTrack->SetEndTimeInRunC(*std::max_element(timeBinInRunC.begin(), timeBinInRunC.end())); + procTrack->SetTimeLength(procTrack->GetEndTimeInRunC() - procTrack->GetStartTimeInRunC()); + procTrack->SetStartFrequency(procTrack->GetStartTimeInAcq() * slope + intercept); + procTrack->SetEndFrequency((procTrack->GetStartTimeInAcq() + procTrack->GetTimeLength()) * slope + intercept); + procTrack->SetFrequencyWidth(std::abs(procTrack->GetEndFrequency() - procTrack->GetStartFrequency())); + procTrack->SetSlope(slope); + procTrack->SetIntercept(intercept); + procTrack->SetTotalPower(amplitudeSum); + + procTrack->SetNTrackBins(nTrackBins); + procTrack->SetTotalTrackSNR(std::accumulate(trackSNR.begin(),trackSNR.end(),0.)); + procTrack->SetMaxTrackSNR(*std::max_element(trackSNR.begin(), trackSNR.end())); + procTrack->SetTotalTrackNUP(std::accumulate(trackNUP.begin(),trackNUP.end(),0.)); + procTrack->SetMaxTrackNUP(*std::max_element(trackNUP.begin(), trackNUP.end())); + procTrack->SetTotalWideTrackSNR(std::accumulate(wideTrackSNR.begin(),wideTrackSNR.end(),0.)); + procTrack->SetTotalWideTrackNUP(std::accumulate(wideTrackNUP.begin(),wideTrackNUP.end(),0.)); + + + if (!(slope > fSlopeMinimum)) + { + procTrack->SetIsCut(true); + } + procTrack->SetSlopeSigma(deltaSlope); + procTrack->SetInterceptSigma(deltaIntercept); + procTrack->SetStartFrequencySigma(sigmaStartFreq); + procTrack->SetEndFrequencySigma(sigmaEndFreq); + + return true; + } + + template + KTTrackProcessingWeightedSlope::TrackID KTTrackProcessingWeightedSlope::ExtractTrackID(TracklikeCandidate tlcData) + { + TrackID trackID; + trackID.fComponent = tlcData.GetComponent(); + trackID.fAcquisitionID = tlcData.GetAcquisitionID(); + trackID.fCandidateID = tlcData.GetCandidateID(); + return trackID; + } + +} /* namespace Katydid */ diff --git a/Source/EventAnalysis/KTTrackProcessingWeightedSlope.hh b/Source/EventAnalysis/KTTrackProcessingWeightedSlope.hh new file mode 100644 index 000000000..6cda3510a --- /dev/null +++ b/Source/EventAnalysis/KTTrackProcessingWeightedSlope.hh @@ -0,0 +1,106 @@ +/** + @file KTTrackProcessingWeightedSlope.hh + @brief Contains KTTrackProcessingWeightedSlope + @details Extracts physics-relevant information about tracks using a weighted-slope algorithm + @author: N.S. Oblath, B. LaRoque & M. Guigue + @date: July 22, 2013 + */ + +#ifndef KTTrackProcessingWeightedSlope_HH_ +#define KTTrackProcessingWeightedSlope_HH_ + +#include "KTProcessor.hh" + +#include "KTMemberVariable.hh" +#include "KTDiscriminatedPoint.hh" +#include "KTProcessedTrackData.hh" + +#include "KTSlot.hh" + +#include + + +namespace Katydid +{ + + class KTSparseWaterfallCandidateData; + class KTSequentialLineData; + + /*! + @class KTTrackProcessingWeightedSlope + @author N.S. Oblath, B. LaRoque & M. Guigue + + @brief Extracts physics-relevant information about tracks using a weighted-slope algorithm + + @details + + Configuration name: "track-proc-ws" + + Available configuration values: + - "slope-min": double -- Minimum track slope to keep (Hz/s) + - "min-points": unsigned -- Minimum number of points required to keep a processed track + - "assigned-error": double -- Error assigned to the points in case of perfectly aligned points + + Slots: + - "swfc": void (KTDataPr) -- [what it does]; Requires KTSparseWaterfallCandidateData; Adds KTProcessedTrackData; Emits signal "track" + - "seqc": void (KTDataPr) -- [what it does]; Requires KTSequentialLineData; Adds KTProcessedTrackData; Emits signal "track" + + Signals: + - "track": void (Nymph::KTDataPtr) -- Emitted when a track has been processed; Guarantees KTProcessedTrackData. + */ + + class KTTrackProcessingWeightedSlope : public Nymph::KTProcessor + { + + public: + typedef KTDiscriminatedPoints Points; + struct TrackID + { + unsigned fComponent; + unsigned fCandidateID; + unsigned fAcquisitionID; + }; + + public: + KTTrackProcessingWeightedSlope(const std::string& name = "track-proc-ws"); + virtual ~KTTrackProcessingWeightedSlope(); + + bool Configure(const scarab::param_node* node); + + private: + + MEMBERVARIABLE(std::string, TrackProcAlgorithm); + MEMBERVARIABLE(double, SlopeMinimum); + MEMBERVARIABLE(unsigned, ProcTrackMinPoints); + MEMBERVARIABLE(double, ProcTrackAssignedError); + + public: + template + bool ProcessTrack(TracklikeCandidate& tlcData); + // Core method + bool DoWeightedSlopeAlgorithm(Points& points, TrackID trackID, KTProcessedTrackData* procTrack); + + private: + template + TrackID ExtractTrackID(TracklikeCandidate tlcData); + + //*************** + // Signals + //*************** + + private: + Nymph::KTSignalData fTrackSignal; + + //*************** + // Slots + //*************** + + private: + Nymph::KTSlotDataOneType< KTSparseWaterfallCandidateData > fSWFSlot; + Nymph::KTSlotDataOneType< KTSequentialLineData > fSeqSlot; + + }; + +} + /* namespace Katydid */ +#endif /* KTTrackProcessingWeightedSlope_HH_ */ diff --git a/Source/Executables/Validation/CMakeLists.txt b/Source/Executables/Validation/CMakeLists.txt index 836dc524f..c760e0beb 100644 --- a/Source/Executables/Validation/CMakeLists.txt +++ b/Source/Executables/Validation/CMakeLists.txt @@ -66,22 +66,25 @@ if (Katydid_ENABLE_TESTING) TestDataAccumulator TestDBScan TestDBScanTrackClustering - TestDistanceClustering + # TestDistanceClustering TestGainNormalization TestGainVariationProcessor #TestHoughTransform # temporarily disabled because it's not compatible with the changes made while introducing the extensible data scheme TestKDTree TestKDTreeData - TestLinearDensityProbe - TestMultiSliceClustering + # TestLinearDensityProbe + # TestMultiSliceClustering TestNanoflann + TestSequentialTrackFinder #TestSimpleClustering # disabled because it's written for the old version of KTMultiSliceClustering; see TestMultiSliceClustering #TestSlidingWindowFFT TestSpectrogramCollector TestSpectrogramStriper TestSpectrogramStriperSwaps TestSpectrumDiscriminator + TestTrackProcessing TestWindowFunction + ) pbuilder_executables( PROGRAMS LIB_DEPENDENCIES ) @@ -129,7 +132,7 @@ if (Katydid_ENABLE_TESTING) TestROOTDictionary TestROOTTreeWritingViaCicada TestROOTWriterFileManager - TestROOTWritingToSameFile + # TestROOTWritingToSameFile ) pbuilder_executables( PROGRAMS LIB_DEPENDENCIES ) diff --git a/Source/Executables/Validation/TestConsensusThresholding.cc b/Source/Executables/Validation/TestConsensusThresholding.cc index f52db4cd6..d7fb41c98 100644 --- a/Source/Executables/Validation/TestConsensusThresholding.cc +++ b/Source/Executables/Validation/TestConsensusThresholding.cc @@ -266,7 +266,7 @@ int main() #endif unsigned iCand = 0; - typedef KTSparseWaterfallCandidateData::Points Points; + typedef KTDiscriminatedPoints Points; for (std::set< Nymph::KTDataPtr >::const_iterator cIt = candidates.begin(); cIt != candidates.end(); ++cIt) { diff --git a/Source/Executables/Validation/TestConvolution1D.cc b/Source/Executables/Validation/TestConvolution1D.cc index bce4b51eb..12b980b47 100644 --- a/Source/Executables/Validation/TestConvolution1D.cc +++ b/Source/Executables/Validation/TestConvolution1D.cc @@ -79,9 +79,9 @@ int main() convProcessor.SetNormalizeKernel( true ); convProcessor.FinishSetup(); - int block = convProcessor.GetBlockSize(); - int overlap = nKernelBins - 1; - int step = block - overlap; + const int block = convProcessor.GetBlockSize(); + const int overlap = nKernelBins - 1; + const int step = block - overlap; convProcessor.Initialize( nBins, block, step, overlap ); diff --git a/Source/Executables/Validation/TestDBScanTrackClustering.cc b/Source/Executables/Validation/TestDBScanTrackClustering.cc index 74ef109d6..9ca38d76e 100644 --- a/Source/Executables/Validation/TestDBScanTrackClustering.cc +++ b/Source/Executables/Validation/TestDBScanTrackClustering.cc @@ -239,7 +239,7 @@ int main() #endif unsigned iCand = 0; - typedef KTSparseWaterfallCandidateData::Points Points; + typedef KTDiscriminatedPoints Points; for (std::set< Nymph::KTDataPtr >::const_iterator cIt = candidates.begin(); cIt != candidates.end(); ++cIt) { diff --git a/Source/Executables/Validation/TestSequentialTrackFinder.cc b/Source/Executables/Validation/TestSequentialTrackFinder.cc new file mode 100644 index 000000000..a7eab57dd --- /dev/null +++ b/Source/Executables/Validation/TestSequentialTrackFinder.cc @@ -0,0 +1,266 @@ +/** +@file TestSequentialTrackFinder.cc +@brief Test executable of the SequentialTrackFinder the OverlapingTrackClustering and the IterativeTrackClustering Processor +@author C. Claessens +@date May 30, 2018 +@details +This executable tests the finding of SparseWaterfallCandidates by faking DiscriminatedPoints1DData +and tests the behavior of the algorithms in this processor. +*/ + + +#include "KTLogger.hh" + +#include "KTSliceHeader.hh" +#include "KTSequentialTrackFinder.hh" +#include "KTOverlappingTrackClustering.hh" +#include "KTIterativeTrackClustering.hh" +#include "KTDiscriminatedPoints1DData.hh" +#include "KTSequentialLineData.hh" +#include "KTSequentialLineSNRCut.hh" +#include "KTSequentialLineNUPCut.hh" +#include "KTRandom.hh" + + + +using namespace Katydid; + +KTLOGGER(testlog, "TestSequentialTrackFinder"); + +KTSliceHeader createFakeHeader( unsigned sliceNumber, double timeBinWidth ) +{ + KTSliceHeader header; + header.SetBinWidth(timeBinWidth); + header.SetTimeInAcq(timeBinWidth*sliceNumber); + header.SetTimeInRun(timeBinWidth*sliceNumber); + header.SetSampleRate(100.e6); + header.SetRawSliceSize(4096); + header.SetAcquisitionID(5); + return header; +} + +KTDiscriminatedPoints1DData createFakeData(unsigned sliceNumber, double timeBinWidth, double freqBinWidth) +{ + int avgPointsPerSlice = 10; + + double pointPowerMean = 1e-6; + double pointPowerStd = 1e-7; + unsigned minBin = 0; + unsigned maxBin = 4096; + double threshold = pointPowerMean - 2* pointPowerStd; + unsigned component = 0; + + // Define the parameters of the fake track to generate + double trackSlope = 500e6/freqBinWidth*timeBinWidth; // [Bins/s] + double trackIntercept = 1000; // [Bins] + unsigned trackStart = 20; //[Bin] + unsigned trackStart2 = 100; + unsigned trackLength = 50; //[Bin] + + KTDiscriminatedPoints1DData disc1d; + + KTRNGUniform<> yBin(minBin, maxBin); + KTRNGGaussian<> powerDistribution(pointPowerMean, pointPowerStd); + KTRNGPoisson<> numberPointsDistribution(avgPointsPerSlice); + + typedef KTDiscriminatedPoints1DData::Point Point; + + // random points + int nPoints = numberPointsDistribution(); + for (unsigned iPoint = 0; iPoint= trackStart and sliceNumber < trackStart + trackLength) + { + double power = powerDistribution(); + unsigned iBin = trackIntercept + trackSlope*(sliceNumber - trackStart); + disc1d.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(freqBinWidth*((double)iBin + 0.5), power, threshold, pointPowerMean,pointPowerStd, 2*power), component); + KTDEBUG(testlog, "Adding track point: "<= trackStart2 and sliceNumber < trackStart2 + trackLength) + { + double power = powerDistribution(); + unsigned iBin = trackIntercept + trackSlope*(sliceNumber - trackStart); + disc1d.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(freqBinWidth * ((double)iBin + 0.5), power, threshold, pointPowerMean, pointPowerStd, 2*power), component); + KTDEBUG(testlog, "Adding track point: "<& candidates = stf.GetCandidates(); + KTINFO(testlog, "Candidates found: " << candidates.size()); + + + // Print some output + unsigned STFPoints = 0; + for (std::set< Nymph::KTDataPtr >::const_iterator cIt = candidates.begin(); cIt != candidates.end(); ++cIt) + { + KTSequentialLineData& sqlData = (*cIt)->Of< KTSequentialLineData >(); + KTDEBUG(testlog, "Candidate " << sqlData.GetCandidateID()); + KTDEBUG(testlog, "Properties (starttime/frequnecy - endtime/frequency - slope) "<fTimeInRunC<<" "<fFrequency<<" "<fNeighborhoodAmplitude); + //} + } + KTINFO(testlog, "Total STF Points: "<::const_iterator cIt = candidates.begin(); cIt != candidates.end(); ++cIt) + { + KTSequentialLineData& sqlData = (*cIt)->Of< KTSequentialLineData >(); + otc.TakeSeqLineCandidate(sqlData); + } + otc.Run(); + + // Get OTC output + std::set< Nymph::KTDataPtr > otccandidates = otc.GetCandidates(); + + KTINFO(testlog, "OTC Candidates found: " << otccandidates.size()); + + // Print some output + unsigned OTCPoints = 0; + std::set< Nymph::KTDataPtr >::const_iterator otcIt = otccandidates.begin(); + while( otcIt != otccandidates.end()) + { + KTSequentialLineData& sqlData = (*otcIt)->Of< KTSequentialLineData >(); + KTDEBUG(testlog, "OTC Candidate " << sqlData.GetCandidateID()); + KTDEBUG(testlog, "Properties (starttime/frequnecy - endtime/frequency - slope) "<Of< Nymph::KTData >(); + snrcut.Apply(data, sqlData); + if (data.GetCutStatus().IsCut() == true) + { + otcIt = otccandidates.erase(otcIt); + } + else + { + const KTDiscriminatedPoints& candPoints = sqlData.GetPoints(); + KTDEBUG(testlog, "Length [bins]: "<fTimeInRunC<<" "<fFrequency<<" "<fNeighborhoodAmplitude); + //} + + } + KTINFO(testlog, "OTC Candidates after Cut: " << otccandidates.size()); + KTINFO(testlog, "Total OTC Points: "<::const_iterator cIt = otccandidates.begin(); cIt != otccandidates.end(); ++cIt) + { + KTSequentialLineData& sqlData = (*cIt)->Of< KTSequentialLineData >(); + itc.TakeSeqLineCandidate(sqlData); + } + itc.Run(); + + // Get ITC output + std::set< Nymph::KTDataPtr > itccandidates = itc.GetCandidates(); + KTINFO(testlog, "ITC Candidates found: " << itccandidates.size()); + + // Print some output + unsigned ITCPoints = 0; + std::set< Nymph::KTDataPtr >::const_iterator cIt = itccandidates.begin(); + while(cIt != itccandidates.end()) + { + KTSequentialLineData& sqlData = (*cIt)->Of< KTSequentialLineData >(); + + KTDEBUG(testlog, "ITC Candidate " << sqlData.GetCandidateID()); + KTDEBUG(testlog, "Properties (starttime/frequnecy - endtime/frequency - slope) "<Of< Nymph::KTData >(); + nupcut.Apply(data, sqlData); + if (data.GetCutStatus().IsCut() == true) + { + cIt = itccandidates.erase(cIt); + } + else + { + const KTDiscriminatedPoints& candPoints = sqlData.GetPoints(); + KTDEBUG(testlog, "Length [bins]: "<fTimeInRunC<<" "<fFrequency<<" "<fNeighborhoodAmplitude); + } + ++cIt; + } + + } + KTINFO(testlog, "ITC Candidates after Cut: " << itccandidates.size()); + KTINFO(testlog, "Total ITC Points: "<SetXMin(minFreq); + splineMean->SetXMax(maxFreq); + + KTSpline* splineVar = new KTSpline(xVals, yValsVar, NFitPoints); + splineVar->SetXMin(minFreq); + splineVar->SetXMax(maxFreq); + + delete [] xVals; + delete [] yValsMean; + delete [] yValsVar; + + KTGainVariationData gvdata; + gvdata.SetNComponents(1); + gvdata.SetSpline(splineMean); + gvdata.SetVarianceSpline(splineVar, 0); + + // Check things have arrived + std::shared_ptr< KTSpline::Implementation > splineImp = gvdata.GetSpline(0)->Implement(nBins, minFreq, maxFreq); + double returnedMean = splineImp->GetMean(); + KTINFO(testlog, "Spline mean: "<(); + KTDiscriminatedPoints1DData& pointData = dataPS.Of< KTDiscriminatedPoints1DData >(); KTDiscriminatedPoints1DData::SetOfPoints setOfPoints = pointData.GetSetOfPoints(0); KTINFO(testlog, "Found " << setOfPoints.size() << " points above threshold"); for (KTDiscriminatedPoints1DData::SetOfPoints::const_iterator it=setOfPoints.begin(); it != setOfPoints.end(); it++) { - KTINFO(testlog, "Bin " << it->first << " = (" << it->second.fAbscissa << ", " << it->second.fOrdinate << ")"); + KTINFO(testlog, "spline[Bin]: "<<(*splineImp)(it->first)); + KTINFO(testlog, "Bin " << it->first << " = (" << it->second.fAbscissa << ", " << it->second.fOrdinate << ", "<< it->second.fMean << ", "<< it->second.fVariance << ", "<< it->second.fNeighborhoodAmplitude<<")"); } #ifdef ROOT_FOUND diff --git a/Source/Executables/Validation/TestTrackProcessing.cc b/Source/Executables/Validation/TestTrackProcessing.cc new file mode 100644 index 000000000..56a05f716 --- /dev/null +++ b/Source/Executables/Validation/TestTrackProcessing.cc @@ -0,0 +1,129 @@ +/** +@file TestTrackProcessing.cc +@brief Test executable of the TrackProcessing Processor +@author M. Guigue +@date May 27, 2018 +@details +This executable tests the Track processing processor by faking a SparseWaterfallCandidateData +and tests the behavior of the algorithms in this processor. +*/ + +#include "KTLogger.hh" + +#include "KTTrackProcessingWeightedSlope.hh" +#include "KTProcessedTrackData.hh" +#include "KTSparseWaterfallCandidateData.hh" +#include "KTDiscriminatedPoint.hh" +#include "KTROOTTreeTypeWriterEventAnalysis.hh" +#include "KTRandom.hh" + +#include // std::abs + +// Define the parameters of the fake track to generate +double trackSlope = 100e6; // [Hz/s] +double trackIntercept = 1e5; // [Hz] +double trackStart = 0.1; //[s] +double trackLength = 0.1; //[s] +double trackSigma = 20000.; // [Hz] +double trackPowerMean = 1e-10; +double trackPowerStd = 1e-11; +int nSlices = 20; +int avgPointsPerSlice = 1; + +using namespace Katydid; + +KTLOGGER(testlog, "TestTrackProcessing"); + +KTSparseWaterfallCandidateData createFakeData(double trackSlope, + double trackIntercept, + double trackStart, + double trackLength, + double trackSigma, + double trackPowerMean, + double trackPowerStd, + double nSlices, + double avgPointsPerSlice) +{ + KTSparseWaterfallCandidateData swfData; + + KTRNGGaussian<> noiseDistribution(0,trackSigma); + KTRNGGaussian<> powerDistribution(trackPowerMean,trackPowerStd); + KTRNGPoisson<> numberPointsDistribution(avgPointsPerSlice); + + typedef KTDiscriminatedPoint Point; + + if (nSlices<=1){ + KTERROR( testlog, "Number of slices <" << nSlices <<"> should be larger than 1!"); + return swfData; + } + double timeStep = (trackLength)/(nSlices-1); + double sliceTime = trackStart; + for (unsigned iSlice=0; iSlice Of< KTSparseWaterfallCandidateData >(); + swfData = createFakeData(trackSlope, trackIntercept,trackStart,trackLength,trackSigma,trackPowerMean,trackPowerStd,nSlices,avgPointsPerSlice); + trackProc.ProcessTrack(swfData); + +#ifdef ROOT_FOUND + KTROOTTreeWriter writer; + writer.SetFilename("TestTrackProcessing_result.root"); + writer.SetFileFlag("recreate"); + + KTROOTTreeTypeWriterEventAnalysis treeTypeWriter; + treeTypeWriter.SetWriter(&writer); + // treeWriter.SetupProcessedTrackTree(); + treeTypeWriter.WriteSparseWaterfallCandidate(dataPtr); + treeTypeWriter.WriteProcessedTrack(dataPtr); + KTINFO(testlog, "Processed track saved in file"); +#endif + + // Check the results of the processing + KTProcessedTrackData& procTrack = dataPtr->Of< KTProcessedTrackData >(); + double foundFrequency = procTrack.GetStartFrequency(); + double toBeFoundFrequency = trackIntercept + trackSlope*trackStart; + double diff = foundFrequency - toBeFoundFrequency; + KTINFO(testlog, "Found a track with start frequency: " << foundFrequency << "; should be close to " << toBeFoundFrequency ); + if (std::abs(diff)>1.e5){ + KTERROR(testlog, "The difference seems too large (>1e5 Hz)! " ); + return -1; + } + KTINFO(testlog, "Track SNR: " << procTrack.GetTotalTrackSNR()); + KTINFO(testlog, "NTrackBins: " << procTrack.GetNTrackBins()); + return 0; +} diff --git a/Source/IO/BasicROOTFileWriter/KTBasicROOTTypeWriterEventAnalysis.cc b/Source/IO/BasicROOTFileWriter/KTBasicROOTTypeWriterEventAnalysis.cc index 9a2ebdb21..751ec3753 100644 --- a/Source/IO/BasicROOTFileWriter/KTBasicROOTTypeWriterEventAnalysis.cc +++ b/Source/IO/BasicROOTFileWriter/KTBasicROOTTypeWriterEventAnalysis.cc @@ -13,6 +13,7 @@ #include "KTSliceHeader.hh" #include "KTSparseWaterfallCandidateData.hh" #include "KTTIFactory.hh" +#include "KTDiscriminatedPoint.hh" #include "TAxis.h" #include "TCanvas.h" @@ -73,7 +74,7 @@ namespace Katydid return; } - const KTSparseWaterfallCandidateData::Points& points = swfcData.GetPoints(); + const KTDiscriminatedPoints& points = swfcData.GetPoints(); if (! fWriter->OpenAndVerifyFile()) return; @@ -89,7 +90,7 @@ namespace Katydid grPoints->SetMarkerColor(4); unsigned iPoint = 0; - for (KTSparseWaterfallCandidateData::Points::const_iterator pIt = points.begin(); pIt != points.end(); ++pIt) + for (KTDiscriminatedPoints::const_iterator pIt = points.begin(); pIt != points.end(); ++pIt) { grPoints->SetPoint(iPoint, pIt->fTimeInRunC, pIt->fFrequency); KTDEBUG(publog, "Point " << iPoint << ": (" << pIt->fTimeInRunC << ", " << pIt->fFrequency << ")"); diff --git a/Source/IO/CMakeLists.txt b/Source/IO/CMakeLists.txt index ab02522ed..cb8e99454 100644 --- a/Source/IO/CMakeLists.txt +++ b/Source/IO/CMakeLists.txt @@ -34,6 +34,7 @@ set (IO_SOURCEFILES if (ROOT_FOUND) set (IO_DICT_HEADERFILES DataDisplay/KTDisplayWindow.hh + Conversions/KTROOTData.hh ) set (IO_HEADERFILES @@ -69,6 +70,7 @@ if (ROOT_FOUND) set (IO_SOURCEFILES ${IO_SOURCEFILES} Conversions/KT2ROOT.cc + Conversions/KTROOTData.cc BasicROOTFileWriter/KTBasicROOTTypeWriterSpectrumAnalysis.cc BasicROOTFileWriter/KTBasicROOTTypeWriterEventAnalysis.cc BasicROOTFileWriter/KTBasicROOTTypeWriterTime.cc diff --git a/Source/IO/Conversions/KT2ROOT.cc b/Source/IO/Conversions/KT2ROOT.cc index 9f369f641..599e4236b 100644 --- a/Source/IO/Conversions/KT2ROOT.cc +++ b/Source/IO/Conversions/KT2ROOT.cc @@ -23,11 +23,13 @@ #include "KTTimeSeriesDist.hh" #include "KTTimeSeriesFFTW.hh" #include "KTTimeSeriesReal.hh" +#include "KTSparseWaterfallCandidateData.hh" #include "CClassifierResultsData.hh" #include "CMTEWithClassifierResultsData.hh" #include "CProcessedMPTData.hh" #include "CROOTData.hh" +#include "KTROOTData.hh" #include "TClonesArray.h" #include "TH1.h" @@ -610,7 +612,9 @@ namespace Katydid rootPTData.SetComponent(ptData.GetComponent()); rootPTData.SetAcquisitionID(ptData.GetAcquisitionID()); rootPTData.SetTrackID(ptData.GetTrackID()); rootPTData.SetEventID(ptData.GetEventID()); rootPTData.SetEventSequenceID(ptData.GetEventSequenceID()); rootPTData.SetIsCut(ptData.GetIsCut()); rootPTData.SetStartTimeInRunC(ptData.GetStartTimeInRunC()); rootPTData.SetStartTimeInAcq(ptData.GetStartTimeInAcq()); rootPTData.SetEndTimeInRunC(ptData.GetEndTimeInRunC()); rootPTData.SetTimeLength(ptData.GetTimeLength()); rootPTData.SetStartFrequency(ptData.GetStartFrequency()); rootPTData.SetEndFrequency(ptData.GetEndFrequency()); rootPTData.SetFrequencyWidth(ptData.GetFrequencyWidth()); - rootPTData.SetSlope(ptData.GetSlope()); rootPTData.SetIntercept(ptData.GetIntercept()); rootPTData.SetTotalPower(ptData.GetTotalPower()); + rootPTData.SetSlope(ptData.GetSlope()); rootPTData.SetIntercept(ptData.GetIntercept()); + rootPTData.SetTotalPower(ptData.GetTotalPower()); rootPTData.SetNTrackBins(ptData.GetNTrackBins()); rootPTData.SetTotalTrackSNR(ptData.GetTotalTrackSNR()); rootPTData.SetMaxTrackSNR(ptData.GetMaxTrackSNR()); rootPTData.SetTotalWideTrackSNR(ptData.GetTotalWideTrackSNR()); + rootPTData.SetNTrackBins(ptData.GetNTrackBins()); rootPTData.SetTotalTrackNUP(ptData.GetTotalTrackNUP()); rootPTData.SetMaxTrackNUP(ptData.GetMaxTrackNUP()); rootPTData.SetTotalWideTrackNUP(ptData.GetTotalWideTrackNUP()); rootPTData.SetStartTimeInRunCSigma(ptData.GetStartTimeInRunCSigma()); rootPTData.SetEndTimeInRunCSigma(ptData.GetEndTimeInRunCSigma()); rootPTData.SetTimeLengthSigma(ptData.GetTimeLengthSigma()); rootPTData.SetStartFrequencySigma(ptData.GetStartFrequencySigma()); rootPTData.SetEndFrequencySigma(ptData.GetEndFrequencySigma()); rootPTData.SetFrequencyWidthSigma(ptData.GetFrequencyWidthSigma()); rootPTData.SetSlopeSigma(ptData.GetSlopeSigma()); rootPTData.SetInterceptSigma(ptData.GetInterceptSigma()); rootPTData.SetTotalPowerSigma(ptData.GetTotalPowerSigma()); @@ -622,7 +626,9 @@ namespace Katydid ptData.SetComponent(rootPTData.GetComponent()); ptData.SetAcquisitionID(rootPTData.GetAcquisitionID()); ptData.SetTrackID(rootPTData.GetTrackID()); ptData.SetEventID(rootPTData.GetEventID()); ptData.SetEventSequenceID(rootPTData.GetEventSequenceID()); ptData.SetIsCut(rootPTData.GetIsCut()); ptData.SetStartTimeInRunC(rootPTData.GetStartTimeInRunC()); ptData.SetStartTimeInAcq(rootPTData.GetStartTimeInAcq()); ptData.SetEndTimeInRunC(rootPTData.GetEndTimeInRunC()); ptData.SetTimeLength(rootPTData.GetTimeLength()); ptData.SetStartFrequency(rootPTData.GetStartFrequency()); ptData.SetEndFrequency(rootPTData.GetEndFrequency()); ptData.SetFrequencyWidth(rootPTData.GetFrequencyWidth()); - ptData.SetSlope(rootPTData.GetSlope()); ptData.SetIntercept(rootPTData.GetIntercept()); ptData.SetTotalPower(rootPTData.GetTotalPower()); + ptData.SetSlope(rootPTData.GetSlope()); ptData.SetIntercept(rootPTData.GetIntercept()); + ptData.SetTotalPower(rootPTData.GetTotalPower()); ptData.SetNTrackBins(rootPTData.GetNTrackBins()); ptData.SetTotalTrackSNR(rootPTData.GetTotalTrackSNR()); ptData.SetMaxTrackSNR(rootPTData.GetMaxTrackSNR()); ptData.SetTotalWideTrackSNR(rootPTData.GetTotalWideTrackSNR()); + ptData.SetNTrackBins(rootPTData.GetNTrackBins()); ptData.SetTotalTrackNUP(rootPTData.GetTotalTrackNUP()); ptData.SetMaxTrackNUP(rootPTData.GetMaxTrackNUP()); ptData.SetTotalWideTrackNUP(rootPTData.GetTotalWideTrackNUP()); ptData.SetStartTimeInRunCSigma(rootPTData.GetStartTimeInRunCSigma()); ptData.SetEndTimeInRunCSigma(rootPTData.GetEndTimeInRunCSigma()); ptData.SetTimeLengthSigma(rootPTData.GetTimeLengthSigma()); ptData.SetStartFrequencySigma(rootPTData.GetStartFrequencySigma()); ptData.SetEndFrequencySigma(rootPTData.GetEndFrequencySigma()); ptData.SetFrequencyWidthSigma(rootPTData.GetFrequencyWidthSigma()); ptData.SetSlopeSigma(rootPTData.GetSlopeSigma()); ptData.SetInterceptSigma(rootPTData.GetInterceptSigma()); ptData.SetTotalPowerSigma(rootPTData.GetTotalPowerSigma()); @@ -654,6 +660,7 @@ namespace Katydid rootMTEData.SetStartTimeInRunCSigma(mteData.GetStartTimeInRunCSigma()); rootMTEData.SetEndTimeInRunCSigma(mteData.GetEndTimeInRunCSigma()); rootMTEData.SetTimeLengthSigma(mteData.GetTimeLengthSigma()); rootMTEData.SetStartFrequencySigma(mteData.GetStartFrequencySigma()); rootMTEData.SetEndFrequencySigma(mteData.GetEndFrequencySigma()); rootMTEData.SetFrequencyWidthSigma(mteData.GetFrequencyWidthSigma()); rootMTEData.SetFirstTrackID(mteData.GetFirstTrackID()); rootMTEData.SetFirstTrackTimeLength(mteData.GetFirstTrackTimeLength()); rootMTEData.SetFirstTrackFrequencyWidth(mteData.GetFirstTrackFrequencyWidth()); rootMTEData.SetFirstTrackSlope(mteData.GetFirstTrackSlope()); rootMTEData.SetFirstTrackIntercept(mteData.GetFirstTrackIntercept()); rootMTEData.SetFirstTrackTotalPower(mteData.GetFirstTrackTotalPower()); + rootMTEData.SetFirstTrackNTrackBins(mteData.GetFirstTrackNTrackBins()); rootMTEData.SetFirstTrackTotalSNR(mteData.GetFirstTrackTotalSNR()); rootMTEData.SetFirstTrackMaxSNR(mteData.GetFirstTrackMaxSNR()); rootMTEData.SetFirstTrackTotalNUP(mteData.GetFirstTrackTotalNUP()); rootMTEData.SetFirstTrackMaxNUP(mteData.GetFirstTrackMaxNUP()); rootMTEData.SetFirstTrackTotalWideSNR(mteData.GetFirstTrackTotalWideSNR()); rootMTEData.SetFirstTrackTotalWideNUP(mteData.GetFirstTrackTotalWideNUP()); rootMTEData.SetUnknownEventTopology(mteData.GetUnknownEventTopology()); Int_t nTracks = (Int_t)mteData.GetNTracks(); TClonesArray* tracks = rootMTEData.GetTracks(); @@ -677,6 +684,7 @@ namespace Katydid mteData.SetStartTimeInRunCSigma(rootMTEData.GetStartTimeInRunCSigma()); mteData.SetEndTimeInRunCSigma(rootMTEData.GetEndTimeInRunCSigma()); mteData.SetTimeLengthSigma(rootMTEData.GetTimeLengthSigma()); mteData.SetStartFrequencySigma(rootMTEData.GetStartFrequencySigma()); mteData.SetEndFrequencySigma(rootMTEData.GetEndFrequencySigma()); mteData.SetFrequencyWidthSigma(rootMTEData.GetFrequencyWidthSigma()); mteData.SetFirstTrackID(rootMTEData.GetFirstTrackID()); mteData.SetFirstTrackTimeLength(rootMTEData.GetFirstTrackTimeLength()); mteData.SetFirstTrackFrequencyWidth(rootMTEData.GetFirstTrackFrequencyWidth()); mteData.SetFirstTrackSlope(rootMTEData.GetFirstTrackSlope()); mteData.SetFirstTrackIntercept(rootMTEData.GetFirstTrackIntercept()); mteData.SetFirstTrackTotalPower(rootMTEData.GetFirstTrackTotalPower()); + mteData.SetFirstTrackNTrackBins(rootMTEData.GetFirstTrackNTrackBins()); mteData.SetFirstTrackTotalSNR(rootMTEData.GetFirstTrackTotalSNR()); mteData.SetFirstTrackMaxSNR(rootMTEData.GetFirstTrackMaxSNR()); mteData.SetFirstTrackTotalNUP(rootMTEData.GetFirstTrackTotalNUP()); mteData.SetFirstTrackMaxNUP(rootMTEData.GetFirstTrackMaxNUP()); mteData.SetFirstTrackTotalWideSNR(rootMTEData.GetFirstTrackTotalWideSNR()); mteData.SetFirstTrackTotalWideNUP(rootMTEData.GetFirstTrackTotalWideNUP()); mteData.SetUnknownEventTopology(rootMTEData.GetUnknownEventTopology()); const TClonesArray* tracks = rootMTEData.GetTracks(); Int_t nTracks = tracks->GetSize(); @@ -738,5 +746,46 @@ namespace Katydid } return; } + + void KT2ROOT::LoadSparseWaterfallCandidateData(const KTSparseWaterfallCandidateData& swfData, TSparseWaterfallCandidateData& rootSWfData) + { + rootSWfData.SetComponent(swfData.GetComponent()); + rootSWfData.SetAcquisitionID(swfData.GetAcquisitionID()); + rootSWfData.SetCandidateID(swfData.GetCandidateID()); + rootSWfData.SetTimeInRunC(swfData.GetTimeInRunC()); + rootSWfData.SetTimeLength(swfData.GetTimeLength()); + rootSWfData.SetMinFrequency(swfData.GetMinFrequency()); + rootSWfData.SetMaxFrequency(swfData.GetMaxFrequency()); + rootSWfData.SetFrequencyWidth(swfData.GetFrequencyWidth()); + + // + Int_t nPoints = (Int_t)swfData.GetPoints().size(); + TClonesArray* points = rootSWfData.GetPoints(); + points->Clear(); points->Expand(nPoints); + Int_t iPoint = 0; + for (KTDiscriminatedPoints::const_iterator pIt = swfData.GetPoints().begin(); pIt != swfData.GetPoints().end(); ++pIt) + { + Katydid::TDiscriminatedPoint* point = new((*points)[iPoint]) Katydid::TDiscriminatedPoint; + point->SetTimeInRunC(pIt->fTimeInRunC); + point->SetFrequency(pIt->fFrequency); + point->SetAmplitude(pIt->fAmplitude); + point->SetTimeInAcq(pIt->fTimeInAcq); + point->SetMean(pIt->fMean); + point->SetVariance(pIt->fVariance); + point->SetNeighborhoodAmplitude(pIt->fNeighborhoodAmplitude); + ++iPoint; + } + return; + } + + // void KT2ROOT::UnloadSparseWaterfallCandidateData(KTSparseWaterfallCandidateData& swfData, const TSparseWaterfallCandidateData& rootSWfData) + // { + // swfData.SetComponent(rootSWfData.GetComponent()); swfData.SetAcquisitionID(rootSWfData.GetAcquisitionID()); swfData.SetCandidateID(rootSWfData.GetCandidateID()); + // swfData.SetTimeInRunC(rootSWfData.GetTimeInRunC()); swfData.SetTimeLength(rootSWfData.GetTimeLength()); + // swfData.SetMinFrequency(rootSWfData.GetMinFrequency()); swfData.SetMaxFrequency(rootSWfData.GetMaxFrequency()); swfData.SetFrequencyWidth(rootSWfData.GetFrequencyWidth()); + + // TODO + // return; + // } } /* namespace Katydid */ diff --git a/Source/IO/Conversions/KT2ROOT.hh b/Source/IO/Conversions/KT2ROOT.hh index af248af6b..b19c11c5e 100644 --- a/Source/IO/Conversions/KT2ROOT.hh +++ b/Source/IO/Conversions/KT2ROOT.hh @@ -42,6 +42,11 @@ namespace Katydid class KTProcessedMPTData; class KTMultiTrackEventData; class KTClassifiedEventData; + class KTSparseWaterfallCandidateData; + class KTDiscriminatedPoint; + + class TDiscriminatedPoint; + class TSparseWaterfallCandidateData; class KT2ROOT { @@ -162,6 +167,12 @@ namespace Katydid static void LoadMTEWithClassifierResultsData(const KTMultiTrackEventData& mteData, Cicada::TMTEWithClassifierResultsData& rootMTECRData); static void UnloadMTEWithClassifierResultsData(KTMultiTrackEventData& mteData, const Cicada::TMTEWithClassifierResultsData& rootMTECRData); + //********************************* + // Sparse Waterfall Candidate Data + //********************************* + + static void LoadSparseWaterfallCandidateData(const KTSparseWaterfallCandidateData& swfData, TSparseWaterfallCandidateData& rootSWfData); + // static void UnloadSparseWaterfallCandidateData(KTSparseWaterfallCandidateData& swfData, const TSparseWaterfallCandidateData& rootSWfData); }; diff --git a/Source/IO/Conversions/KTROOTData.cc b/Source/IO/Conversions/KTROOTData.cc index 52df73f6b..b10f726bb 100644 --- a/Source/IO/Conversions/KTROOTData.cc +++ b/Source/IO/Conversions/KTROOTData.cc @@ -18,486 +18,84 @@ #include -ClassImp(Katydid::TProcessedMPTData); -ClassImp(Katydid::TProcessedTrackData); -ClassImp(Katydid::TMultiTrackEventData); -ClassImp(Katydid::TClassifiedEventData); -ClassImp(Katydid::TClassifierResultsData); +ClassImp(Katydid::TDiscriminatedPoint); +ClassImp(Katydid::TSparseWaterfallCandidateData); namespace Katydid { - //*********************** - // TProcessedTrackData - //*********************** - - TProcessedTrackData::TProcessedTrackData() : - TObject(), - fComponent(0), fTrackID(0), fEventSequenceID(-1), fIsCut(false), - fMVAClassifier(-999.), fMainband(true), - fAcquisitionID(0), - fStartTimeInRunC(0.), fStartTimeInAcq(0.), fEndTimeInRunC(0.),fTimeLength(0.), - fStartFrequency(0.), fEndFrequency(0.), fFrequencyWidth(0.), - fSlope(0.), fIntercept(0.), fTotalPower(0.), - fStartTimeInRunCSigma(0.), fEndTimeInRunCSigma(0.), fTimeLengthSigma(0.), - fStartFrequencySigma(0.), fEndFrequencySigma(0.), fFrequencyWidthSigma(0.), - fSlopeSigma(0.), fInterceptSigma(0.), fTotalPowerSigma(0.) - {} - - TProcessedTrackData::TProcessedTrackData(const KTProcessedTrackData& orig) : - TObject(), - fComponent(0), fTrackID(0), fEventSequenceID(-1), fIsCut(false), - fMVAClassifier(-999.), fMainband(true), - fAcquisitionID(0), - fStartTimeInRunC(0.), fStartTimeInAcq(0.), fEndTimeInRunC(0.),fTimeLength(0.), - fStartFrequency(0.), fEndFrequency(0.), fFrequencyWidth(0.), - fSlope(0.), fIntercept(0.), fTotalPower(0.), - fStartTimeInRunCSigma(0.), fEndTimeInRunCSigma(0.), fTimeLengthSigma(0.), - fStartFrequencySigma(0.), fEndFrequencySigma(0.), fFrequencyWidthSigma(0.), - fSlopeSigma(0.), fInterceptSigma(0.), fTotalPowerSigma(0.) - { - Load(orig); - } - - TProcessedTrackData::TProcessedTrackData(const TProcessedTrackData& orig) : - TObject(orig), - fComponent(orig.fComponent), fTrackID(orig.fTrackID), fEventID(orig.fEventID), fEventSequenceID(orig.fEventSequenceID), fIsCut(orig.fIsCut), - fStartTimeInAcq(orig.fStartTimeInAcq), fEndTimeInRunC(orig.fEndTimeInRunC),fTimeLength(orig.fTimeLength), - fAcquisitionID(orig.fAcquisitionID), - fStartTimeInRunC(orig.fStartTimeInRunC), - fStartFrequency(orig.fStartFrequency), fEndFrequency(orig.fEndFrequency), fFrequencyWidth(orig.fFrequencyWidth), - fSlope(orig.fSlope), fIntercept(orig.fIntercept), fTotalPower(orig.fTotalPower), - fStartTimeInRunCSigma(orig.fStartTimeInRunCSigma), fEndTimeInRunCSigma(orig.fEndTimeInRunCSigma), fTimeLengthSigma(orig.fTimeLengthSigma), - fStartFrequencySigma(orig.fStartFrequencySigma), fEndFrequencySigma(orig.fEndFrequencySigma), fFrequencyWidthSigma(orig.fFrequencyWidthSigma), - fSlopeSigma(orig.fSlopeSigma), fInterceptSigma(orig.fInterceptSigma), fTotalPowerSigma(orig.fTotalPowerSigma) - {} - - TProcessedTrackData::~TProcessedTrackData() - {} - - TObject* TProcessedTrackData::Clone(const char* newname) - { - TProcessedTrackData* newData = new TProcessedTrackData(*this); - return newData; - } - - TProcessedTrackData& TProcessedTrackData::operator=(const TProcessedTrackData& rhs) - { - fComponent = rhs.fComponent; fTrackID = rhs.fTrackID; fEventSequenceID = rhs.fEventSequenceID; fIsCut = rhs.fIsCut; - fMVAClassifier = rhs.fMVAClassifier; fMainband = rhs.fMainband; - fAcquisitionID = rhs.fAcquisitionID; - fStartTimeInRunC = rhs.fStartTimeInRunC; fStartTimeInAcq = rhs.fStartTimeInAcq; fEndTimeInRunC = rhs.fEndTimeInRunC; fTimeLength = rhs.fTimeLength; - fStartFrequency = rhs.fStartFrequency; fEndFrequency = rhs.fEndFrequency; fFrequencyWidth = rhs.fFrequencyWidth; - fSlope = rhs.fSlope; fIntercept = rhs.fIntercept; fTotalPower = rhs.fTotalPower; - fStartTimeInRunCSigma = rhs.fStartTimeInRunCSigma; fEndTimeInRunCSigma = rhs.fEndTimeInRunCSigma; fTimeLengthSigma = rhs.fTimeLengthSigma; - fStartFrequencySigma = rhs.fStartFrequencySigma; fEndFrequencySigma = rhs.fEndFrequencySigma; fFrequencyWidthSigma = rhs.fFrequencyWidthSigma; - fSlopeSigma = rhs.fSlopeSigma; fInterceptSigma = rhs.fInterceptSigma; fTotalPowerSigma = rhs.fTotalPowerSigma; - return *this; - } - - void TProcessedTrackData::Load(const KTProcessedTrackData& data) - { - fComponent = data.GetComponent(); fAcquisitionID = data.GetAcquisitionID(); fTrackID = data.GetTrackID(); fEventID = data.GetEventID(); fEventSequenceID = data.GetEventSequenceID(); fIsCut = data.GetIsCut(); - fMVAClassifier = data.GetMVAClassifier(); fMainband = data.GetMainband(); - fAcquisitionID = data.GetAcquisitionID(); - fStartTimeInRunC = data.GetStartTimeInRunC(); fStartTimeInAcq = data.GetStartTimeInAcq(); fEndTimeInRunC = data.GetEndTimeInRunC();fTimeLength = data.GetTimeLength(); - fStartFrequency = data.GetStartFrequency(); fEndFrequency = data.GetEndFrequency(); fFrequencyWidth = data.GetFrequencyWidth(); - fSlope = data.GetSlope(); fIntercept = data.GetIntercept(); fTotalPower = data.GetTotalPower(); - fStartTimeInRunCSigma = data.GetStartTimeInRunCSigma(); fEndTimeInRunCSigma = data.GetEndTimeInRunCSigma(); fTimeLengthSigma = data.GetTimeLengthSigma(); - fStartFrequencySigma = data.GetStartFrequencySigma(); fEndFrequencySigma = data.GetEndFrequencySigma(); fFrequencyWidthSigma = data.GetFrequencyWidthSigma(); - fSlopeSigma = data.GetSlopeSigma(); fInterceptSigma = data.GetInterceptSigma(); fTotalPowerSigma = data.GetTotalPowerSigma(); - return; - } - void TProcessedTrackData::Unload(KTProcessedTrackData& data) const - { - data.SetComponent(fComponent); data.SetAcquisitionID(fAcquisitionID); data.SetTrackID(fTrackID); data.SetEventID(fEventID); data.SetEventSequenceID(fEventSequenceID); data.SetIsCut(fIsCut); - data.SetStartTimeInRunC(fStartTimeInRunC); data.SetStartTimeInAcq(fStartTimeInAcq); data.SetEndTimeInRunC(fEndTimeInRunC); data.SetTimeLength(fTimeLength); - data.SetStartFrequency(fStartFrequency); data.SetEndFrequency(fEndFrequency); data.SetFrequencyWidth(fFrequencyWidth); - data.SetSlope(fSlope); data.SetIntercept(fIntercept); data.SetTotalPower(fTotalPower); - data.SetStartTimeInRunCSigma(fStartTimeInRunCSigma); data.SetEndTimeInRunCSigma(fEndTimeInRunCSigma); data.SetTimeLengthSigma(fTimeLengthSigma); - data.SetStartFrequencySigma(fStartFrequencySigma); data.SetEndFrequencySigma(fEndFrequencySigma); data.SetFrequencyWidthSigma(fFrequencyWidthSigma); - data.SetSlopeSigma(fSlopeSigma); data.SetInterceptSigma(fInterceptSigma); data.SetTotalPowerSigma(fTotalPowerSigma); - return; - } //*********************** - // TClassifierResultsData + // TDiscriminatedPoint //*********************** - TClassifierResultsData::TClassifierResultsData() : + TDiscriminatedPoint::TDiscriminatedPoint() : TObject(), - fComponent(0), fMainCarrierHigh(0), fMainCarrierLow(0), fSideBand(0) + fTimeInRunC(0), fFrequency(0), fAmplitude(0), fTimeInAcq(0), + fMean(0), fVariance(0),fNeighborhoodAmplitude(0) {} - TClassifierResultsData::TClassifierResultsData(const KTClassifierResultsData& orig) : - TObject(), - fComponent(0), fMainCarrierHigh(0), fMainCarrierLow(0), fSideBand(0) - { - Load(orig); - } - - TClassifierResultsData::TClassifierResultsData(const TClassifierResultsData& orig) : - TObject(orig), - fComponent(orig.fComponent), fMainCarrierHigh(orig.fMainCarrierHigh), fMainCarrierLow(orig.fMainCarrierLow), fSideBand(orig.fSideBand) - {} - - TClassifierResultsData::~TClassifierResultsData() - {} - - TObject* TClassifierResultsData::Clone(const char* newname) - { - TClassifierResultsData* newData = new TClassifierResultsData(*this); - return newData; - } - - TClassifierResultsData& TClassifierResultsData::operator=(const TClassifierResultsData& rhs) - { - fComponent = rhs.fComponent; fMainCarrierHigh = rhs.fMainCarrierHigh; fMainCarrierLow = rhs.fMainCarrierLow; fSideBand = rhs.fSideBand; - return *this; - } - - void TClassifierResultsData::Load(const KTClassifierResultsData& data) - { - fComponent = data.GetComponent(); fMainCarrierHigh = data.GetMainCarrierHigh(); fMainCarrierLow = data.GetMainCarrierLow(); fSideBand = data.GetSideBand(); - return; - } - void TClassifierResultsData::Unload(KTClassifierResultsData& data) const - { - data.SetComponent(fComponent); data.SetMainCarrierHigh(fMainCarrierHigh); data.SetMainCarrierLow(fMainCarrierLow); data.SetSideBand(fSideBand); - return; - } - - - //*********************** - // TProcessedMPTData - //*********************** - - TProcessedMPTData::TProcessedMPTData() : - TObject(), - fComponent(0), fTrackID(0), fEventSequenceID(-1), fIsCut(false), - fMVAClassifier(-999.), fMainband(true), fAxialFrequency(0.), - fAcquisitionID(0), - fStartTimeInRunC(0.), fStartTimeInAcq(0.), fEndTimeInRunC(0.),fTimeLength(0.), - fStartFrequency(0.), fEndFrequency(0.), fFrequencyWidth(0.), - fSlope(0.), fIntercept(0.), fTotalPower(0.), - fStartTimeInRunCSigma(0.), fEndTimeInRunCSigma(0.), fTimeLengthSigma(0.), - fStartFrequencySigma(0.), fEndFrequencySigma(0.), fFrequencyWidthSigma(0.), - fSlopeSigma(0.), fInterceptSigma(0.), fTotalPowerSigma(0.) - {} - - TProcessedMPTData::TProcessedMPTData(const KTProcessedMPTData& orig) : - TObject(), - fComponent(0), fTrackID(0), fEventSequenceID(-1), fIsCut(false), - fMVAClassifier(-999.), fMainband(true), fAxialFrequency(0.), - fAcquisitionID(0), - fStartTimeInRunC(0.), fStartTimeInAcq(0.), fEndTimeInRunC(0.),fTimeLength(0.), - fStartFrequency(0.), fEndFrequency(0.), fFrequencyWidth(0.), - fSlope(0.), fIntercept(0.), fTotalPower(0.), - fStartTimeInRunCSigma(0.), fEndTimeInRunCSigma(0.), fTimeLengthSigma(0.), - fStartFrequencySigma(0.), fEndFrequencySigma(0.), fFrequencyWidthSigma(0.), - fSlopeSigma(0.), fInterceptSigma(0.), fTotalPowerSigma(0.) - { - Load(orig); - } - - TProcessedMPTData::TProcessedMPTData(const TProcessedMPTData& orig) : + TDiscriminatedPoint::TDiscriminatedPoint(const TDiscriminatedPoint& orig) : TObject(orig), - fComponent(orig.fComponent), fTrackID(orig.fTrackID), fEventSequenceID(orig.fEventSequenceID), fIsCut(orig.fIsCut), - fMVAClassifier(orig.fMVAClassifier), fMainband(orig.fMainband), fAxialFrequency(orig.fAxialFrequency), - fAcquisitionID(orig.fAcquisitionID), - fStartTimeInRunC(orig.fStartTimeInRunC), fStartTimeInAcq(orig.fStartTimeInAcq), fEndTimeInRunC(orig.fEndTimeInRunC), fTimeLength(orig.fTimeLength), - fStartFrequency(orig.fStartFrequency), fEndFrequency(orig.fEndFrequency), fFrequencyWidth(orig.fFrequencyWidth), - fSlope(orig.fSlope), fIntercept(orig.fIntercept), fTotalPower(orig.fTotalPower), - fStartTimeInRunCSigma(orig.fStartTimeInRunCSigma), fEndTimeInRunCSigma(orig.fEndTimeInRunCSigma), fTimeLengthSigma(orig.fTimeLengthSigma), - fStartFrequencySigma(orig.fStartFrequencySigma), fEndFrequencySigma(orig.fEndFrequencySigma), fFrequencyWidthSigma(orig.fFrequencyWidthSigma), - fSlopeSigma(orig.fSlopeSigma), fInterceptSigma(orig.fInterceptSigma), fTotalPowerSigma(orig.fTotalPowerSigma) + fTimeInRunC(orig.fTimeInRunC), fFrequency(orig.fFrequency), fAmplitude(orig.fAmplitude), fTimeInAcq(orig.fTimeInAcq), + fMean(orig.fMean), fVariance(orig.fVariance),fNeighborhoodAmplitude(orig.fNeighborhoodAmplitude) {} - TProcessedMPTData::~TProcessedMPTData() + TDiscriminatedPoint::~TDiscriminatedPoint() {} - TObject* TProcessedMPTData::Clone(const char* newname) + TObject* TDiscriminatedPoint::Clone(const char* newname) { - TProcessedMPTData* newData = new TProcessedMPTData(*this); + TDiscriminatedPoint* newData = new TDiscriminatedPoint(*this); return newData; } - TProcessedMPTData& TProcessedMPTData::operator=(const TProcessedMPTData& rhs) + TDiscriminatedPoint& TDiscriminatedPoint::operator=(const TDiscriminatedPoint& rhs) { - fComponent = rhs.fComponent; fTrackID = rhs.fTrackID; fEventSequenceID = rhs.fEventSequenceID; fIsCut = rhs.fIsCut; - fMVAClassifier = rhs.fMVAClassifier; fMainband = rhs.fMainband; fAxialFrequency = rhs.fAxialFrequency; - fAcquisitionID = rhs.fAcquisitionID; - fStartTimeInRunC = rhs.fStartTimeInRunC; fStartTimeInAcq = rhs.fStartTimeInAcq; fEndTimeInRunC = rhs.fEndTimeInRunC; fTimeLength = rhs.fTimeLength; - fStartFrequency = rhs.fStartFrequency; fEndFrequency = rhs.fEndFrequency; fFrequencyWidth = rhs.fFrequencyWidth; - fSlope = rhs.fSlope; fIntercept = rhs.fIntercept; fTotalPower = rhs.fTotalPower; - fStartTimeInRunCSigma = rhs.fStartTimeInRunCSigma; fEndTimeInRunCSigma = rhs.fEndTimeInRunCSigma; fTimeLengthSigma = rhs.fTimeLengthSigma; - fStartFrequencySigma = rhs.fStartFrequencySigma; fEndFrequencySigma = rhs.fEndFrequencySigma; fFrequencyWidthSigma = rhs.fFrequencyWidthSigma; - fSlopeSigma = rhs.fSlopeSigma; fInterceptSigma = rhs.fInterceptSigma; fTotalPowerSigma = rhs.fTotalPowerSigma; + fTimeInRunC = rhs.fTimeInRunC; fFrequency = rhs.fFrequency; fAmplitude = rhs.fAmplitude; fTimeInAcq = rhs.fTimeInAcq; + fMean = rhs.fMean; fVariance = rhs.fVariance; fNeighborhoodAmplitude = rhs.fNeighborhoodAmplitude; return *this; } - void TProcessedMPTData::Load(const KTProcessedMPTData& data) - { - fComponent = data.GetComponent(); fTrackID = data.GetMainTrack().GetTrackID(); fEventSequenceID = data.GetMainTrack().GetEventSequenceID(); fIsCut = data.GetMainTrack().GetIsCut(); - fMVAClassifier = data.GetMainTrack().GetMVAClassifier(); fMainband = data.GetMainTrack().GetMainband(); fAxialFrequency = data.GetAxialFrequency(); - fAcquisitionID = data.GetMainTrack().GetAcquisitionID(); - fStartTimeInRunC = data.GetMainTrack().GetStartTimeInRunC(); fStartTimeInAcq = data.GetMainTrack().GetStartTimeInAcq(); fEndTimeInRunC = data.GetMainTrack().GetEndTimeInRunC(); fTimeLength = data.GetMainTrack().GetTimeLength(); - fStartFrequency = data.GetMainTrack().GetStartFrequency(); fEndFrequency = data.GetMainTrack().GetEndFrequency(); fFrequencyWidth = data.GetMainTrack().GetFrequencyWidth(); - fSlope = data.GetMainTrack().GetSlope(); fIntercept = data.GetMainTrack().GetIntercept(); fTotalPower = data.GetMainTrack().GetTotalPower(); - fStartTimeInRunCSigma = data.GetMainTrack().GetStartTimeInRunCSigma(); fEndTimeInRunCSigma = data.GetMainTrack().GetEndTimeInRunCSigma(); fTimeLengthSigma = data.GetMainTrack().GetTimeLengthSigma(); - fStartFrequencySigma = data.GetMainTrack().GetStartFrequencySigma(); fEndFrequencySigma = data.GetMainTrack().GetEndFrequencySigma(); fFrequencyWidthSigma = data.GetMainTrack().GetFrequencyWidthSigma(); - fSlopeSigma = data.GetMainTrack().GetSlopeSigma(); fInterceptSigma = data.GetMainTrack().GetInterceptSigma(); fTotalPowerSigma = data.GetMainTrack().GetTotalPowerSigma(); - return; - } - void TProcessedMPTData::Unload(KTProcessedMPTData& mptData) const - { - KTProcessedTrackData* data = new KTProcessedTrackData(); - - data->SetComponent(fComponent); data->SetTrackID(fTrackID); data->SetEventSequenceID(fEventSequenceID); data->SetIsCut(fIsCut); - data->SetMVAClassifier(fMVAClassifier); data->SetMainband(fMainband); - data->SetAcquisitionID(fAcquisitionID); - data->SetStartTimeInRunC(fStartTimeInRunC); data->SetStartTimeInAcq(fStartTimeInAcq); data->SetEndTimeInRunC(fEndTimeInRunC); data->SetTimeLength(fTimeLength); - data->SetStartFrequency(fStartFrequency); data->SetEndFrequency(fEndFrequency); data->SetFrequencyWidth(fFrequencyWidth); - data->SetSlope(fSlope); data->SetIntercept(fIntercept); data->SetTotalPower(fTotalPower); - data->SetStartTimeInRunCSigma(fStartTimeInRunCSigma); data->SetEndTimeInRunCSigma(fEndTimeInRunCSigma); data->SetTimeLengthSigma(fTimeLengthSigma); - data->SetStartFrequencySigma(fStartFrequencySigma); data->SetEndFrequencySigma(fEndFrequencySigma); data->SetFrequencyWidthSigma(fFrequencyWidthSigma); - data->SetSlopeSigma(fSlopeSigma); data->SetInterceptSigma(fInterceptSigma); data->SetTotalPowerSigma(fTotalPowerSigma); - - mptData.SetComponent(fComponent); - mptData.SetMainTrack(*data); - mptData.SetAxialFrequency(fAxialFrequency); - return; - } - - //************************ - // TMultiTrackEventData + // TSparseWaterfallCandidate //************************ - TMultiTrackEventData::TMultiTrackEventData() : - fComponent(0), fAcquisitionID(0), fEventID(0), fTotalEventSequences(0), - fStartTimeInRunC(0.), fStartTimeInAcq(0.), fEndTimeInRunC(0.),fTimeLength(0.), - fStartFrequency(0.), fEndFrequency(0.), fMinimumFrequency(0.), fMaximumFrequency(0.), fFrequencyWidth(0.), - fStartTimeInRunCSigma(0.), fEndTimeInRunCSigma(0.), fTimeLengthSigma(0.), - fStartFrequencySigma(0.), fEndFrequencySigma(0.), fFrequencyWidthSigma(0.), - fFirstTrackID(0), fFirstTrackTimeLength(0.), fFirstTrackFrequencyWidth(0.), fFirstTrackSlope(0.), fFirstTrackIntercept(0.), fFirstTrackTotalPower(0.), - fUnknownEventTopology(false) - { - // this cannot be initialized in the initializer list because ROOT - fTracks = new TClonesArray("Katydid::TProcessedTrackData", 20); - } - - TMultiTrackEventData::TMultiTrackEventData(const TMultiTrackEventData& orig) : - fComponent(orig.fComponent), fAcquisitionID(orig.fAcquisitionID), fEventID(orig.fEventID), fTotalEventSequences(orig.fTotalEventSequences), - fStartTimeInRunC(orig.fStartTimeInRunC), fStartTimeInAcq(orig.fStartTimeInAcq), fEndTimeInRunC(orig.fEndTimeInRunC),fTimeLength(orig.fTimeLength), - fStartFrequency(orig.fStartFrequency), fEndFrequency(orig.fEndFrequency), fMinimumFrequency(orig.fMaximumFrequency), fMaximumFrequency(orig.fMinimumFrequency), fFrequencyWidth(orig.fFrequencyWidth), - fStartTimeInRunCSigma(orig.fStartTimeInRunCSigma), fEndTimeInRunCSigma(orig.fEndTimeInRunCSigma), fTimeLengthSigma(orig.fTimeLengthSigma), - fStartFrequencySigma(orig.fStartFrequencySigma), fEndFrequencySigma(orig.fEndFrequencySigma), fFrequencyWidthSigma(orig.fFrequencyWidthSigma), - fFirstTrackID(orig.fFirstTrackID), fFirstTrackTimeLength(orig.fFirstTrackTimeLength), fFirstTrackFrequencyWidth(orig.fFirstTrackFrequencyWidth), fFirstTrackSlope(orig.fFirstTrackSlope), fFirstTrackIntercept(orig.fFirstTrackIntercept), fFirstTrackTotalPower(orig.fFirstTrackTotalPower), - fUnknownEventTopology(orig.fUnknownEventTopology) - { - // this cannot be initialized in the initializer list because ROOT - fTracks = new TClonesArray(*orig.fTracks); - } - - TMultiTrackEventData::TMultiTrackEventData(const KTMultiTrackEventData& orig) : - fComponent(0), fAcquisitionID(0), fEventID(0), fTotalEventSequences(0), - fStartTimeInRunC(0.), fStartTimeInAcq(0.), fEndTimeInRunC(0.),fTimeLength(0.), - fStartFrequency(0.), fEndFrequency(0.), fMinimumFrequency(0.), fMaximumFrequency(0.), fFrequencyWidth(0.), - fStartTimeInRunCSigma(0.), fEndTimeInRunCSigma(0.), fTimeLengthSigma(0.), - fStartFrequencySigma(0.), fEndFrequencySigma(0.), fFrequencyWidthSigma(0.), - fFirstTrackID(0), fFirstTrackTimeLength(0.), fFirstTrackFrequencyWidth(0.), fFirstTrackSlope(0.), fFirstTrackIntercept(0.), fFirstTrackTotalPower(0.), - fUnknownEventTopology(false) - { - // this cannot be initialized in the initializer list because ROOT - fTracks = new TClonesArray("Katydid::TProcessedTrackData", 20); - Load(orig); - } - - TMultiTrackEventData::~TMultiTrackEventData() - { - fTracks->Clear(); - } - - TObject* TMultiTrackEventData::Clone(const char* newname) - { - TMultiTrackEventData* newData = new TMultiTrackEventData(*this); - return newData; - } - - TMultiTrackEventData& TMultiTrackEventData::operator=(const TMultiTrackEventData& rhs) - { - fComponent = rhs.fComponent; fAcquisitionID = rhs.fAcquisitionID; fEventID = rhs.fEventID; fTotalEventSequences = rhs.fTotalEventSequences; - fStartTimeInRunC = rhs.fStartTimeInRunC; fStartTimeInAcq = rhs.fStartTimeInAcq; fEndTimeInRunC = rhs.fEndTimeInRunC;fTimeLength = rhs.fTimeLength; - fStartFrequency = rhs.fStartFrequency; fEndFrequency = rhs.fEndFrequency; fMinimumFrequency = rhs.fMinimumFrequency; fMaximumFrequency = rhs.fMaximumFrequency; fFrequencyWidth = rhs.fFrequencyWidth; - fStartTimeInRunCSigma = rhs.fStartTimeInRunCSigma; fEndTimeInRunCSigma = rhs.fEndTimeInRunCSigma; fTimeLengthSigma = rhs.fTimeLengthSigma; - fStartFrequencySigma = rhs.fStartFrequencySigma; fEndFrequencySigma = rhs.fEndFrequencySigma; fFrequencyWidthSigma = rhs.fFrequencyWidthSigma; - fFirstTrackID = rhs.fFirstTrackID; fFirstTrackTimeLength = rhs.fFirstTrackTimeLength; fFirstTrackFrequencyWidth = rhs.fFirstTrackFrequencyWidth; fFirstTrackSlope = rhs.fFirstTrackSlope; fFirstTrackIntercept = rhs.fFirstTrackIntercept; fFirstTrackTotalPower = rhs.fFirstTrackTotalPower; - fUnknownEventTopology = rhs.fUnknownEventTopology; - fTracks->Clear(); (*fTracks) = *(rhs.fTracks); - return *this; - } - - void TMultiTrackEventData::Load(const KTMultiTrackEventData& data) - { - fComponent = data.GetComponent(); fAcquisitionID = data.GetAcquisitionID(); fEventID = data.GetEventID(); fTotalEventSequences = data.GetTotalEventSequences(); - fStartTimeInRunC = data.GetStartTimeInRunC(); fStartTimeInAcq = data.GetStartTimeInAcq(); fEndTimeInRunC = data.GetEndTimeInRunC();fTimeLength = data.GetTimeLength(); - fStartFrequency = data.GetStartFrequency(); fEndFrequency = data.GetEndFrequency(); fMinimumFrequency = data.GetMinimumFrequency(); fMaximumFrequency = data.GetMaximumFrequency(); fFrequencyWidth = data.GetFrequencyWidth(); - fStartTimeInRunCSigma = data.GetStartTimeInRunCSigma(); fEndTimeInRunCSigma = data.GetEndTimeInRunCSigma(); fTimeLengthSigma = data.GetTimeLengthSigma(); - fStartFrequencySigma = data.GetStartFrequencySigma(); fEndFrequencySigma = data.GetEndFrequencySigma(); fFrequencyWidthSigma = data.GetFrequencyWidthSigma(); - fFirstTrackID = data.GetFirstTrackID(); fFirstTrackTimeLength = data.GetFirstTrackTimeLength(); fFirstTrackFrequencyWidth = data.GetFirstTrackFrequencyWidth(); fFirstTrackSlope = data.GetFirstTrackSlope(); fFirstTrackIntercept = data.GetFirstTrackIntercept(); fFirstTrackTotalPower = data.GetFirstTrackTotalPower(); - fUnknownEventTopology = data.GetUnknownEventTopology(); - Int_t nTracks = (Int_t)data.GetNTracks(); - fTracks->Clear(); fTracks->Expand(nTracks); - Int_t iTrack = 0; - for (TrackSetCIt trIt = data.GetTracksBegin(); trIt != data.GetTracksEnd(); ++trIt) - { - TProcessedTrackData* track = new((*fTracks)[iTrack]) TProcessedTrackData(trIt->fProcTrack); - ++iTrack; - } - return; - } - void TMultiTrackEventData::Unload(KTMultiTrackEventData& data) const - { - data.ClearTracks(); // do this first, since it clears some of the member variables other than just fTracks - data.SetComponent(fComponent); data.SetAcquisitionID(fAcquisitionID); data.SetEventID(fEventID); data.SetTotalEventSequences(fTotalEventSequences); - data.SetStartTimeInRunC(fStartTimeInRunC); data.SetStartTimeInAcq(fStartTimeInAcq); data.SetEndTimeInRunC(fEndTimeInRunC); data.SetTimeLength(fTimeLength); - data.SetStartFrequency(fStartFrequency); data.SetEndFrequency(fEndFrequency); data.SetMinimumFrequency(fMinimumFrequency); data.SetMaximumFrequency(fMaximumFrequency); data.SetFrequencyWidth(fFrequencyWidth); - data.SetStartTimeInRunCSigma(fStartTimeInRunCSigma); data.SetEndTimeInRunCSigma(fEndTimeInRunCSigma); data.SetTimeLengthSigma(fTimeLengthSigma); - data.SetStartFrequencySigma(fStartFrequencySigma); data.SetEndFrequencySigma(fEndFrequencySigma); data.SetFrequencyWidthSigma(fFrequencyWidthSigma); - data.SetFirstTrackID(fFirstTrackID); data.SetFirstTrackTimeLength(fFirstTrackTimeLength); data.SetFirstTrackFrequencyWidth(fFirstTrackFrequencyWidth); data.SetFirstTrackSlope(fFirstTrackSlope); data.SetFirstTrackIntercept(fFirstTrackIntercept); data.SetFirstTrackTotalPower(fFirstTrackTotalPower); - data.SetUnknownEventTopology(fUnknownEventTopology); - - Int_t nTracks = fTracks->GetSize(); - Nymph::KTDataPtr dummyData; - KTProcessedTrackData& procTrack = dummyData->Of< KTProcessedTrackData >(); - AllTrackData track( dummyData, procTrack ); - - for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack) - { - ((TProcessedTrackData*)((*fTracks)[iTrack]))->Unload(procTrack); - data.AddTrack(track); - } - return; - } - - //************************ - // TClassifiedEventData - //************************ - - TClassifiedEventData::TClassifiedEventData() : - fComponent(0), fAcquisitionID(0), fEventID(0), fTotalEventSequences(0), - fStartTimeInRunC(0.), fStartTimeInAcq(0.), fEndTimeInRunC(0.),fTimeLength(0.), - fStartFrequency(0.), fEndFrequency(0.), fMinimumFrequency(0.), fMaximumFrequency(0.), fFrequencyWidth(0.), - fStartTimeInRunCSigma(0.), fEndTimeInRunCSigma(0.), fTimeLengthSigma(0.), - fStartFrequencySigma(0.), fEndFrequencySigma(0.), fFrequencyWidthSigma(0.), - fFirstTrackID(0), fFirstTrackTimeLength(0.), fFirstTrackFrequencyWidth(0.), fFirstTrackSlope(0.), fFirstTrackIntercept(0.), fFirstTrackTotalPower(0.), - fUnknownEventTopology(false) - { - // this cannot be initialized in the initializer list because ROOT - fTracks = new TClonesArray("Katydid::TProcessedTrackData", 20); - fClassifierResults = new TClonesArray("Katydid::TClassifierResultsData", 20); - } - - TClassifiedEventData::TClassifiedEventData(const TClassifiedEventData& orig) : - fComponent(orig.fComponent), fAcquisitionID(orig.fAcquisitionID), fEventID(orig.fEventID), fTotalEventSequences(orig.fTotalEventSequences), - fStartTimeInRunC(orig.fStartTimeInRunC), fStartTimeInAcq(orig.fStartTimeInAcq), fEndTimeInRunC(orig.fEndTimeInRunC),fTimeLength(orig.fTimeLength), - fStartFrequency(orig.fStartFrequency), fEndFrequency(orig.fEndFrequency), fMinimumFrequency(orig.fMaximumFrequency), fMaximumFrequency(orig.fMinimumFrequency), fFrequencyWidth(orig.fFrequencyWidth), - fStartTimeInRunCSigma(orig.fStartTimeInRunCSigma), fEndTimeInRunCSigma(orig.fEndTimeInRunCSigma), fTimeLengthSigma(orig.fTimeLengthSigma), - fStartFrequencySigma(orig.fStartFrequencySigma), fEndFrequencySigma(orig.fEndFrequencySigma), fFrequencyWidthSigma(orig.fFrequencyWidthSigma), - fFirstTrackID(orig.fFirstTrackID), fFirstTrackTimeLength(orig.fFirstTrackTimeLength), fFirstTrackFrequencyWidth(orig.fFirstTrackFrequencyWidth), fFirstTrackSlope(orig.fFirstTrackSlope), fFirstTrackIntercept(orig.fFirstTrackIntercept), fFirstTrackTotalPower(orig.fFirstTrackTotalPower), - fUnknownEventTopology(orig.fUnknownEventTopology) + TSparseWaterfallCandidateData::TSparseWaterfallCandidateData() : + TObject(), + fComponent(0), fAcquisitionID(0), fCandidateID(0), + fTimeInRunC(0.), fTimeLength(0.), + fMinFrequency(0.), fMaxFrequency(0.), fFrequencyWidth(0.) { // this cannot be initialized in the initializer list because ROOT - fTracks = new TClonesArray(*orig.fTracks); - fClassifierResults = new TClonesArray(*orig.fClassifierResults); + fPoints = new TClonesArray("Katydid::TDiscriminatedPoint", 20); } - TClassifiedEventData::TClassifiedEventData(const KTMultiTrackEventData& orig) : - fComponent(0), fAcquisitionID(0), fEventID(0), fTotalEventSequences(0), - fStartTimeInRunC(0.), fStartTimeInAcq(0.), fEndTimeInRunC(0.),fTimeLength(0.), - fStartFrequency(0.), fEndFrequency(0.), fMinimumFrequency(0.), fMaximumFrequency(0.), fFrequencyWidth(0.), - fStartTimeInRunCSigma(0.), fEndTimeInRunCSigma(0.), fTimeLengthSigma(0.), - fStartFrequencySigma(0.), fEndFrequencySigma(0.), fFrequencyWidthSigma(0.), - fFirstTrackID(0), fFirstTrackTimeLength(0.), fFirstTrackFrequencyWidth(0.), fFirstTrackSlope(0.), fFirstTrackIntercept(0.), fFirstTrackTotalPower(0.), - fUnknownEventTopology(false) + TSparseWaterfallCandidateData::TSparseWaterfallCandidateData(const TSparseWaterfallCandidateData& orig) : + fComponent(orig.fComponent), fAcquisitionID(orig.fAcquisitionID), fCandidateID(orig.fCandidateID), + fTimeInRunC(orig.fTimeInRunC), fTimeLength(orig.fTimeLength), + fMinFrequency(orig.fMinFrequency), fMaxFrequency(orig.fMaxFrequency), fFrequencyWidth(orig.fFrequencyWidth) { // this cannot be initialized in the initializer list because ROOT - fTracks = new TClonesArray("Katydid::TProcessedTrackData", 20); - fClassifierResults = new TClonesArray("Katydid::TClassifierResultsData", 20); - Load(orig); + fPoints = new TClonesArray(*orig.fPoints); } - TClassifiedEventData::~TClassifiedEventData() + TSparseWaterfallCandidateData::~TSparseWaterfallCandidateData() { - fTracks->Clear(); - fClassifierResults->Clear(); + fPoints->Clear(); } - TObject* TClassifiedEventData::Clone(const char* newname) + TObject* TSparseWaterfallCandidateData::Clone(const char* newname) { - TClassifiedEventData* newData = new TClassifiedEventData(*this); + TSparseWaterfallCandidateData* newData = new TSparseWaterfallCandidateData(*this); return newData; } - TClassifiedEventData& TClassifiedEventData::operator=(const TClassifiedEventData& rhs) + TSparseWaterfallCandidateData& TSparseWaterfallCandidateData::operator=(const TSparseWaterfallCandidateData& rhs) { - fComponent = rhs.fComponent; fAcquisitionID = rhs.fAcquisitionID; fEventID = rhs.fEventID; fTotalEventSequences = rhs.fTotalEventSequences; - fStartTimeInRunC = rhs.fStartTimeInRunC; fStartTimeInAcq = rhs.fStartTimeInAcq; fEndTimeInRunC = rhs.fEndTimeInRunC;fTimeLength = rhs.fTimeLength; - fStartFrequency = rhs.fStartFrequency; fEndFrequency = rhs.fEndFrequency; fMinimumFrequency = rhs.fMinimumFrequency; fMaximumFrequency = rhs.fMaximumFrequency; fFrequencyWidth = rhs.fFrequencyWidth; - fStartTimeInRunCSigma = rhs.fStartTimeInRunCSigma; fEndTimeInRunCSigma = rhs.fEndTimeInRunCSigma; fTimeLengthSigma = rhs.fTimeLengthSigma; - fStartFrequencySigma = rhs.fStartFrequencySigma; fEndFrequencySigma = rhs.fEndFrequencySigma; fFrequencyWidthSigma = rhs.fFrequencyWidthSigma; - fFirstTrackID = rhs.fFirstTrackID; fFirstTrackTimeLength = rhs.fFirstTrackTimeLength; fFirstTrackFrequencyWidth = rhs.fFirstTrackFrequencyWidth; fFirstTrackSlope = rhs.fFirstTrackSlope; fFirstTrackIntercept = rhs.fFirstTrackIntercept; fFirstTrackTotalPower = rhs.fFirstTrackTotalPower; - fUnknownEventTopology = rhs.fUnknownEventTopology; - fTracks->Clear(); (*fTracks) = *(rhs.fTracks); - fClassifierResults->Clear(); (*fClassifierResults) = *(rhs.fClassifierResults); + fComponent = rhs.fComponent; fAcquisitionID = rhs.fAcquisitionID; fCandidateID = rhs.fCandidateID; + fTimeInRunC = rhs.fTimeInRunC; fTimeLength = rhs.fTimeLength; + fMinFrequency = rhs.fMinFrequency; fMaxFrequency = rhs.fMaxFrequency; fFrequencyWidth = rhs.fFrequencyWidth; + fPoints->Clear(); (*fPoints) = *(rhs.fPoints); return *this; } - - void TClassifiedEventData::Load(const KTMultiTrackEventData& data) - { - fComponent = data.GetComponent(); fAcquisitionID = data.GetAcquisitionID(); fEventID = data.GetEventID(); fTotalEventSequences = data.GetTotalEventSequences(); - fStartTimeInRunC = data.GetStartTimeInRunC(); fStartTimeInAcq = data.GetStartTimeInAcq(); fEndTimeInRunC = data.GetEndTimeInRunC();fTimeLength = data.GetTimeLength(); - fStartFrequency = data.GetStartFrequency(); fEndFrequency = data.GetEndFrequency(); fMinimumFrequency = data.GetMinimumFrequency(); fMaximumFrequency = data.GetMaximumFrequency(); fFrequencyWidth = data.GetFrequencyWidth(); - fStartTimeInRunCSigma = data.GetStartTimeInRunCSigma(); fEndTimeInRunCSigma = data.GetEndTimeInRunCSigma(); fTimeLengthSigma = data.GetTimeLengthSigma(); - fStartFrequencySigma = data.GetStartFrequencySigma(); fEndFrequencySigma = data.GetEndFrequencySigma(); fFrequencyWidthSigma = data.GetFrequencyWidthSigma(); - fFirstTrackID = data.GetFirstTrackID(); fFirstTrackTimeLength = data.GetFirstTrackTimeLength(); fFirstTrackFrequencyWidth = data.GetFirstTrackFrequencyWidth(); fFirstTrackSlope = data.GetFirstTrackSlope(); fFirstTrackIntercept = data.GetFirstTrackIntercept(); fFirstTrackTotalPower = data.GetFirstTrackTotalPower(); - fUnknownEventTopology = data.GetUnknownEventTopology(); - Int_t nTracks = (Int_t)data.GetNTracks(); - fTracks->Clear(); fTracks->Expand(nTracks); - fClassifierResults->Clear(); fClassifierResults->Expand(nTracks); - Int_t iTrack = 0; - for (TrackSetCIt trIt = data.GetTracksBegin(); trIt != data.GetTracksEnd(); ++trIt) - { - TProcessedTrackData* track = new((*fTracks)[iTrack]) TProcessedTrackData(trIt->fProcTrack); - TClassifierResultsData* classifier = new((*fClassifierResults)[iTrack]) TClassifierResultsData(trIt->fData->Of< KTClassifierResultsData >()); - ++iTrack; - } - return; - } - void TClassifiedEventData::Unload(KTMultiTrackEventData& data) const - { - data.ClearTracks(); // do this first, since it clears some of the member variables other than just fTracks - data.SetComponent(fComponent); data.SetAcquisitionID(fAcquisitionID); data.SetEventID(fEventID); data.SetTotalEventSequences(fTotalEventSequences); - data.SetStartTimeInRunC(fStartTimeInRunC); data.SetStartTimeInAcq(fStartTimeInAcq); data.SetEndTimeInRunC(fEndTimeInRunC); data.SetTimeLength(fTimeLength); - data.SetStartFrequency(fStartFrequency); data.SetEndFrequency(fEndFrequency); data.SetMinimumFrequency(fMinimumFrequency); data.SetMaximumFrequency(fMaximumFrequency); data.SetFrequencyWidth(fFrequencyWidth); - data.SetStartTimeInRunCSigma(fStartTimeInRunCSigma); data.SetEndTimeInRunCSigma(fEndTimeInRunCSigma); data.SetTimeLengthSigma(fTimeLengthSigma); - data.SetStartFrequencySigma(fStartFrequencySigma); data.SetEndFrequencySigma(fEndFrequencySigma); data.SetFrequencyWidthSigma(fFrequencyWidthSigma); - data.SetFirstTrackID(fFirstTrackID); data.SetFirstTrackTimeLength(fFirstTrackTimeLength); data.SetFirstTrackFrequencyWidth(fFirstTrackFrequencyWidth); data.SetFirstTrackSlope(fFirstTrackSlope); data.SetFirstTrackIntercept(fFirstTrackIntercept); data.SetFirstTrackTotalPower(fFirstTrackTotalPower); - data.SetUnknownEventTopology(fUnknownEventTopology); - - Int_t nTracks = fTracks->GetSize(); - Nymph::KTDataPtr dummyData; - KTProcessedTrackData& procTrack = dummyData->Of< KTProcessedTrackData >(); - KTClassifierResultsData& classData = dummyData->Of< KTClassifierResultsData >(); - AllTrackData track( dummyData, procTrack ); - - for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack) - { - ((TProcessedTrackData*)((*fTracks)[iTrack]))->Unload(procTrack); - ((TClassifierResultsData*)((*fClassifierResults)[iTrack]))->Unload(classData); - data.AddTrack(track); - } - return; - } - } diff --git a/Source/IO/Conversions/KTROOTData.hh b/Source/IO/Conversions/KTROOTData.hh index a1bf33bd1..03c2d5173 100644 --- a/Source/IO/Conversions/KTROOTData.hh +++ b/Source/IO/Conversions/KTROOTData.hh @@ -20,259 +20,319 @@ namespace Katydid // TProcessedTrackData //*********************** - class KTProcessedTrackData; - - class TProcessedTrackData : public TObject - { - MEMBERVARIABLE(UInt_t, Component); - MEMBERVARIABLE(UInt_t, AcquisitionID); - MEMBERVARIABLE(UInt_t, TrackID); - MEMBERVARIABLE(UInt_t, EventID); - MEMBERVARIABLE(Int_t, EventSequenceID); - - MEMBERVARIABLE(Bool_t, IsCut); - - MEMBERVARIABLE(Double_t, MVAClassifier); - MEMBERVARIABLE(Bool_t, Mainband); - - MEMBERVARIABLE(Double_t, StartTimeInRunC); - MEMBERVARIABLE(Double_t, StartTimeInAcq); - MEMBERVARIABLE(Double_t, EndTimeInRunC); - MEMBERVARIABLE(Double_t, TimeLength); - MEMBERVARIABLE(Double_t, StartFrequency); - MEMBERVARIABLE(Double_t, EndFrequency); - MEMBERVARIABLE(Double_t, FrequencyWidth); - MEMBERVARIABLE(Double_t, Slope); - MEMBERVARIABLE(Double_t, Intercept); - MEMBERVARIABLE(Double_t, TotalPower); - - MEMBERVARIABLE(Double_t, StartTimeInRunCSigma); - MEMBERVARIABLE(Double_t, EndTimeInRunCSigma); - MEMBERVARIABLE(Double_t, TimeLengthSigma); - MEMBERVARIABLE(Double_t, StartFrequencySigma); - MEMBERVARIABLE(Double_t, EndFrequencySigma); - MEMBERVARIABLE(Double_t, FrequencyWidthSigma); - MEMBERVARIABLE(Double_t, SlopeSigma); - MEMBERVARIABLE(Double_t, InterceptSigma); - MEMBERVARIABLE(Double_t, TotalPowerSigma); - - public: - TProcessedTrackData(); - TProcessedTrackData(const KTProcessedTrackData& data); - TProcessedTrackData(const TProcessedTrackData& orig); - virtual ~TProcessedTrackData(); - TObject* Clone(const char* newname=""); - TProcessedTrackData& operator=(const TProcessedTrackData& rhs); - - void Load(const KTProcessedTrackData& data); - void Unload(KTProcessedTrackData& data) const; - - ClassDef(TProcessedTrackData, 1); - }; - - //*********************** - // TProcessedMPTData - //*********************** - - class KTProcessedMPTData; - - class TProcessedMPTData : public TObject - { - MEMBERVARIABLE(UInt_t, Component); - MEMBERVARIABLE(Int_t, EventSequenceID); - MEMBERVARIABLE(UInt_t, AcquisitionID); - MEMBERVARIABLE(UInt_t, TrackID); - - MEMBERVARIABLE(Bool_t, IsCut); - - MEMBERVARIABLE(Double_t, MVAClassifier); - MEMBERVARIABLE(Bool_t, Mainband); - MEMBERVARIABLE(Double_t, AxialFrequency); - - MEMBERVARIABLE(Double_t, StartTimeInRunC); - MEMBERVARIABLE(Double_t, StartTimeInAcq); - MEMBERVARIABLE(Double_t, EndTimeInRunC); - MEMBERVARIABLE(Double_t, TimeLength); - MEMBERVARIABLE(Double_t, StartFrequency); - MEMBERVARIABLE(Double_t, EndFrequency); - MEMBERVARIABLE(Double_t, FrequencyWidth); - MEMBERVARIABLE(Double_t, Slope); - MEMBERVARIABLE(Double_t, Intercept); - MEMBERVARIABLE(Double_t, TotalPower); - - MEMBERVARIABLE(Double_t, StartTimeInRunCSigma); - MEMBERVARIABLE(Double_t, EndTimeInRunCSigma); - MEMBERVARIABLE(Double_t, TimeLengthSigma); - MEMBERVARIABLE(Double_t, StartFrequencySigma); - MEMBERVARIABLE(Double_t, EndFrequencySigma); - MEMBERVARIABLE(Double_t, FrequencyWidthSigma); - MEMBERVARIABLE(Double_t, SlopeSigma); - MEMBERVARIABLE(Double_t, InterceptSigma); - MEMBERVARIABLE(Double_t, TotalPowerSigma); - - public: - TProcessedMPTData(); - TProcessedMPTData(const KTProcessedMPTData& data); - TProcessedMPTData(const TProcessedMPTData& orig); - virtual ~TProcessedMPTData(); - TObject* Clone(const char* newname=""); - TProcessedMPTData& operator=(const TProcessedMPTData& rhs); - - void Load(const KTProcessedMPTData& data); - void Unload(KTProcessedMPTData& mptData) const; - - ClassDef(TProcessedMPTData, 1); - }; - - //*********************** - // TClassifierResultsData - //*********************** - - class KTClassifierResultsData; - - class TClassifierResultsData : public TObject - { - MEMBERVARIABLE(UInt_t, Component); - MEMBERVARIABLE(Int_t, MainCarrierHigh); - MEMBERVARIABLE(Int_t, MainCarrierLow); - MEMBERVARIABLE(Int_t, SideBand); - - public: - TClassifierResultsData(); - TClassifierResultsData(const KTClassifierResultsData& data); - TClassifierResultsData(const TClassifierResultsData& orig); - virtual ~TClassifierResultsData(); - TObject* Clone(const char* newname=""); - TClassifierResultsData& operator=(const TClassifierResultsData& rhs); - - void Load(const KTClassifierResultsData& data); - void Unload(KTClassifierResultsData& mptData) const; - - ClassDef(TClassifierResultsData, 1); - }; + // class KTProcessedTrackData; + + // class TProcessedTrackData : public TObject + // { + // MEMBERVARIABLE(UInt_t, Component); + // MEMBERVARIABLE(UInt_t, AcquisitionID); + // MEMBERVARIABLE(UInt_t, TrackID); + // MEMBERVARIABLE(UInt_t, EventID); + // MEMBERVARIABLE(Int_t, EventSequenceID); + + // MEMBERVARIABLE(Bool_t, IsCut); + + // MEMBERVARIABLE(Double_t, MVAClassifier); + // MEMBERVARIABLE(Bool_t, Mainband); + + // MEMBERVARIABLE(Double_t, StartTimeInRunC); + // MEMBERVARIABLE(Double_t, StartTimeInAcq); + // MEMBERVARIABLE(Double_t, EndTimeInRunC); + // MEMBERVARIABLE(Double_t, TimeLength); + // MEMBERVARIABLE(Double_t, StartFrequency); + // MEMBERVARIABLE(Double_t, EndFrequency); + // MEMBERVARIABLE(Double_t, FrequencyWidth); + // MEMBERVARIABLE(Double_t, Slope); + // MEMBERVARIABLE(Double_t, Intercept); + // MEMBERVARIABLE(Double_t, TotalPower); + + // MEMBERVARIABLE(Double_t, StartTimeInRunCSigma); + // MEMBERVARIABLE(Double_t, EndTimeInRunCSigma); + // MEMBERVARIABLE(Double_t, TimeLengthSigma); + // MEMBERVARIABLE(Double_t, StartFrequencySigma); + // MEMBERVARIABLE(Double_t, EndFrequencySigma); + // MEMBERVARIABLE(Double_t, FrequencyWidthSigma); + // MEMBERVARIABLE(Double_t, SlopeSigma); + // MEMBERVARIABLE(Double_t, InterceptSigma); + // MEMBERVARIABLE(Double_t, TotalPowerSigma); + + // public: + // TProcessedTrackData(); + // TProcessedTrackData(const KTProcessedTrackData& data); + // TProcessedTrackData(const TProcessedTrackData& orig); + // virtual ~TProcessedTrackData(); + // TObject* Clone(const char* newname=""); + // TProcessedTrackData& operator=(const TProcessedTrackData& rhs); + + // void Load(const KTProcessedTrackData& data); + // void Unload(KTProcessedTrackData& data) const; + + // ClassDef(TProcessedTrackData, 1); + // }; + + // //*********************** + // // TProcessedMPTData + // //*********************** + + // class KTProcessedMPTData; + + // class TProcessedMPTData : public TObject + // { + // MEMBERVARIABLE(UInt_t, Component); + // MEMBERVARIABLE(Int_t, EventSequenceID); + // MEMBERVARIABLE(UInt_t, AcquisitionID); + // MEMBERVARIABLE(UInt_t, TrackID); + + // MEMBERVARIABLE(Bool_t, IsCut); + + // MEMBERVARIABLE(Double_t, MVAClassifier); + // MEMBERVARIABLE(Bool_t, Mainband); + // MEMBERVARIABLE(Double_t, AxialFrequency); + + // MEMBERVARIABLE(Double_t, StartTimeInRunC); + // MEMBERVARIABLE(Double_t, StartTimeInAcq); + // MEMBERVARIABLE(Double_t, EndTimeInRunC); + // MEMBERVARIABLE(Double_t, TimeLength); + // MEMBERVARIABLE(Double_t, StartFrequency); + // MEMBERVARIABLE(Double_t, EndFrequency); + // MEMBERVARIABLE(Double_t, FrequencyWidth); + // MEMBERVARIABLE(Double_t, Slope); + // MEMBERVARIABLE(Double_t, Intercept); + // MEMBERVARIABLE(Double_t, TotalPower); + + // MEMBERVARIABLE(Double_t, StartTimeInRunCSigma); + // MEMBERVARIABLE(Double_t, EndTimeInRunCSigma); + // MEMBERVARIABLE(Double_t, TimeLengthSigma); + // MEMBERVARIABLE(Double_t, StartFrequencySigma); + // MEMBERVARIABLE(Double_t, EndFrequencySigma); + // MEMBERVARIABLE(Double_t, FrequencyWidthSigma); + // MEMBERVARIABLE(Double_t, SlopeSigma); + // MEMBERVARIABLE(Double_t, InterceptSigma); + // MEMBERVARIABLE(Double_t, TotalPowerSigma); + + // public: + // TProcessedMPTData(); + // TProcessedMPTData(const KTProcessedMPTData& data); + // TProcessedMPTData(const TProcessedMPTData& orig); + // virtual ~TProcessedMPTData(); + // TObject* Clone(const char* newname=""); + // TProcessedMPTData& operator=(const TProcessedMPTData& rhs); + + // void Load(const KTProcessedMPTData& data); + // void Unload(KTProcessedMPTData& mptData) const; + + // ClassDef(TProcessedMPTData, 1); + // }; + + // //*********************** + // // TClassifierResultsData + // //*********************** + + // class KTClassifierResultsData; + + // class TClassifierResultsData : public TObject + // { + // MEMBERVARIABLE(UInt_t, Component); + // MEMBERVARIABLE(Int_t, MainCarrierHigh); + // MEMBERVARIABLE(Int_t, MainCarrierLow); + // MEMBERVARIABLE(Int_t, SideBand); + + // public: + // TClassifierResultsData(); + // TClassifierResultsData(const KTClassifierResultsData& data); + // TClassifierResultsData(const TClassifierResultsData& orig); + // virtual ~TClassifierResultsData(); + // TObject* Clone(const char* newname=""); + // TClassifierResultsData& operator=(const TClassifierResultsData& rhs); + + // void Load(const KTClassifierResultsData& data); + // void Unload(KTClassifierResultsData& mptData) const; + + // ClassDef(TClassifierResultsData, 1); + // }; + + // //************************ + // // TMultiTrackEventData + // //************************ + + // class KTMultiTrackEventData; + + // class TMultiTrackEventData : public TObject + // { + // MEMBERVARIABLE(UInt_t, Component); + // MEMBERVARIABLE(UInt_t, AcquisitionID); + // MEMBERVARIABLE(UInt_t, EventID); + // MEMBERVARIABLE(UInt_t, TotalEventSequences); + + // MEMBERVARIABLE(Double_t, StartTimeInRunC); + // MEMBERVARIABLE(Double_t, StartTimeInAcq); + // MEMBERVARIABLE(Double_t, EndTimeInRunC); + // MEMBERVARIABLE(Double_t, TimeLength); + // MEMBERVARIABLE(Double_t, StartFrequency); + // MEMBERVARIABLE(Double_t, EndFrequency); + // MEMBERVARIABLE(Double_t, MinimumFrequency); + // MEMBERVARIABLE(Double_t, MaximumFrequency); + // MEMBERVARIABLE(Double_t, FrequencyWidth); + + // MEMBERVARIABLE(Double_t, StartTimeInRunCSigma); + // MEMBERVARIABLE(Double_t, EndTimeInRunCSigma); + // MEMBERVARIABLE(Double_t, TimeLengthSigma); + // MEMBERVARIABLE(Double_t, StartFrequencySigma); + // MEMBERVARIABLE(Double_t, EndFrequencySigma); + // MEMBERVARIABLE(Double_t, FrequencyWidthSigma); + + // MEMBERVARIABLE(UInt_t, FirstTrackID); + // MEMBERVARIABLE(Double_t, FirstTrackTimeLength); + // MEMBERVARIABLE(Double_t, FirstTrackFrequencyWidth); + // MEMBERVARIABLE(Double_t, FirstTrackSlope); + // MEMBERVARIABLE(Double_t, FirstTrackIntercept); + // MEMBERVARIABLE(Double_t, FirstTrackTotalPower); + + // MEMBERVARIABLE(Double_t, UnknownEventTopology); + + // public: + // TClonesArray* GetTracks() {return fTracks;} + + // private: + // TClonesArray* fTracks; //-> + + // public: + // TMultiTrackEventData(); + // TMultiTrackEventData(const KTMultiTrackEventData& data); + // TMultiTrackEventData(const TMultiTrackEventData& orig); + // virtual ~TMultiTrackEventData(); + // TObject* Clone(const char* newname=""); + // TMultiTrackEventData& operator=(const TMultiTrackEventData& rhs); + + // void Load(const KTMultiTrackEventData& data); + // void Unload(KTMultiTrackEventData& data) const; + + // ClassDef(TMultiTrackEventData, 1); + // }; + + // //************************ + // // TClassifiedEventData + // //************************ + + // //class KTClassifiedEventData; + + // class TClassifiedEventData : public TObject + // { + // MEMBERVARIABLE(UInt_t, Component); + // MEMBERVARIABLE(UInt_t, AcquisitionID); + // MEMBERVARIABLE(UInt_t, EventID); + // MEMBERVARIABLE(UInt_t, TotalEventSequences); + + // MEMBERVARIABLE(Double_t, StartTimeInRunC); + // MEMBERVARIABLE(Double_t, StartTimeInAcq); + // MEMBERVARIABLE(Double_t, EndTimeInRunC); + // MEMBERVARIABLE(Double_t, TimeLength); + // MEMBERVARIABLE(Double_t, StartFrequency); + // MEMBERVARIABLE(Double_t, EndFrequency); + // MEMBERVARIABLE(Double_t, MinimumFrequency); + // MEMBERVARIABLE(Double_t, MaximumFrequency); + // MEMBERVARIABLE(Double_t, FrequencyWidth); + + // MEMBERVARIABLE(Double_t, StartTimeInRunCSigma); + // MEMBERVARIABLE(Double_t, EndTimeInRunCSigma); + // MEMBERVARIABLE(Double_t, TimeLengthSigma); + // MEMBERVARIABLE(Double_t, StartFrequencySigma); + // MEMBERVARIABLE(Double_t, EndFrequencySigma); + // MEMBERVARIABLE(Double_t, FrequencyWidthSigma); + + // MEMBERVARIABLE(UInt_t, FirstTrackID); + // MEMBERVARIABLE(Double_t, FirstTrackTimeLength); + // MEMBERVARIABLE(Double_t, FirstTrackFrequencyWidth); + // MEMBERVARIABLE(Double_t, FirstTrackSlope); + // MEMBERVARIABLE(Double_t, FirstTrackIntercept); + // MEMBERVARIABLE(Double_t, FirstTrackTotalPower); + + // MEMBERVARIABLE(Double_t, UnknownEventTopology); + + // public: + // TClonesArray* GetTracks() {return fTracks;} + // TClonesArray* GetClassifierResults() {return fClassifierResults;} + + // private: + // TClonesArray* fTracks; //-> + // TClonesArray* fClassifierResults; //-> + + // public: + // TClassifiedEventData(); + // TClassifiedEventData(const KTMultiTrackEventData& data); + // TClassifiedEventData(const TClassifiedEventData& orig); + // virtual ~TClassifiedEventData(); + // TObject* Clone(const char* newname=""); + // TClassifiedEventData& operator=(const TClassifiedEventData& rhs); + + // void Load(const KTMultiTrackEventData& data); + // void Unload(KTMultiTrackEventData& data) const; + + // ClassDef(TClassifiedEventData, 1); + // }; //************************ - // TMultiTrackEventData + // TDiscriminatedPoint //************************ - class KTMultiTrackEventData; + class KTDiscriminatedPoint; - class TMultiTrackEventData : public TObject + class TDiscriminatedPoint : public TObject { - MEMBERVARIABLE(UInt_t, Component); - MEMBERVARIABLE(UInt_t, AcquisitionID); - MEMBERVARIABLE(UInt_t, EventID); - MEMBERVARIABLE(UInt_t, TotalEventSequences); - - MEMBERVARIABLE(Double_t, StartTimeInRunC); - MEMBERVARIABLE(Double_t, StartTimeInAcq); - MEMBERVARIABLE(Double_t, EndTimeInRunC); - MEMBERVARIABLE(Double_t, TimeLength); - MEMBERVARIABLE(Double_t, StartFrequency); - MEMBERVARIABLE(Double_t, EndFrequency); - MEMBERVARIABLE(Double_t, MinimumFrequency); - MEMBERVARIABLE(Double_t, MaximumFrequency); - MEMBERVARIABLE(Double_t, FrequencyWidth); - - MEMBERVARIABLE(Double_t, StartTimeInRunCSigma); - MEMBERVARIABLE(Double_t, EndTimeInRunCSigma); - MEMBERVARIABLE(Double_t, TimeLengthSigma); - MEMBERVARIABLE(Double_t, StartFrequencySigma); - MEMBERVARIABLE(Double_t, EndFrequencySigma); - MEMBERVARIABLE(Double_t, FrequencyWidthSigma); - MEMBERVARIABLE(UInt_t, FirstTrackID); - MEMBERVARIABLE(Double_t, FirstTrackTimeLength); - MEMBERVARIABLE(Double_t, FirstTrackFrequencyWidth); - MEMBERVARIABLE(Double_t, FirstTrackSlope); - MEMBERVARIABLE(Double_t, FirstTrackIntercept); - MEMBERVARIABLE(Double_t, FirstTrackTotalPower); - - MEMBERVARIABLE(Double_t, UnknownEventTopology); - - public: - TClonesArray* GetTracks() {return fTracks;} - - private: - TClonesArray* fTracks; //-> + MEMBERVARIABLE(Double_t, TimeInRunC); + MEMBERVARIABLE(Double_t, Frequency); + MEMBERVARIABLE(Double_t, Amplitude); + MEMBERVARIABLE(Double_t, TimeInAcq); + MEMBERVARIABLE(Double_t, Mean); + MEMBERVARIABLE(Double_t, Variance); + MEMBERVARIABLE(Double_t, NeighborhoodAmplitude); public: - TMultiTrackEventData(); - TMultiTrackEventData(const KTMultiTrackEventData& data); - TMultiTrackEventData(const TMultiTrackEventData& orig); - virtual ~TMultiTrackEventData(); + TDiscriminatedPoint(); + TDiscriminatedPoint(const TDiscriminatedPoint& orig); + virtual ~TDiscriminatedPoint(); TObject* Clone(const char* newname=""); - TMultiTrackEventData& operator=(const TMultiTrackEventData& rhs); - - void Load(const KTMultiTrackEventData& data); - void Unload(KTMultiTrackEventData& data) const; + TDiscriminatedPoint& operator=(const TDiscriminatedPoint& rhs); - ClassDef(TMultiTrackEventData, 1); + ClassDef(TDiscriminatedPoint, 1); }; //************************ - // TClassifiedEventData + // TSparseWaterFallCandidateData //************************ - //class KTClassifiedEventData; + class KTSparseWaterfallCandidateData; - class TClassifiedEventData : public TObject + class TSparseWaterfallCandidateData : public TObject { MEMBERVARIABLE(UInt_t, Component); MEMBERVARIABLE(UInt_t, AcquisitionID); - MEMBERVARIABLE(UInt_t, EventID); - MEMBERVARIABLE(UInt_t, TotalEventSequences); + MEMBERVARIABLE(UInt_t, CandidateID); - MEMBERVARIABLE(Double_t, StartTimeInRunC); - MEMBERVARIABLE(Double_t, StartTimeInAcq); - MEMBERVARIABLE(Double_t, EndTimeInRunC); + MEMBERVARIABLE(Double_t, TimeInRunC); MEMBERVARIABLE(Double_t, TimeLength); - MEMBERVARIABLE(Double_t, StartFrequency); - MEMBERVARIABLE(Double_t, EndFrequency); - MEMBERVARIABLE(Double_t, MinimumFrequency); - MEMBERVARIABLE(Double_t, MaximumFrequency); + MEMBERVARIABLE(Double_t, MinFrequency); + MEMBERVARIABLE(Double_t, MaxFrequency); MEMBERVARIABLE(Double_t, FrequencyWidth); - MEMBERVARIABLE(Double_t, StartTimeInRunCSigma); - MEMBERVARIABLE(Double_t, EndTimeInRunCSigma); - MEMBERVARIABLE(Double_t, TimeLengthSigma); - MEMBERVARIABLE(Double_t, StartFrequencySigma); - MEMBERVARIABLE(Double_t, EndFrequencySigma); - MEMBERVARIABLE(Double_t, FrequencyWidthSigma); - - MEMBERVARIABLE(UInt_t, FirstTrackID); - MEMBERVARIABLE(Double_t, FirstTrackTimeLength); - MEMBERVARIABLE(Double_t, FirstTrackFrequencyWidth); - MEMBERVARIABLE(Double_t, FirstTrackSlope); - MEMBERVARIABLE(Double_t, FirstTrackIntercept); - MEMBERVARIABLE(Double_t, FirstTrackTotalPower); - - MEMBERVARIABLE(Double_t, UnknownEventTopology); - public: - TClonesArray* GetTracks() {return fTracks;} - TClonesArray* GetClassifierResults() {return fClassifierResults;} + TClonesArray* GetPoints() {return fPoints;} private: - TClonesArray* fTracks; //-> - TClonesArray* fClassifierResults; //-> + TClonesArray* fPoints; public: - TClassifiedEventData(); - TClassifiedEventData(const KTMultiTrackEventData& data); - TClassifiedEventData(const TClassifiedEventData& orig); - virtual ~TClassifiedEventData(); + TSparseWaterfallCandidateData(); + TSparseWaterfallCandidateData(const TSparseWaterfallCandidateData& orig); + virtual ~TSparseWaterfallCandidateData(); TObject* Clone(const char* newname=""); - TClassifiedEventData& operator=(const TClassifiedEventData& rhs); + TSparseWaterfallCandidateData& operator=(const TSparseWaterfallCandidateData& rhs); - void Load(const KTMultiTrackEventData& data); - void Unload(KTMultiTrackEventData& data) const; + std::string GetBranchName() { return std::string("SparseWaterfall"); } // Defines the default name of the object saved inside the output tree - ClassDef(TClassifiedEventData, 1); + ClassDef(TSparseWaterfallCandidateData, 1); }; - - } - #endif /* KTROOTDATA_HH_ */ diff --git a/Source/IO/Conversions/LinkDef/ConversionsLinkDef.hh b/Source/IO/Conversions/LinkDef/ConversionsLinkDef.hh index 6a0678f0a..70fe9b8ce 100644 --- a/Source/IO/Conversions/LinkDef/ConversionsLinkDef.hh +++ b/Source/IO/Conversions/LinkDef/ConversionsLinkDef.hh @@ -9,4 +9,7 @@ #pragma link C++ namespace Katydid; +#pragma link C++ class Katydid::TDiscriminatedPoint+; +#pragma link C++ class Katydid::TSparseWaterfallCandidateData+; + #endif diff --git a/Source/IO/LinkDef/IOLinkDef.hh b/Source/IO/LinkDef/IOLinkDef.hh index ca1a0f141..1d8c65ea0 100644 --- a/Source/IO/LinkDef/IOLinkDef.hh +++ b/Source/IO/LinkDef/IOLinkDef.hh @@ -10,5 +10,8 @@ #pragma link C++ namespace Katydid; #pragma link C++ class Katydid::KTDisplayWindow+; +#pragma link C++ class Katydid::TDiscriminatedPoint+; +#pragma link C++ class Katydid::TSparseWaterfallCandidateData+; + #endif diff --git a/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterEventAnalysis.cc b/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterEventAnalysis.cc index 284b6ef28..839317fa5 100644 --- a/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterEventAnalysis.cc +++ b/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterEventAnalysis.cc @@ -21,17 +21,21 @@ #include "KTSliceHeader.hh" #include "KTSparseWaterfallCandidateData.hh" #include "KTWaterfallCandidateData.hh" +#include "KTDiscriminatedPoint.hh" #include "CClassifierResultsData.hh" #include "CMTEWithClassifierResultsData.hh" #include "CProcessedMPTData.hh" #include "CROOTData.hh" +#include "KTROOTData.hh" #include "TFile.h" #include "TGraph.h" #include "TGraph2D.h" #include "TH2.h" #include "TTree.h" +#include "TClonesArray.h" +#include "TNtupleD.h" #include @@ -61,7 +65,7 @@ namespace Katydid fPowerFitDataTree(NULL), fFreqCandidateData(), fWaterfallCandidateData(), - fSparseWaterfallCandidateData(), + fSparseWaterfallCandidateDataPtr(NULL), fProcessedTrackDataPtr(NULL), fProcessedMPTDataPtr(NULL), fMultiPeakTrackData(), @@ -223,8 +227,8 @@ namespace Katydid fWaterfallCandidateData.fTimeLength = wcData.GetTimeLength(); fWaterfallCandidateData.fFirstSliceNumber = wcData.GetFirstSliceNumber(); fWaterfallCandidateData.fLastSliceNumber = wcData.GetLastSliceNumber(); - fWaterfallCandidateData.fMinFrequency = wcData.GetMinimumFrequency(); - fWaterfallCandidateData.fMaxFrequency = wcData.GetMaximumFrequency(); + fWaterfallCandidateData.fMinFrequency = wcData.GetMinFrequency(); + fWaterfallCandidateData.fMaxFrequency = wcData.GetMaxFrequency(); fWaterfallCandidateData.fMeanStartFrequency = wcData.GetMeanStartFrequency(); fWaterfallCandidateData.fMeanEndFrequency = wcData.GetMeanEndFrequency(); fWaterfallCandidateData.fFrequencyWidth = wcData.GetFrequencyWidth(); @@ -294,14 +298,141 @@ namespace Katydid // Sparse Waterfall Candidates //**************************** + // void KTROOTTreeTypeWriterEventAnalysis::WriteSparseWaterfallCandidate(Nymph::KTDataPtr data) + // { + // KTDEBUG(publog, "Attempting to write to sparse waterfall candidate root tree"); + // KTSparseWaterfallCandidateData& swcData = data->Of< KTSparseWaterfallCandidateData >(); + + // if (! fWriter->OpenAndVerifyFile()) return; + + // if (fSparseWaterfallCandidateTree == NULL) + // { + // if (! SetupSparseWaterfallCandidateTree()) + // { + // KTERROR(publog, "Something went wrong while setting up the sparse waterfall candidate tree! Nothing was written."); + // return; + // } + // } + + // // Load() also clears any existing data + // //fFreqCandidateData->Load(*data); + // fSparseWaterfallCandidateData.fComponent = swcData.GetComponent(); + // fSparseWaterfallCandidateData.fAcquisitionID = swcData.GetAcquisitionID(); + // //fSparseWaterfallCandidateData.fTimeBinWidth = swcData.GetTimeBinWidth(); + // //fSparseWaterfallCandidateData.fFreqBinWidth = swcData.GetFreqBinWidth(); + // fSparseWaterfallCandidateData.fTimeInRunC = swcData.GetTimeInRunC(); + // fSparseWaterfallCandidateData.fTimeLength = swcData.GetTimeLength(); + // fSparseWaterfallCandidateData.fMinFrequency = swcData.GetMinFrequency(); + // fSparseWaterfallCandidateData.fMaxFrequency = swcData.GetMaxFrequency(); + // fSparseWaterfallCandidateData.fFrequencyWidth = swcData.GetFrequencyWidth(); + + // const KTDiscriminatedPoints& points = swcData.GetPoints(); + // // KTDEBUG(publog, "# points in sparse waterfall candidate " << points.size()); + + // if (points.size() == 0) + // { + // KTWARN(publog, "No points in sparse waterfall candidate; nothing written to ROOT file"); + // return; + // } + + // fSparseWaterfallCandidateData.fPoints = new TNtupleD("Points","Points","Frequency:TimeInRunC"); + // unsigned iPoint = 0; + // for (KTDiscriminatedPoints::const_iterator pIt = points.begin(); pIt != points.end(); ++pIt) + // { + // KTDEBUG(publog, "In loop " << iPoint); + // // TDiscriminatedPoint* point = (TDiscriminatedPoint*) fSparseWaterfallCandidateData.fPoints->ConstructedAt(iPoint); + // // TDiscriminatedPoint* point = (TDiscriminatedPoint*)fSparseWaterfallCandidateData.fPoints->ConstructedAt(iPoint); + // KTDEBUG(publog, "Past constructon " << iPoint); + // // point->fTimeInRunC = pIt->fTimeInRunC; + // // point->fFrequency = pIt->fFrequency; + // // point->fAmplitude = pIt->fAmplitude; + // // point->fTimeInAcq = pIt->fTimeInAcq; + // // point->fMean = pIt->fMean; + // // point->fVariance = pIt->fVariance; + // // point->fNeighborhoodAmplitude = pIt->fNeighborhoodAmplitude; + // // fSparseWaterfallCandidateData.fPoints[iPoint] = new TDiscriminatedPoint(); + // // fSparseWaterfallCandidateData.fPoints[iPoint]->fFrequency = pIt->fTimeInRunC; + // fSparseWaterfallCandidateData.fPoints->Fill(pIt->fTimeInRunC,pIt->fFrequency); + // // point->fFrequency = pIt->fFrequency; + // // point->fAmplitude = pIt->fAmplitude; + // // point->fTimeInAcq = pIt->fTimeInAcq; + // // point->fMean = pIt->fMean; + // // point->fVariance = pIt->fVariance; + // // point->fNeighborhoodAmplitude = pIt->fNeighborhoodAmplitude; + // // fSparseWaterfallCandidateData.fPoints->SetPoint(iPoint, pIt->fTimeInRunC, pIt->fFrequency, pIt->fAmplitude); + // ++iPoint; + // } + // // fSparseWaterfallCandidateData.fPoints->SetDirectory(NULL); + // // KTDEBUG(publog, "Candidate info:\n" + // // << "\tNumber of points: " << fSparseWaterfallCandidateData.fPoints->GetN());// << "\n" + // //<< "\tTime axis: bin width: " << fSparseWaterfallCandidateData.fTimeBinWidth << " s\n" + // //<< "\tFreq axis: bin width: " << fSparseWaterfallCandidateData.fFreqBinWidth << " Hz"); + + // fSparseWaterfallCandidateTree->Fill(); + // // fSparseWaterfallCandidateData.fPoints->Clear(); + + // return; + // } + + // bool KTROOTTreeTypeWriterEventAnalysis::SetupSparseWaterfallCandidateTree() + // { + // if( fWriter->GetAccumulate() ) + // { + // fWriter->GetFile()->GetObject( "swfCand", fSparseWaterfallCandidateTree ); + + // if( fSparseWaterfallCandidateTree != NULL ) + // { + // KTINFO( publog, "Tree already exists; will add to it" ); + // fWriter->AddTree( fSparseWaterfallCandidateTree ); + + // fSparseWaterfallCandidateTree->SetBranchAddress("Component", &fSparseWaterfallCandidateData.fComponent); + // fSparseWaterfallCandidateTree->SetBranchAddress("AcquisitionID", &fSparseWaterfallCandidateData.fAcquisitionID); + // fSparseWaterfallCandidateTree->SetBranchAddress("CandidateID", &fSparseWaterfallCandidateData.fCandidateID); + // //fSparseWaterfallCandidateTree->SetBranchAddress("TimeBinWidth", &fSparseWaterfallCandidateData.fTimeBinWidth); + // //fSparseWaterfallCandidateTree->SetBranchAddress("FreqBinWidth", &fSparseWaterfallCandidateData.fFreqBinWidth); + // fSparseWaterfallCandidateTree->SetBranchAddress("TimeInRunC", &fSparseWaterfallCandidateData.fTimeInRunC); + // fSparseWaterfallCandidateTree->SetBranchAddress("TimeLength", &fSparseWaterfallCandidateData.fTimeLength); + // fSparseWaterfallCandidateTree->SetBranchAddress("MinFrequency", &fSparseWaterfallCandidateData.fMinFrequency); + // fSparseWaterfallCandidateTree->SetBranchAddress("MaxFrequency", &fSparseWaterfallCandidateData.fMaxFrequency); + // fSparseWaterfallCandidateTree->SetBranchAddress("FrequencyWidth", &fSparseWaterfallCandidateData.fFrequencyWidth); + // fSparseWaterfallCandidateTree->SetBranchAddress("Points", &fSparseWaterfallCandidateData.fPoints); + + // return true; + // } + // } + + // fSparseWaterfallCandidateTree = new TTree("swfCand", "Sparse Waterfall Candidates"); + // if (fSparseWaterfallCandidateTree == NULL) + // { + // KTERROR(publog, "Tree was not created!"); + // return false; + // } + // fWriter->AddTree(fSparseWaterfallCandidateTree); + + // fSparseWaterfallCandidateTree->Branch("Component", &fSparseWaterfallCandidateData.fComponent, "fComponent/i"); + // fSparseWaterfallCandidateTree->Branch("AcquisitionID", &fSparseWaterfallCandidateData.fAcquisitionID, "fAcquisitionID/i"); + // fSparseWaterfallCandidateTree->Branch("CandidateID", &fSparseWaterfallCandidateData.fCandidateID, "fCandidateID/i"); + // //fSparseWaterfallCandidateTree->Branch("TimeBinWidth", &fSparseWaterfallCandidateData.fTimeBinWidth, "fTimeBinWidth/d"); + // //fSparseWaterfallCandidateTree->Branch("FreqBinWidth", &fSparseWaterfallCandidateData.fFreqBinWidth, "fFreqBinWidth/d"); + // fSparseWaterfallCandidateTree->Branch("TimeInRunC", &fSparseWaterfallCandidateData.fTimeInRunC, "fTimeInRunC/d"); + // fSparseWaterfallCandidateTree->Branch("TimeLength", &fSparseWaterfallCandidateData.fTimeLength, "fTimeLength/d"); + // fSparseWaterfallCandidateTree->Branch("MinFrequency", &fSparseWaterfallCandidateData.fMinFrequency, "fMinFrequency/d"); + // fSparseWaterfallCandidateTree->Branch("MaxFrequency", &fSparseWaterfallCandidateData.fMaxFrequency, "fMaxFrequency/d"); + // fSparseWaterfallCandidateTree->Branch("FrequencyWidth", &fSparseWaterfallCandidateData.fFrequencyWidth, "fFrequencyWidth/d"); + // fSparseWaterfallCandidateTree->Branch("Points", &fSparseWaterfallCandidateData.fPoints, 32000, 0); + + // return true; + // } + + void KTROOTTreeTypeWriterEventAnalysis::WriteSparseWaterfallCandidate(Nymph::KTDataPtr data) { KTDEBUG(publog, "Attempting to write to sparse waterfall candidate root tree"); - KTSparseWaterfallCandidateData& swcData = data->Of< KTSparseWaterfallCandidateData >(); + KTSparseWaterfallCandidateData& swfData = data->Of< KTSparseWaterfallCandidateData >(); if (! fWriter->OpenAndVerifyFile()) return; - if (fSparseWaterfallCandidateTree == NULL) + if (fSparseWaterfallCandidateDataPtr == NULL) { if (! SetupSparseWaterfallCandidateTree()) { @@ -310,40 +441,12 @@ namespace Katydid } } - // Load() also clears any existing data - //fFreqCandidateData->Load(*data); - fSparseWaterfallCandidateData.fComponent = swcData.GetComponent(); - fSparseWaterfallCandidateData.fAcquisitionID = swcData.GetAcquisitionID(); - //fSparseWaterfallCandidateData.fTimeBinWidth = swcData.GetTimeBinWidth(); - //fSparseWaterfallCandidateData.fFreqBinWidth = swcData.GetFreqBinWidth(); - fSparseWaterfallCandidateData.fTimeInRunC = swcData.GetTimeInRunC(); - fSparseWaterfallCandidateData.fTimeLength = swcData.GetTimeLength(); - fSparseWaterfallCandidateData.fMinFrequency = swcData.GetMinimumFrequency(); - fSparseWaterfallCandidateData.fMaxFrequency = swcData.GetMaximumFrequency(); - fSparseWaterfallCandidateData.fFrequencyWidth = swcData.GetFrequencyWidth(); - - const KTSparseWaterfallCandidateData::Points& points = swcData.GetPoints(); - - if (points.size() == 0) - { - KTWARN(publog, "No points in sparse waterfall candidate; nothing written to ROOT file"); - return; - } - - fSparseWaterfallCandidateData.fPoints = new TGraph2D(points.size()); - unsigned iPoint = 0; - for (KTSparseWaterfallCandidateData::Points::const_iterator pIt = points.begin(); pIt != points.end(); ++pIt) - { - fSparseWaterfallCandidateData.fPoints->SetPoint(iPoint, pIt->fTimeInRunC, pIt->fFrequency, pIt->fAmplitude); - ++iPoint; - } - fSparseWaterfallCandidateData.fPoints->SetDirectory(NULL); - KTDEBUG(publog, "Candidate info:\n" - << "\tNumber of points: " << fSparseWaterfallCandidateData.fPoints->GetN());// << "\n" - //<< "\tTime axis: bin width: " << fSparseWaterfallCandidateData.fTimeBinWidth << " s\n" - //<< "\tFreq axis: bin width: " << fSparseWaterfallCandidateData.fFreqBinWidth << " Hz"); + KT2ROOT::LoadSparseWaterfallCandidateData(swfData, *fSparseWaterfallCandidateDataPtr); + KTDEBUG(publog, "Before filling"); + KTDEBUG(publog, fSparseWaterfallCandidateDataPtr->GetComponent()); fSparseWaterfallCandidateTree->Fill(); + KTDEBUG(publog, "After filling"); return; } @@ -352,30 +455,20 @@ namespace Katydid { if( fWriter->GetAccumulate() ) { - fWriter->GetFile()->GetObject( "swfCand", fSparseWaterfallCandidateTree ); + fWriter->GetFile()->GetObject( "sparseWaterfall", fSparseWaterfallCandidateTree ); if( fSparseWaterfallCandidateTree != NULL ) { KTINFO( publog, "Tree already exists; will add to it" ); fWriter->AddTree( fSparseWaterfallCandidateTree ); - fSparseWaterfallCandidateTree->SetBranchAddress("Component", &fSparseWaterfallCandidateData.fComponent); - fSparseWaterfallCandidateTree->SetBranchAddress("AcquisitionID", &fSparseWaterfallCandidateData.fAcquisitionID); - fSparseWaterfallCandidateTree->SetBranchAddress("CandidateID", &fSparseWaterfallCandidateData.fCandidateID); - //fSparseWaterfallCandidateTree->SetBranchAddress("TimeBinWidth", &fSparseWaterfallCandidateData.fTimeBinWidth); - //fSparseWaterfallCandidateTree->SetBranchAddress("FreqBinWidth", &fSparseWaterfallCandidateData.fFreqBinWidth); - fSparseWaterfallCandidateTree->SetBranchAddress("TimeInRunC", &fSparseWaterfallCandidateData.fTimeInRunC); - fSparseWaterfallCandidateTree->SetBranchAddress("TimeLength", &fSparseWaterfallCandidateData.fTimeLength); - fSparseWaterfallCandidateTree->SetBranchAddress("MinFrequency", &fSparseWaterfallCandidateData.fMinFrequency); - fSparseWaterfallCandidateTree->SetBranchAddress("MaxFrequency", &fSparseWaterfallCandidateData.fMaxFrequency); - fSparseWaterfallCandidateTree->SetBranchAddress("FrequencyWidth", &fSparseWaterfallCandidateData.fFrequencyWidth); - fSparseWaterfallCandidateTree->SetBranchAddress("Points", &fSparseWaterfallCandidateData.fPoints); + fSparseWaterfallCandidateTree->SetBranchAddress(fSparseWaterfallCandidateDataPtr->GetBranchName().c_str(), &fSparseWaterfallCandidateDataPtr); return true; } } - fSparseWaterfallCandidateTree = new TTree("swfCand", "Sparse Waterfall Candidates"); + fSparseWaterfallCandidateTree = new TTree("sparseWaterfall", "Sparse Waterfall Candidate"); if (fSparseWaterfallCandidateTree == NULL) { KTERROR(publog, "Tree was not created!"); @@ -383,21 +476,14 @@ namespace Katydid } fWriter->AddTree(fSparseWaterfallCandidateTree); - fSparseWaterfallCandidateTree->Branch("Component", &fSparseWaterfallCandidateData.fComponent, "fComponent/i"); - fSparseWaterfallCandidateTree->Branch("AcquisitionID", &fSparseWaterfallCandidateData.fAcquisitionID, "fAcquisitionID/i"); - fSparseWaterfallCandidateTree->Branch("CandidateID", &fSparseWaterfallCandidateData.fCandidateID, "fCandidateID/i"); - //fSparseWaterfallCandidateTree->Branch("TimeBinWidth", &fSparseWaterfallCandidateData.fTimeBinWidth, "fTimeBinWidth/d"); - //fSparseWaterfallCandidateTree->Branch("FreqBinWidth", &fSparseWaterfallCandidateData.fFreqBinWidth, "fFreqBinWidth/d"); - fSparseWaterfallCandidateTree->Branch("TimeInRunC", &fSparseWaterfallCandidateData.fTimeInRunC, "fTimeInRunC/d"); - fSparseWaterfallCandidateTree->Branch("TimeLength", &fSparseWaterfallCandidateData.fTimeLength, "fTimeLength/d"); - fSparseWaterfallCandidateTree->Branch("MinFrequency", &fSparseWaterfallCandidateData.fMinFrequency, "fMinFrequency/d"); - fSparseWaterfallCandidateTree->Branch("MaxFrequency", &fSparseWaterfallCandidateData.fMaxFrequency, "fMaxFrequency/d"); - fSparseWaterfallCandidateTree->Branch("FrequencyWidth", &fSparseWaterfallCandidateData.fFrequencyWidth, "fFrequencyWidth/d"); - fSparseWaterfallCandidateTree->Branch("Points", &fSparseWaterfallCandidateData.fPoints, 32000, 0); + fSparseWaterfallCandidateDataPtr = new TSparseWaterfallCandidateData(); + + fSparseWaterfallCandidateTree->Branch(fSparseWaterfallCandidateDataPtr->GetBranchName().c_str(), "Katydid::TSparseWaterfallCandidateData", &fSparseWaterfallCandidateDataPtr); return true; } + //**************** // Processed Track //**************** @@ -423,7 +509,7 @@ namespace Katydid KTINFO(publog, "Tree already exists!"); fWriter->AddTree( fProcessedTrackTree ); - fProcessedTrackTree->SetBranchAddress("Track", &fProcessedTrackDataPtr); + fProcessedTrackTree->SetBranchAddress(fProcessedTrackDataPtr->GetBranchName().c_str(), &fProcessedTrackDataPtr); } KT2ROOT::LoadProcTrackData(ptData, *fProcessedTrackDataPtr); @@ -444,7 +530,7 @@ namespace Katydid KTINFO( publog, "Tree already exists; will add to it" ); fWriter->AddTree( fProcessedTrackTree ); - fProcessedTrackTree->SetBranchAddress("Track", &fProcessedTrackDataPtr); + fProcessedTrackTree->SetBranchAddress(fProcessedTrackDataPtr->GetBranchName().c_str(), &fProcessedTrackDataPtr); return true; } @@ -460,7 +546,7 @@ namespace Katydid //fProcessedTrackDataPtr = new Cicada::TProcessedTrackData(); - fProcessedTrackTree->Branch("Track", "Cicada::TProcessedTrackData", &fProcessedTrackDataPtr); + fProcessedTrackTree->Branch(fProcessedTrackDataPtr->GetBranchName().c_str(), "Cicada::TProcessedTrackData", &fProcessedTrackDataPtr); return true; } @@ -504,7 +590,7 @@ namespace Katydid KTINFO( publog, "Tree already exists; will add to it" ); fWriter->AddTree( fProcessedMPTTree ); - fProcessedMPTTree->SetBranchAddress("MultiPeakTrack", &fProcessedMPTDataPtr); + fProcessedMPTTree->SetBranchAddress(fProcessedMPTDataPtr->GetBranchName().c_str(), &fProcessedMPTDataPtr); return true; } @@ -520,7 +606,7 @@ namespace Katydid //fProcessedTrackDataPtr = new TProcessedTrackData(); - fProcessedMPTTree->Branch("MultiPeakTrack", "Katydid::TProcessedMPTData", &fProcessedMPTDataPtr); + fProcessedMPTTree->Branch(fProcessedMPTDataPtr->GetBranchName().c_str(), "Katydid::TProcessedMPTData", &fProcessedMPTDataPtr); return true; } @@ -652,7 +738,7 @@ namespace Katydid KTINFO( publog, "Tree already exists; will add to it" ); fWriter->AddTree( fMultiTrackEventTree ); - fMultiTrackEventTree->SetBranchAddress("Event", &fMultiTrackEventDataPtr); + fMultiTrackEventTree->SetBranchAddress(fMultiTrackEventDataPtr->GetBranchName().c_str(), &fMultiTrackEventDataPtr); return true; } @@ -668,7 +754,7 @@ namespace Katydid fMultiTrackEventDataPtr = new Cicada::TMultiTrackEventData(); - fMultiTrackEventTree->Branch("Event", "Cicada::TMultiTrackEventData", &fMultiTrackEventDataPtr); + fMultiTrackEventTree->Branch(fMultiTrackEventDataPtr->GetBranchName().c_str(), "Cicada::TMultiTrackEventData", &fMultiTrackEventDataPtr); return true; } @@ -712,7 +798,7 @@ namespace Katydid KTINFO( publog, "Tree already exists; will add to it" ); fWriter->AddTree( fMTEWithClassifierResultsTree ); - fMTEWithClassifierResultsTree->SetBranchAddress("Event", &fMTEWithClassifierResultsDataPtr); + fMTEWithClassifierResultsTree->SetBranchAddress(fMTEWithClassifierResultsDataPtr->GetBranchName().c_str(), &fMTEWithClassifierResultsDataPtr); return true; } @@ -728,7 +814,7 @@ namespace Katydid fMTEWithClassifierResultsDataPtr = new Cicada::TMTEWithClassifierResultsData(); - fMTEWithClassifierResultsTree->Branch("Event", "Cicada::TMTEWithClassifierResultsData", &fMTEWithClassifierResultsDataPtr); + fMTEWithClassifierResultsTree->Branch(fMTEWithClassifierResultsDataPtr->GetBranchName().c_str(), "Cicada::TMTEWithClassifierResultsData", &fMTEWithClassifierResultsDataPtr); return true; } diff --git a/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterEventAnalysis.hh b/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterEventAnalysis.hh index fabe9e034..7e1e3fa02 100644 --- a/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterEventAnalysis.hh +++ b/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterEventAnalysis.hh @@ -13,6 +13,9 @@ #include "KTData.hh" #include "Rtypes.h" +#include "TClonesArray.h" +#include "TNtupleD.h" +#include "KTROOTData.hh" #include @@ -34,6 +37,7 @@ namespace Katydid //class KTFrequencyCandidateData; //class KTWaterfallCandidateData; + // class TSparseWaterfallCandidateData; struct TFrequencyCandidateData { @@ -60,33 +64,44 @@ namespace Katydid Double_t fMeanStartFrequency; Double_t fMeanEndFrequency; Double_t fFrequencyWidth; + UInt_t fStartRecordNumber; + UInt_t fStartSampleNumber; + UInt_t fEndRecordNumber; + UInt_t fEndSampleNumber; TH2D* fCandidate; }; // commented-out fields match fields not yet implemented in KTSparseWaterfallCandidateData - struct TSparseWaterfallCandidateData - { - TGraph2D* fPoints; - UInt_t fComponent; - UInt_t fAcquisitionID; - UInt_t fCandidateID; - //Double_t fTimeBinWidth; - //Double_t fFreqBinWidth; - Double_t fTimeInRunC; - Double_t fTimeLength; - //ULong64_t fFirstSliceNumber; - //ULong64_t fLastSliceNumber; - Double_t fMinFrequency; - Double_t fMaxFrequency; - //Double_t fMeanStartFrequency; - //Double_t fMeanEndFrequency; - Double_t fFrequencyWidth; - //UInt_t fStartRecordNumber; - //UInt_t fStartSampleNumber; - //UInt_t fEndRecordNumber; - //UInt_t fEndSampleNumber; - }; + // struct TDiscriminatedPoint + // { + // Double_t fTimeInRunC; + // Double_t fFrequency; + // Double_t fAmplitude; + // Double_t fTimeInAcq; + // Double_t fMean; + // Double_t fVariance; + // Double_t fNeighborhoodAmplitude; + // }; + + // struct TSparseWaterfallCandidateData + // { + // UInt_t fComponent; + // UInt_t fAcquisitionID; + // UInt_t fCandidateID; + // //Double_t fTimeBinWidth; + // //Double_t fFreqBinWidth; + // Double_t fTimeInRunC; + // Double_t fTimeLength; + // //ULong64_t fFirstSliceNumber; + // //ULong64_t fLastSliceNumber; + // Double_t fMinFrequency; + // Double_t fMaxFrequency; + // //Double_t fMeanStartFrequency; + // //Double_t fMeanEndFrequency; + // Double_t fFrequencyWidth; + // TNtupleD* fPoints; //<- TimeInRunc, Frequency, Amplitude, Threshold, ..., ... + // }; struct TMultiPeakTrackData { @@ -226,7 +241,7 @@ namespace Katydid TFrequencyCandidateData fFreqCandidateData; TWaterfallCandidateData fWaterfallCandidateData; - TSparseWaterfallCandidateData fSparseWaterfallCandidateData; + TSparseWaterfallCandidateData* fSparseWaterfallCandidateDataPtr; Cicada::TProcessedTrackData* fProcessedTrackDataPtr; Cicada::TProcessedMPTData* fProcessedMPTDataPtr; TMultiPeakTrackData fMultiPeakTrackData; diff --git a/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterSpectrumAnalysis.cc b/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterSpectrumAnalysis.cc index 79816015c..755e818a8 100644 --- a/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterSpectrumAnalysis.cc +++ b/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterSpectrumAnalysis.cc @@ -94,6 +94,9 @@ namespace Katydid fDiscPoints1DData.fAbscissa = it->second.fAbscissa; fDiscPoints1DData.fOrdinate = it->second.fOrdinate; fDiscPoints1DData.fThreshold = it->second.fThreshold; + fDiscPoints1DData.fMean = it->second.fMean; + fDiscPoints1DData.fVariance = it->second.fVariance; + fDiscPoints1DData.fNeighborhoodAmplitude = it->second.fNeighborhoodAmplitude; fDiscPoints1DTree->Fill(); } @@ -183,6 +186,9 @@ namespace Katydid fKDTreePointData.fTimeInRunC = it->fCoords[0]; fKDTreePointData.fFrequency = it->fCoords[1]; fKDTreePointData.fAmplitude = it->fAmplitude; + fKDTreePointData.fMean = it->fMean; + fKDTreePointData.fVariance = it->fVariance; + fKDTreePointData.fNeighborhoodAmplitude = it->fNeighborhoodAmplitude; fKDTreePointData.fNoiseFlag = it->fNoiseFlag; KTKDTreeData::TreeIndex::Neighbors neighbors = index->NearestNeighborsByNumber(pid, 2); fKDTreePointData.fNNDistance = neighbors.dist(1); diff --git a/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterSpectrumAnalysis.hh b/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterSpectrumAnalysis.hh index 965f32d68..15236c22a 100644 --- a/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterSpectrumAnalysis.hh +++ b/Source/IO/ROOTTreeWriter/KTROOTTreeTypeWriterSpectrumAnalysis.hh @@ -30,6 +30,9 @@ namespace Katydid Double_t fAbscissa; Double_t fOrdinate; Double_t fThreshold; + Double_t fMean; //<- + Double_t fVariance; //<- + Double_t fNeighborhoodAmplitude; //<- }; struct TKDTreePointData @@ -39,6 +42,9 @@ namespace Katydid Double_t fTimeInRunC; Double_t fFrequency; Double_t fAmplitude; + Double_t fMean; + Double_t fVariance; + Double_t fNeighborhoodAmplitude; Bool_t fNoiseFlag; Double_t fNNDistance; UInt_t fKNNWithin0p22; diff --git a/Source/SpectrumAnalysis/KTConvolution.cc b/Source/SpectrumAnalysis/KTConvolution.cc index 84430527b..39e77881b 100644 --- a/Source/SpectrumAnalysis/KTConvolution.cc +++ b/Source/SpectrumAnalysis/KTConvolution.cc @@ -369,165 +369,6 @@ namespace Katydid return CoreConvolve1D( static_cast< KTFrequencySpectrumDataPolarCore& >(data), newData ); } - template< class XSpectrumDataCore, class XConvolvedSpectrumTypeData > - bool KTConvolution1D::CoreConvolve1D( XSpectrumDataCore& data, XConvolvedSpectrumTypeData& newData ) - { - newData.SetNComponents( data.GetNComponents() ); - - // Set overlap-and-save method parameters - // These do not change, but I want to group them together like this so it's easy to follow - int block = GetBlockSize(); - int overlap = fKernelSize - 1; - int step = block - overlap; - - KTINFO(sdlog, "Block size: " << block); - KTINFO(sdlog, "Overlap: " << overlap); - KTINFO(sdlog, "Step size: " << step); - - int nBinsTotal = GetSpectrum( data, 0 )->GetNFrequencyBins(); - KTINFO(sdlog, "nBinsTotal = " << nBinsTotal); - - // Now that nBinsTotal is determined, we can initialize the DFTs - // The following conditional should only be true on the first slice - if( ! fInitialized ) - { - Initialize( nBinsTotal, block, step, overlap ); - } - - // First loop over components - for( unsigned iComponent = 0; iComponent < data.GetNComponents(); ++iComponent ) - { - KTINFO(sdlog, "Starting component: " << iComponent); - - // Get power spectrum and initialize convolved spectrum for this component - typename XSpectrumDataCore::spectrum_type* transformedSpectrum = DoConvolution( GetSpectrum( data, iComponent ), block, step, overlap ); - - if( transformedSpectrum == nullptr ) - { - KTERROR( sdlog, "Convolution was unsuccessful. Aborting." ); - return false; - } - - // Set power spectrum - newData.SetSpectrum( transformedSpectrum, iComponent ); - KTDEBUG(sdlog, "Filled new spectrum"); - } - - KTINFO(sdlog, "All components finished successfully!"); - - return true; - } - - template< class XSpectraType > - XSpectraType* KTConvolution1D::DoConvolution( const XSpectraType* myInitialSpectrum, const int block, const int step, const int overlap ) - { - // Block loop parameters - int nBin = 0; - int nBinsTotal = myInitialSpectrum->GetNFrequencyBins(); - int blockNumber = 0; - int position = 0; - - // non-const version - XSpectraType* initialSpectrum = new XSpectraType( *myInitialSpectrum ); - - // If we're doing cross-correlation, first we need to conjugate and reverse the input spectrum - if( fTransformType == "cross-correlation" ) - { - ConjugateAndReverse( *initialSpectrum ); - } - - XSpectraType* transformedSpectrum = new XSpectraType( nBinsTotal, initialSpectrum->GetRangeMin(), initialSpectrum->GetRangeMax() ); - - if( ! SetUpGeneralVars< XSpectraType* >() ) - { - KTERROR(sdlog, "Spectrum type unknown. Returning blank spectrum"); - return transformedSpectrum; - } - - // Loop over block numbers - while( (blockNumber+1) * step <= nBinsTotal ) - { - KTDEBUG(sdlog, "Block number: " << blockNumber); - KTDEBUG(sdlog, "Starting position: " << blockNumber * step - overlap); - KTDEBUG(sdlog, "nBinsTotal: " << nBinsTotal); - - // Fill input array - for( nBin = 0; nBin < block; ++nBin ) - { - position = nBin + blockNumber * step - overlap; - SetInputArray( position, nBin, initialSpectrum ); - } - - // FFT of input block - KTDEBUG(sdlog, "Performing DFT"); - fftw_execute( fGeneralForwardPlan ); - - // Bin multiplication in fourier space - KTDEBUG(sdlog, "Multiplying arrays in fourier space"); - - for( int nBin = 0; nBin < nBinLimitRegular; ++nBin ) - { - fGeneralTransformedOutputArray[nBin][0] = fGeneralTransformedInputArray[nBin][0] * fGeneralTransformedKernelArray[nBin][0] - fGeneralTransformedInputArray[nBin][1] * fGeneralTransformedKernelArray[nBin][1]; - fGeneralTransformedOutputArray[nBin][1] = fGeneralTransformedInputArray[nBin][0] * fGeneralTransformedKernelArray[nBin][1] + fGeneralTransformedInputArray[nBin][1] * fGeneralTransformedKernelArray[nBin][0]; - } - - // Reverse FFT of output block - KTDEBUG(sdlog, "Performing reverse DFT"); - fftw_execute( fGeneralReversePlan ); - - // Loop over bins in the output block and fill the convolved spectrum - for( nBin = overlap; nBin < block; ++nBin ) - { - SetOutputArray( nBin - overlap + blockNumber * step, nBin, *transformedSpectrum, block ); - } - - // Increment block number - ++blockNumber; - } - - if( blockNumber * step == nBinsTotal ) - { - KTINFO(sdlog, "Reached end of input data"); - return transformedSpectrum; - } - - KTINFO(sdlog, "Reached final block"); - KTINFO(sdlog, "Starting position: " << blockNumber * step - overlap); - - // Same procedure as above, this time with a shorter final block - - for( nBin = 0; position+1 < nBinsTotal; ++nBin ) - { - position = nBin + blockNumber * step - overlap; - SetInputArray( position, nBin, initialSpectrum ); - } - - KTINFO(sdlog, "Short array length = " << nBin); - KTDEBUG(sdlog, "Initialized short array length = " << fShortSize); - - // FFT of input block - fftw_execute( fGeneralForwardPlanShort ); - - for( int nBin = 0; nBin < nBinLimitShort; ++nBin ) - { - fGeneralTransformedOutputArray[nBin][0] = fGeneralTransformedInputArray[nBin][0] * fGeneralTransformedKernelArray[nBin][0] - fGeneralTransformedInputArray[nBin][1] * fGeneralTransformedKernelArray[nBin][1]; - fGeneralTransformedOutputArray[nBin][1] = fGeneralTransformedInputArray[nBin][0] * fGeneralTransformedKernelArray[nBin][1] + fGeneralTransformedInputArray[nBin][1] * fGeneralTransformedKernelArray[nBin][0]; - } - - // Reverse FFT of output block - fftw_execute( fGeneralReversePlanShort ); - - // Loop over bins in the output block and fill the convolved spectrum - for( nBin = overlap; nBin < fShortSize; ++nBin ) - { - SetOutputArray( nBin - overlap + blockNumber * step, nBin, *transformedSpectrum, fShortSize ); - } - - KTINFO(sdlog, "Component finished!"); - - return transformedSpectrum; - } - template< class XSpectraType > bool KTConvolution1D::SetUpGeneralVars() { diff --git a/Source/SpectrumAnalysis/KTConvolution.hh b/Source/SpectrumAnalysis/KTConvolution.hh index 73b838336..644155580 100644 --- a/Source/SpectrumAnalysis/KTConvolution.hh +++ b/Source/SpectrumAnalysis/KTConvolution.hh @@ -16,6 +16,8 @@ #include "KTFrequencySpectrumDataFFTW.hh" #include "KTPowerSpectrumData.hh" +#include "KTLogger.hh" + #include #include #include @@ -71,6 +73,8 @@ namespace Katydid - "fs-polar": void (Nymph::KTDataPtr) -- Emitted upon convolution of a frequency spectrum; Guarantees KTConvolvedFrequencySpectrumDataPolar */ + KTLOGGER(convlog_hh, "KTConvolution.hh"); + class KTConvolution1D : public Nymph::KTProcessor { @@ -199,6 +203,169 @@ namespace Katydid }; + template< class XSpectrumDataCore, class XConvolvedSpectrumTypeData > + bool KTConvolution1D::CoreConvolve1D( XSpectrumDataCore& data, XConvolvedSpectrumTypeData& newData ) + { + newData.SetNComponents( data.GetNComponents() ); + + // Set overlap-and-save method parameters + // These do not change, but I want to group them together like this so it's easy to follow + int block = GetBlockSize(); + int overlap = fKernelSize - 1; + int step = block - overlap; + + KTINFO(convlog_hh, "Block size: " << block); + KTINFO(convlog_hh, "Overlap: " << overlap); + KTINFO(convlog_hh, "Step size: " << step); + + int nBinsTotal = GetSpectrum( data, 0 )->GetNFrequencyBins(); + KTINFO(convlog_hh, "nBinsTotal = " << nBinsTotal); + + // Now that nBinsTotal is determined, we can initialize the DFTs + // The following conditional should only be true on the first slice + if( ! fInitialized ) + { + Initialize( nBinsTotal, block, step, overlap ); + } + + // First loop over components + for( unsigned iComponent = 0; iComponent < data.GetNComponents(); ++iComponent ) + { + KTINFO(convlog_hh, "Starting component: " << iComponent); + + // Get power spectrum and initialize convolved spectrum for this component + typename XSpectrumDataCore::spectrum_type* transformedSpectrum = DoConvolution( GetSpectrum( data, iComponent ), block, step, overlap ); + + if( transformedSpectrum == nullptr ) + { + KTERROR( convlog_hh, "Convolution was unsuccessful. Aborting." ); + return false; + } + + // Set power spectrum + newData.SetSpectrum( transformedSpectrum, iComponent ); + KTDEBUG(convlog_hh, "Filled new spectrum"); + } + + KTINFO(convlog_hh, "All components finished successfully!"); + + return true; + } + + template< class XSpectraType > + XSpectraType* KTConvolution1D::DoConvolution( const XSpectraType* myInitialSpectrum, const int block, const int step, const int overlap ) + { + int nBinsTotal = myInitialSpectrum->GetNFrequencyBins(); + + // non-const version + XSpectraType* initialSpectrum = new XSpectraType( *myInitialSpectrum ); + + // If we're doing cross-correlation, first we need to conjugate and reverse the input spectrum + if( fTransformType == "cross-correlation" ) + { + ConjugateAndReverse( *initialSpectrum ); + } + + XSpectraType* transformedSpectrum = new XSpectraType( nBinsTotal, initialSpectrum->GetRangeMin(), initialSpectrum->GetRangeMax() ); + + if( ! SetUpGeneralVars< XSpectraType* >() ) + { + KTERROR(convlog_hh, "Spectrum type unknown. Returning blank spectrum"); + return transformedSpectrum; + } + + // Loop over block numbers + int blockNumber = 0; + int position = 0; + while( (blockNumber+1) * step <= nBinsTotal ) + { + KTDEBUG(convlog_hh, "Block number: " << blockNumber); + KTDEBUG(convlog_hh, "Starting position: " << blockNumber * step - overlap); + KTDEBUG(convlog_hh, "nBinsTotal: " << nBinsTotal); + + // Fill input array + for( int nBin = 0; nBin < block; ++nBin ) + { + position = nBin + blockNumber * step - overlap; + SetInputArray( position, nBin, initialSpectrum ); + } + + // FFT of input block + KTDEBUG(convlog_hh, "Performing DFT"); + fftw_execute( fGeneralForwardPlan ); + + // Bin multiplication in fourier space + KTDEBUG(convlog_hh, "Multiplying arrays in fourier space"); + + for( int nBin = 0; nBin < nBinLimitRegular; ++nBin ) + { + fGeneralTransformedOutputArray[nBin][0] = fGeneralTransformedInputArray[nBin][0] * fGeneralTransformedKernelArray[nBin][0] - fGeneralTransformedInputArray[nBin][1] * fGeneralTransformedKernelArray[nBin][1]; + fGeneralTransformedOutputArray[nBin][1] = fGeneralTransformedInputArray[nBin][0] * fGeneralTransformedKernelArray[nBin][1] + fGeneralTransformedInputArray[nBin][1] * fGeneralTransformedKernelArray[nBin][0]; + } + + // Reverse FFT of output block + KTDEBUG(convlog_hh, "Performing reverse DFT"); + fftw_execute( fGeneralReversePlan ); + + // Loop over bins in the output block and fill the convolved spectrum + for( int nBin = overlap; nBin < block; ++nBin ) + { + SetOutputArray( nBin - overlap + blockNumber * step, nBin, *transformedSpectrum, block ); + } + + // Increment block number + ++blockNumber; + } + + if( blockNumber * step == nBinsTotal ) + { + KTINFO(convlog_hh, "Reached end of input data"); + return transformedSpectrum; + } + + KTINFO(convlog_hh, "Reached final block"); + KTINFO(convlog_hh, "Starting position: " << blockNumber * step - overlap); + + // Same procedure as above, this time with a shorter final block + +#ifndef NDEBUG + int lastNBin = 0; +#endif + for( int nBin = 0; position+1 < nBinsTotal; ++nBin ) + { + position = nBin + blockNumber * step - overlap; + SetInputArray( position, nBin, initialSpectrum ); +#ifndef NDEBUG + lastNBin = nBin; +#endif + } + + KTDEBUG(convlog_hh, "Short array length = " << lastNBin); + KTDEBUG(convlog_hh, "Initialized short array length = " << fShortSize); + + // FFT of input block + fftw_execute( fGeneralForwardPlanShort ); + + for( int nBin = 0; nBin < nBinLimitShort; ++nBin ) + { + fGeneralTransformedOutputArray[nBin][0] = fGeneralTransformedInputArray[nBin][0] * fGeneralTransformedKernelArray[nBin][0] - fGeneralTransformedInputArray[nBin][1] * fGeneralTransformedKernelArray[nBin][1]; + fGeneralTransformedOutputArray[nBin][1] = fGeneralTransformedInputArray[nBin][0] * fGeneralTransformedKernelArray[nBin][1] + fGeneralTransformedInputArray[nBin][1] * fGeneralTransformedKernelArray[nBin][0]; + } + + // Reverse FFT of output block + fftw_execute( fGeneralReversePlanShort ); + + // Loop over bins in the output block and fill the convolved spectrum + for( int nBin = overlap; nBin < fShortSize; ++nBin ) + { + SetOutputArray( nBin - overlap + blockNumber * step, nBin, *transformedSpectrum, fShortSize ); + } + + KTINFO(convlog_hh, "Component finished!"); + + return transformedSpectrum; + } + inline const KTPowerSpectrum* KTConvolution1D::GetSpectrum( KTPowerSpectrumDataCore& data, unsigned iComponent ) { return data.GetSpectrum( iComponent ); diff --git a/Source/SpectrumAnalysis/KTCreateKDTree.cc b/Source/SpectrumAnalysis/KTCreateKDTree.cc index a9841a41b..95a047ae5 100644 --- a/Source/SpectrumAnalysis/KTCreateKDTree.cc +++ b/Source/SpectrumAnalysis/KTCreateKDTree.cc @@ -13,6 +13,7 @@ #include "KTProcessedTrackData.hh" #include "KTSliceHeader.hh" #include "KTSparseWaterfallCandidateData.hh" +#include "KTDiscriminatedPoint.hh" using std::string; using std::vector; @@ -142,6 +143,9 @@ namespace Katydid newPoint.fCoords[1] = fInvScalingY * pIt->second.fAbscissa; newPoint.fAmplitude = pIt->second.fOrdinate; newPoint.fTimeInAcq = fInvScalingX * (slHeader.GetTimeInAcq() + 0.5 * slHeader.GetSliceLength()); + newPoint.fMean = pIt->second.fMean; + newPoint.fVariance = pIt->second.fVariance; + newPoint.fNeighborhoodAmplitude = pIt->second.fNeighborhoodAmplitude; fTreeData.AddPoint(newPoint, iComponent); } KTDEBUG(kdlog, "Tree data (component " << iComponent << ") now has " << fTreeData.GetSetOfPoints(iComponent).size() << " points (Slice Number: " << newPoint.fSliceNumber << ")"); @@ -185,14 +189,17 @@ namespace Katydid KTKDTreeData::Point newPoint; newPoint.fSliceNumber = 0; // slice number isn't available in KTSparseWaterfallCandidateData if (newPoint.fSliceNumber > fTreeData.GetLastSlice()) fTreeData.SetLastSlice(newPoint.fSliceNumber); - const KTSparseWaterfallCandidateData::Points& incomingPts = swfcData.GetPoints(); - for (KTSparseWaterfallCandidateData::Points::const_iterator pIt = incomingPts.begin(); + const KTDiscriminatedPoints& incomingPts = swfcData.GetPoints(); + for (KTDiscriminatedPoints::const_iterator pIt = incomingPts.begin(); pIt != incomingPts.end(); ++pIt) { newPoint.fCoords[0] = fInvScalingX * pIt->fTimeInRunC; newPoint.fCoords[1] = fInvScalingY * pIt->fFrequency; newPoint.fAmplitude = pIt->fAmplitude; newPoint.fTimeInAcq = fInvScalingX * pIt->fTimeInAcq; + newPoint.fMean = pIt->fMean; + newPoint.fVariance = pIt->fVariance; + newPoint.fNeighborhoodAmplitude = pIt->fNeighborhoodAmplitude; fTreeData.AddPoint(newPoint, component); } KTDEBUG(kdlog, "Tree data (component " << component << ") now has " << fTreeData.GetSetOfPoints(component).size() << " points"); diff --git a/Source/SpectrumAnalysis/KTHoughTransform.cc b/Source/SpectrumAnalysis/KTHoughTransform.cc index a03c2ad45..0fd8c12aa 100644 --- a/Source/SpectrumAnalysis/KTHoughTransform.cc +++ b/Source/SpectrumAnalysis/KTHoughTransform.cc @@ -12,6 +12,7 @@ #include "KTMath.hh" #include "KTFrequencySpectrumPolar.hh" #include "KTSparseWaterfallCandidateData.hh" +#include "KTDiscriminatedPoint.hh" #include @@ -56,16 +57,16 @@ namespace Katydid { KTHoughData& newData = data.Of< KTHoughData >().SetNComponents(1); - const KTSparseWaterfallCandidateData::Points& points = data.GetPoints(); + const KTDiscriminatedPoints& points = data.GetPoints(); - KTPhysicalArray< 2, double >* newTransform = TransformPoints(points, data.GetTimeInRunC(), data.GetTimeLength(), data.GetMinimumFrequency(), data.GetFrequencyWidth()); + KTPhysicalArray< 2, double >* newTransform = TransformPoints(points, data.GetTimeInRunC(), data.GetTimeLength(), data.GetMinFrequency(), data.GetFrequencyWidth()); if (newTransform == NULL) { KTERROR(htlog, "Something went wrong in the transform"); } else { - newData.SetTransform(newTransform, data.GetTimeInRunC(), data.GetTimeLength(), data.GetMinimumFrequency(), data.GetFrequencyWidth(), 0); + newData.SetTransform(newTransform, data.GetTimeInRunC(), data.GetTimeLength(), data.GetMinFrequency(), data.GetFrequencyWidth(), 0); } KTINFO(htlog, "Completed hough transform"); diff --git a/Source/SpectrumAnalysis/KTHoughTransform.hh b/Source/SpectrumAnalysis/KTHoughTransform.hh index 981ebbc26..e25680ea9 100644 --- a/Source/SpectrumAnalysis/KTHoughTransform.hh +++ b/Source/SpectrumAnalysis/KTHoughTransform.hh @@ -17,6 +17,7 @@ #include "KTSlot.hh" #include "KTSparseWaterfallCandidateData.hh" #include "KTWaterfallCandidateData.hh" +#include "KTMemberVariable.hh" #include @@ -54,7 +55,7 @@ namespace Katydid { public: typedef KTDiscriminatedPoints2DData::SetOfPoints SetOfPoints; - typedef KTSparseWaterfallCandidateData::Points SWFPoints; + typedef KTDiscriminatedPoints SWFPoints; public: KTHoughTransform(const std::string& name = "hough-transform"); @@ -62,18 +63,6 @@ namespace Katydid bool Configure(const scarab::param_node* node); - unsigned GetNThetaPoints() const; - void SetNThetaPoints(unsigned nPoints); - - unsigned GetNRPoints() const; - void SetNRPoints(unsigned nPoints); - - private: - - unsigned fNThetaPoints; - unsigned fNRPoints; - - public: bool TransformData(KTSparseWaterfallCandidateData& data); KTPhysicalArray< 2, double >* TransformPoints(const SWFPoints& points, double minTime, double timeLength, double minFreq, double freqWidth); @@ -82,6 +71,9 @@ namespace Katydid bool TransformData(KTDiscriminatedPoints2DData& data); KTPhysicalArray< 2, double >* TransformSetOfPoints(const SetOfPoints& points, unsigned nTimeBins, unsigned nFreqBins); + + MEMBERVARIABLE(unsigned, NThetaPoints); + MEMBERVARIABLE(unsigned, NRPoints); private: @@ -108,27 +100,5 @@ namespace Katydid }; - inline unsigned KTHoughTransform::GetNThetaPoints() const - { - return fNThetaPoints; - } - - inline void KTHoughTransform::SetNThetaPoints(unsigned nPoints) - { - fNThetaPoints = nPoints; - return; - } - - inline unsigned KTHoughTransform::GetNRPoints() const - { - return fNRPoints; - } - - inline void KTHoughTransform::SetNRPoints(unsigned nPoints) - { - fNRPoints = nPoints; - return; - } - } /* namespace Katydid */ #endif /* KTHOUGHTRANSFORM_HH_ */ diff --git a/Source/SpectrumAnalysis/KTSequentialTrackFinder.cc b/Source/SpectrumAnalysis/KTSequentialTrackFinder.cc index e0c77c3a8..72aa30b81 100644 --- a/Source/SpectrumAnalysis/KTSequentialTrackFinder.cc +++ b/Source/SpectrumAnalysis/KTSequentialTrackFinder.cc @@ -24,7 +24,7 @@ namespace Katydid KTSequentialTrackFinder::KTSequentialTrackFinder(const std::string& name) : KTProcessor(name), - fTrimmingFactor(3.2), + fTrimmingThreshold(6), fLinePowerRadius(4), fPointAmplitudeAfterVisit(0), fMinFreqBinDistance(10), @@ -47,16 +47,22 @@ namespace Katydid fCalculateMaxBin(true), fActiveLines(), fNLines(0), - fApplyPowerCut(false), - fApplyDensityCut(false), - fPowerThreshold(0.0), - fDensityThreshold(0.0), + fApplyTotalPowerCut(false), + fApplyAveragePowerCut(false), + fApplyTotalSNRCut(false), + fApplyAverageSNRCut(false), + fApplyTotalUnitlessResidualCut(false), + fApplyAverageUnitlessResidualCut(false), + fTotalPowerThreshold(0.0), + fAveragePowerThreshold(0.0), + fTotalSNRThreshold(0.0), + fAverageSNRThreshold(0.0), + fTotalUnitlessResidualThreshold(0.0), + fAverageUnitlessResidualThreshold(0.0), fCalcSlope(&KTSequentialTrackFinder::CalculateSlopeFirstRef), - fTrackSignal("pre-candidate", this), + fLineSignal("seq-cand", this), fClusterDoneSignal("clustering-done", this), - //fGainVarSlot("gv", this, &KTSequentialTrackFinder::SetPreCalcGainVar), - //fPSPreCalcSlot("ps-pre", this, &KTSeqTrack::PointLineAssignment), - //fPSSlot("ps-in", this, &KTSequentialTrackFinder::CollectPointsFromSlice), + fDiscrimPowerSlot("disc-1d-ps", this, &KTSequentialTrackFinder::CollectDiscrimPointsFromSlice), fDiscrimSlot("disc-1d", this, &KTSequentialTrackFinder::CollectDiscrimPointsFromSlice), fDoneSlot("done", this, &KTSequentialTrackFinder::AcquisitionIsOver, &fClusterDoneSignal) { @@ -73,7 +79,7 @@ namespace Katydid SetMinFrequency(node->get_value("min-frequency", GetMinFrequency())); SetMaxFrequency(node->get_value("max-frequency", GetMaxFrequency())); - SetTrimmingFactor(node->get_value("trimming-factor", GetTrimmingFactor())); + SetTrimmingThreshold(node->get_value("trimming-threshold", GetTrimmingThreshold())); SetLinePowerRadius(node->get_value("line-power-radius", GetLinePowerRadius())); SetMinPoints(node->get_value("min-points", GetMinPoints())); SetMinSlope(node->get_value("min-slope", GetMinSlope())); @@ -115,13 +121,33 @@ namespace Katydid } if (node->has("apply-power-cut")) { - SetApplyPowerCut(node->get_value("apply-power-cut", GetApplyPowerCut())); - SetPowerThreshold(node->get_value("power-threshold", GetPowerThreshold())); + SetApplyTotalPowerCut(node->get_value("apply-total-power-cut", GetApplyTotalPowerCut())); + SetTotalPowerThreshold(node->get_value("total-power-threshold", GetTotalPowerThreshold())); } if (node->has("apply-power-density-cut")) { - SetApplyDensityCut(node->get_value("apply-power-density-cut", GetApplyDensityCut())); - SetDensityThreshold(node->get_value("power-density-threshold", GetDensityThreshold())); + SetApplyAveragePowerCut(node->get_value("apply-average-power-cut", GetApplyAveragePowerCut())); + SetAveragePowerThreshold(node->get_value("average-power-threshold", GetAveragePowerThreshold())); + } + if (node->has("apply-total-snr-cut")) + { + SetApplyTotalSNRCut(node->get_value("apply-total-snr-cut", GetApplyTotalSNRCut())); + SetTotalSNRThreshold(node->get_value("total-snr-threshold", GetTotalSNRThreshold())); + } + if (node->has("apply-average-snr-cut")) + { + SetApplyAverageSNRCut(node->get_value("apply-average-snr-cut", GetApplyAverageSNRCut())); + SetAverageSNRThreshold(node->get_value("average-snr-threshold", GetAverageSNRThreshold())); + } + if (node->has("apply-total-nup-cut")) + { + SetApplyTotalUnitlessResidualCut(node->get_value("apply-total-nup-cut", GetApplyTotalUnitlessResidualCut())); + SetTotalUnitlessResidualThreshold(node->get_value("total-nup-threshold", GetTotalUnitlessResidualThreshold())); + } + if (node->has("apply-average-nup-cut")) + { + SetApplyAverageUnitlessResidualCut(node->get_value("apply-average-nup-cut", GetApplyAverageUnitlessResidualCut())); + SetAverageUnitlessResidualThreshold(node->get_value("average-nup-threshold", GetAverageUnitlessResidualThreshold())); } if (node->has("n-slope-points")) { @@ -129,11 +155,11 @@ namespace Katydid } if (node->has("slope-method")) { - if (node->get_value("slope-method") == "weighted_first_point_ref") + if (node->get_value("slope-method") == "weighted-first-point-ref") { SetSlopeMethod(slopeMethod::weighted_first_point_ref); } - if (node->get_value("slope-method") == "weighted_last_point_ref") + else if (node->get_value("slope-method") == "weighted-last-point-ref") { SetSlopeMethod(slopeMethod::weighted_last_point_ref); } @@ -142,9 +168,9 @@ namespace Katydid // SetSlopeMethod(slopeMethod::weighted); //} else if (node->get_value("slope-method") == "unweighted") - { - SetSlopeMethod(slopeMethod::unweighted); - } + { + SetSlopeMethod(slopeMethod::unweighted); + } else { KTERROR(stflog, "Set slope method not valid"); @@ -177,6 +203,11 @@ namespace Katydid this->CollectDiscrimPoints(slHeader, spectrum, discrimPoints); return true; } + bool KTSequentialTrackFinder::CollectDiscrimPointsFromSlice(KTSliceHeader& slHeader, KTDiscriminatedPoints1DData& discrimPoints) + { + this->CollectDiscrimPoints(slHeader, discrimPoints); + return true; + } bool KTSequentialTrackFinder::CollectDiscrimPoints(const KTSliceHeader& slHeader, const KTPowerSpectrumData& spectrum, const KTDiscriminatedPoints1DData& discrimPoints) @@ -218,27 +249,88 @@ namespace Katydid // this vector will collect the discriminated points - std::vector points; + KTDiscriminatedPowerSortedPoints points; const KTDiscriminatedPoints1DData::SetOfPoints& incomingPts = discrimPoints.GetSetOfPoints(iComponent); for (KTDiscriminatedPoints1DData::SetOfPoints::const_iterator pIt = incomingPts.begin(); pIt != incomingPts.end(); ++pIt) { //KTINFO(stflog, "discriminated point: bin = " <first<< ", frequency = "<second.fAbscissa<< ", amplitude = "<second.fOrdinate<<", "<first) <<", threshold = "<second.fThreshold); - Point newPoint(pIt->first, pIt->second.fAbscissa, newTimeInAcq, newTimeInRunC, pIt->second.fOrdinate, pIt->second.fThreshold, acqID, iComponent); - points.push_back(newPoint); + KTDiscriminatedPoint newPoint(newTimeInRunC, pIt->second.fAbscissa, pIt->second.fOrdinate, newTimeInAcq, pIt->second.fMean, pIt->second.fVariance, pIt->second.fNeighborhoodAmplitude); + newPoint.fBinInSlice = pIt->first; + points.insert(newPoint); + } + + KTDEBUG( stflog, "Collected "<()); + + // Loop over the high power points + this->LoopOverHighPowerPoints(powerSpectrum, points, acqID, iComponent); + + } + return true; + } + + bool KTSequentialTrackFinder::CollectDiscrimPoints(const KTSliceHeader& slHeader, const KTDiscriminatedPoints1DData& discrimPoints) + { + KTDEBUG(stflog, "Initial slope is: "<first >= fMinBin and pIt->first <= fMaxBin ) + { + //KTINFO(stflog, "discriminated point: bin = " <first<< ", frequency = "<second.fAbscissa<< ", amplitude = "<second.fOrdinate <<", threshold = "<second.fThreshold); + KTDiscriminatedPoint newPoint(newTimeInRunC, pIt->second.fAbscissa, pIt->second.fOrdinate, newTimeInAcq, pIt->second.fMean, pIt->second.fVariance, pIt->second.fNeighborhoodAmplitude); + newPoint.fBinInSlice = pIt->first; + points.insert(newPoint); + } } // sort points by power - std::sort(points.begin(), points.end(),std::less()); + //std::sort(points.begin(), points.end(),std::less()); + KTDEBUG( stflog, "Collected "<LoopOverHighPowerPoints(powerSpectrum, points, iComponent); + this->LoopOverHighPowerPoints(points, acqID, iComponent); } return true; } - bool KTSequentialTrackFinder::LoopOverHighPowerPoints(KTPowerSpectrum& slice, std::vector& points, unsigned component) + + bool KTSequentialTrackFinder::LoopOverHighPowerPoints(KTPowerSpectrum& slice, KTDiscriminatedPowerSortedPoints& points, uint64_t acqID, unsigned component) { KTDEBUG(stflog, "Time and Frequency tolerances are "<::reverse_iterator pointIt = points.rbegin(); pointIt != points.rend(); ++pointIt) + for(KTDiscriminatedPowerSortedPoints::reverse_iterator pointIt = points.rbegin(); pointIt != points.rend(); ++pointIt) { - newFreq = pointIt->fPointFreq; + newFreq = pointIt->fFrequency; // The amplitude of the bin the in the slice at the position of the point in the power spectrum gets set to zero after a visit (in SearchTrueLinePoint) // To prevent that in the next iteration the point gets re-found and added to another line the amplitude of the point is reassigned here - pointIt->fAmplitude = slice(pointIt->fBinInSlice); - if (pointIt->fAmplitude == 0.0) + KTDiscriminatedPoint tempPoint = *pointIt; + tempPoint.fAmplitude = slice(pointIt->fBinInSlice); + if (tempPoint.fAmplitude == 0.0) { KTDEBUG(stflog, "Point amplitude is 0, skipping point"); continue; } else { - this->UpdateLinePoint(*pointIt, slice); - newFreq = pointIt->fPointFreq; + + this->UpdateLinePoint(tempPoint, slice); + newFreq = tempPoint.fFrequency; } - if (newFreq == 0.0 or pointIt->fAmplitude==0.0) + if (newFreq == 0.0 or tempPoint.fAmplitude==0.0) { KTDEBUG(stflog, "Point frequency and/or amplitude is zero, skipping point"); continue; @@ -278,17 +372,17 @@ namespace Katydid //KTDEBUG(stflog, "Currently there are N active Lines "<::iterator lineIt = fActiveLines.begin(); + std::vector< KTSequentialLineData >::iterator lineIt = fActiveLines.begin(); while( lineIt != fActiveLines.end()) { // Check whether line should still be active. If not then check whether the line is a valid new track candidate. - if (lineIt->fEndTimeInRunCfTimeInRunC-fTimeGapTolerance) + if (lineIt->GetEndTimeInRunC() fTimeInRunC-fTimeGapTolerance) { - if (lineIt->fNPoints >= fMinPoints) + if (lineIt->GetNPoints() >= fMinPoints) { - lineIt->LineTrimming(fTrimmingFactor, fMinPoints); + lineIt->LineSNRTrimming(fTrimmingThreshold, fMinPoints); - if (lineIt->fNPoints >= fMinPoints and lineIt->fSlope > fMinSlope) + if (lineIt->GetNPoints() >= fMinPoints and lineIt->GetSlope() >= fMinSlope) { KTINFO(stflog, "Found track candidate"); (this->*fCalcSlope)(*lineIt); @@ -301,27 +395,133 @@ namespace Katydid else { // Under these conditions a point will be added to a line - bool timeCondition = pointIt->fTimeInRunC > lineIt->fEndTimeInRunC; - bool anyPointCondition = std::abs(pointIt->fPointFreq - (lineIt->fEndFrequency + lineIt->fSlope*(pointIt->fTimeInAcq - lineIt->fEndTimeInAcq))) < fFrequencyAcceptance; - bool secondPointCondition = std::abs(pointIt->fPointFreq - (lineIt->fEndFrequency + lineIt->fSlope*(pointIt->fTimeInAcq - lineIt->fEndTimeInAcq))) < fInitialFrequencyAcceptance; + bool timeCondition = tempPoint.fTimeInRunC > lineIt->GetEndTimeInRunC(); + bool anyPointCondition = std::abs(tempPoint.fFrequency - (lineIt->GetEndFrequency() + lineIt->GetSlope()*(pointIt->fTimeInAcq - lineIt->GetEndTimeInAcq()))) < fFrequencyAcceptance; + bool secondPointCondition = std::abs(tempPoint.fFrequency - (lineIt->GetEndFrequency() + lineIt->GetSlope()*(pointIt->fTimeInAcq - lineIt->GetEndTimeInAcq()))) < fInitialFrequencyAcceptance; // if point matches this line: insert if (timeCondition and anyPointCondition) { - lineIt->InsertPoint(*pointIt); + lineIt->AddPoint(tempPoint); (this->*fCalcSlope)(*lineIt); match = true; - ++lineIt; + break; } // if this line consists of only one point so far, try again with different radius - else if (lineIt->fNPoints == 1 and timeCondition and secondPointCondition) + else if (lineIt->GetNPoints() == 1 and timeCondition and secondPointCondition) { KTDEBUG(stflog, "Trying initial-frequency-acceptance "<InsertPoint(*pointIt); + lineIt->AddPoint(tempPoint); (this->*fCalcSlope)(*lineIt); match = true; + break; + } + // if not try next line + else + { ++lineIt; } + } + }//end of while loop. all existing lines were compared + + // if point was not picked up + if (match == false) + { + //KTDEBUG(stflog, "Starting new line"); + + KTSequentialLineData newLine; + newLine.SetSlope( fInitialSlope ); + newLine.SetAcquisitionID( acqID ); + newLine.SetComponent( component ); + newLine.AddPoint(tempPoint); + (this->*fCalcSlope)(newLine); + fActiveLines.push_back(newLine); + match = true; + } + } + } + return true; + } + + bool KTSequentialTrackFinder::LoopOverHighPowerPoints(KTDiscriminatedPowerSortedPoints& points, uint64_t acqID, unsigned component) + { + KTDEBUG(stflog, "Time and Frequency tolerances are "<fBinInSlice<<", power "<fAmplitude); + newFreq = pointIt->fFrequency; + + // Need to think about how to prevent visiting the same neighborhood twice + + if (pointIt->fAmplitude == 0.0) + { + KTDEBUG(stflog, "Point amplitude is 0, skipping point"); + continue; + } + if (newFreq == 0.0 or pointIt->fAmplitude==0.0) + { + KTDEBUG(stflog, "Point frequency and/or amplitude is zero, skipping point"); + continue; + } + else + { + match = false; + + // loop over active lines, in order of earliest start time + // dont need to sort them because they are already sorted by the slice of the line's start point + + //KTDEBUG(stflog, "Currently there are N active Lines "<::iterator lineIt = fActiveLines.begin(); + while( lineIt != fActiveLines.end()) + { + // Check whether line should still be active. If not then check whether the line is a valid new track candidate. + if (lineIt->GetEndTimeInRunC() < pointIt->fTimeInRunC-fTimeGapTolerance) + { + if (lineIt->GetNPoints() >= fMinPoints) + { + lineIt->LineSNRTrimming(fTrimmingThreshold, fMinPoints); + + if (lineIt->GetNPoints() >= fMinPoints and lineIt->GetSlope() >= fMinSlope) + { + KTDEBUG(stflog, "Found line candidate"); + (this->*fCalcSlope)(*lineIt); + this->EmitPreCandidate(*lineIt); + } + } + // in any case, this line should be removed from the vector with active lines + lineIt = fActiveLines.erase(lineIt); + } + else + { + // Under these conditions a point will be added to a line + bool timeCondition = pointIt->fTimeInRunC > lineIt->GetEndTimeInRunC(); + bool anyPointCondition = std::abs(pointIt->fFrequency - (lineIt->GetEndFrequency() + lineIt->GetSlope()*(pointIt->fTimeInAcq - lineIt->GetEndTimeInAcq()))) < fFrequencyAcceptance; + bool secondPointCondition = std::abs(pointIt->fFrequency - (lineIt->GetEndFrequency() + lineIt->GetSlope()*(pointIt->fTimeInAcq - lineIt->GetEndTimeInAcq()))) < fInitialFrequencyAcceptance; + + // if point matches this line: insert + if (timeCondition and anyPointCondition) + { + KTDEBUG(stflog, "Matching conditions fullfilled"); + lineIt->AddPoint(*pointIt); + (this->*fCalcSlope)(*lineIt); + match = true; + break; + } + // if this line consists of only one point so far, try again with different radius + else if (lineIt->GetNPoints() == 1 and timeCondition and secondPointCondition) + { + KTDEBUG(stflog, "Trying initial-frequency-acceptance "<AddPoint(*pointIt); + (this->*fCalcSlope)(*lineIt); + match = true; + break; + } // if not try next line else { @@ -335,10 +535,13 @@ namespace Katydid { //KTDEBUG(stflog, "Starting new line"); - LineRef new_line(fInitialSlope); - new_line.InsertPoint(*pointIt); - (this->*fCalcSlope)(new_line); - fActiveLines.push_back(new_line); + KTSequentialLineData newLine; + newLine.SetSlope( fInitialSlope ); + newLine.SetAcquisitionID( acqID ); + newLine.SetComponent( component ); + newLine.AddPoint(*pointIt); + (this->*fCalcSlope)(newLine); + fActiveLines.push_back(newLine); match = true; } } @@ -347,62 +550,102 @@ namespace Katydid } - bool KTSequentialTrackFinder::EmitPreCandidate(LineRef line) + bool KTSequentialTrackFinder::EmitPreCandidate(KTSequentialLineData& line) { - bool lineIsTrack = true; + KTDEBUG(stflog, "applying cuts and then emitting candidate"); + bool lineIsCandidate = true; + + line.CalculateTotalPower(); + line.CalculateTotalSNR(); + line.CalculateTotalNUP(); - if (fApplyPowerCut) + if ( fApplyTotalPowerCut ) { - if (line.fAmplitudeSum <= fPowerThreshold) + if ( line.GetTotalWidePower() <= fTotalPowerThreshold ) { - lineIsTrack = false; + lineIsCandidate = false; } } - if (fApplyDensityCut) + if ( fApplyAveragePowerCut ) { - if ((double)line.fAmplitudeSum/(line.fEndTimeInRunC-line.fStartTimeInRunC) <= fDensityThreshold) + if ( line.GetTotalWidePower()/(line.GetEndTimeInRunC()-line.GetStartTimeInRunC()) <= fAveragePowerThreshold ) { - lineIsTrack = false; + lineIsCandidate = false; } } - - if (lineIsTrack == true) + if ( fApplyTotalSNRCut ) + { + if ( line.GetTotalWideSNR() <= fTotalSNRThreshold) + { + lineIsCandidate = false; + } + } + if ( fApplyAverageSNRCut ) + { + if ( line.GetTotalWideSNR() / ( line.GetEndTimeInRunC() - line.GetStartTimeInRunC() ) <= fAverageSNRThreshold ) + { + lineIsCandidate = false; + } + } + if ( fApplyTotalUnitlessResidualCut ) + { + if ( line.GetTotalWideNUP() <= fTotalUnitlessResidualThreshold ) + { + lineIsCandidate = false; + } + } + if ( fApplyAverageUnitlessResidualCut ) + { + if ( line.GetTotalWideNUP() / ( line.GetEndTimeInRunC() - line.GetStartTimeInRunC() ) <= fAverageUnitlessResidualThreshold ) + { + lineIsCandidate = false; + } + } + // after all cuts have been applied and point cluster is still a candidate, create SparseWaterfallCandidateData + if (lineIsCandidate == true) { // Set up new data object Nymph::KTDataPtr data( new Nymph::KTData() ); - KTProcessedTrackData& newTrack = data->Of< KTProcessedTrackData >(); - newTrack.SetComponent( line.fComponent ); - newTrack.SetTrackID(fNLines); + KTSequentialLineData& newCand = data->Of< KTSequentialLineData >(); + newCand.SetComponent( line.GetComponent() ); + newCand.SetAcquisitionID( line.GetAcquisitionID()); + newCand.SetCandidateID( fNLines ); + newCand.SetSlope( line.GetSlope() ); + newCand.SetTotalSNR( line.GetTotalSNR() ); + newCand.SetTotalWideSNR( line.GetTotalWideSNR() ); + newCand.SetTotalPower( line.GetTotalPower() ); + newCand.SetTotalWidePower( line.GetTotalWidePower() ); + newCand.SetTotalNUP( line.GetTotalNUP() ); + newCand.SetTotalWideNUP( line.GetTotalWideNUP() ); + ++fNLines; - newTrack.SetStartTimeInRunC( line.fStartTimeInRunC ); - newTrack.SetEndTimeInRunC( line.fEndTimeInRunC ); - newTrack.SetStartTimeInAcq( line.fStartTimeInAcq); - newTrack.SetStartFrequency( line.fStartFrequency ); - newTrack.SetEndFrequency( line.fEndFrequency ); - newTrack.SetSlope(line.fSlope); - newTrack.SetSlopeSigma(line.fSlopeSigma); - newTrack.SetInterceptSigma(line.fInterceptSigma); - newTrack.SetStartFrequencySigma(line.fStartFrequencySigma); - newTrack.SetEndFrequencySigma(line.fEndFrequencySigma); - newTrack.SetTotalPower(line.fAmplitudeSum); + // Add line points to swf candidate + KTDiscriminatedPoints& points = line.GetPoints(); + for(KTDiscriminatedPoints::iterator pointIt = points.begin(); pointIt != points.end(); ++pointIt ) + { + KTDiscriminatedPoint newPoint(*pointIt); + newCand.AddPoint(newPoint); + } // Process & emit new track - KTINFO(stflog, "Now processing track candidate"); - ProcessNewTrack( newTrack ); + //KTINFO(stflog, "Now processing track candidate"); + //ProcessNewTrack( newTrack ); KTDEBUG(stflog, "Emitting track signal"); - fTrackSignal( data ); + fCandidates.insert( data ); + fLineSignal( data ); } else { - KTDEBUG(stflog, "Line did not make it above the cut and was not emitted as track"); + KTDEBUG(stflog, "Line did not make it above the cut and was not emitted as candidate"); } return true; } + /* void KTSequentialTrackFinder::ProcessNewTrack( KTProcessedTrackData& myNewTrack ) { myNewTrack.SetTimeLength( myNewTrack.GetEndTimeInRunC() - myNewTrack.GetStartTimeInRunC() ); @@ -412,15 +655,15 @@ namespace Katydid //myNewTrack.SetSlope( myNewTrack.GetFrequencyWidth() / myNewTrack.GetTimeLength() ); myNewTrack.SetIntercept( myNewTrack.GetStartFrequency() - myNewTrack.GetSlope() * myNewTrack.GetStartTimeInRunC() ); - } + }*/ - void KTSequentialTrackFinder::UpdateLinePoint(Point& point, KTPowerSpectrum& slice) + void KTSequentialTrackFinder::UpdateLinePoint(KTDiscriminatedPoint& point, KTPowerSpectrum& slice) { double Delta = fConvergeDelta + 1.0; unsigned loopCounter = 0; int maxIterations = 10; - double frequency = point.fPointFreq; + double frequency = point.fFrequency; double amplitude = point.fAmplitude; unsigned frequencyBin = point.fBinInSlice; double oldFrequencyBin; @@ -456,6 +699,7 @@ namespace Katydid amplitude += slice(iBin); slice(iBin) = fPointAmplitudeAfterVisit; } + amplitude = amplitude - ( 2 * fLinePowerRadius - 1 ) * point.fMean; //amplitude = amplitude / fLinePowerRadius; } else @@ -473,29 +717,11 @@ namespace Katydid slice(iBin) = fPointAmplitudeAfterVisit; } } - - /* - if (frequencyBin > fMinBin + fMinFreqBinDistance and frequencyBin < fMaxBin - fMinFreqBinDistance) - { - for (int iBin = frequencyBin - fMinFreqBinDistance; iBin <= frequencyBin + fMinFreqBinDistance; ++iBin) - { - slice(iBin)=fPointAmplitudeAfterVisit; - } - } - // if point was to close to edge, try to set smaller range to zero - else if (frequencyBin > fMinBin + fSearchRadius and frequencyBin < fMaxBin - fSearchRadius) - { - for (int iBin = frequencyBin - fSearchRadius; iBin <= frequencyBin + fSearchRadius; ++iBin) - { - slice(iBin) = fPointAmplitudeAfterVisit; - } - }*/ - // Replace values stored in discPoint point.fBinInSlice = frequencyBin; - point.fPointFreq = frequency; - point.fAmplitude = amplitude; - //point.fThreshold *= 2*fLinePowerRadius; //assuming thresholds are flat over small region + point.fFrequency = frequency; + point.fNeighborhoodAmplitude = amplitude; + } inline void KTSequentialTrackFinder::WeightedAverage(const KTPowerSpectrum& slice, unsigned& frequencyBin, double& frequency) @@ -523,14 +749,14 @@ namespace Katydid { KTINFO(stflog, "Got egg-done signal. Checking remaining line candidates"); - std::vector< LineRef >::iterator lineIt = fActiveLines.begin(); + std::vector< KTSequentialLineData >::iterator lineIt = fActiveLines.begin(); while( lineIt != fActiveLines.end()) { - if (lineIt->fNPoints >= fMinPoints) + if (lineIt->GetNPoints() >= fMinPoints) { - lineIt->LineTrimming(fTrimmingFactor, fMinPoints); + lineIt->LineSNRTrimming(fTrimmingThreshold, fMinPoints); - if (lineIt->fNPoints >= fMinPoints and lineIt->fSlope > fMinSlope) + if (lineIt->GetNPoints() >= fMinPoints and lineIt->GetSlope() > fMinSlope) { this->EmitPreCandidate(*lineIt); } @@ -576,103 +802,123 @@ namespace Katydid Line.fSlope = fInitialSlope; } }*/ - void KTSequentialTrackFinder::CalculateUnweightedSlope(LineRef& Line) + void KTSequentialTrackFinder::CalculateUnweightedSlope(KTSequentialLineData& Line) { //KTDEBUG(stflog, "Calculating line slope"); - Line.fNPoints = Line.fLinePoints.size(); - Line.fSumX += Line.fLinePoints.back().fTimeInRunC; - Line.fSumY += Line.fLinePoints.back().fPointFreq; - Line.fSumXY += Line.fLinePoints.back().fTimeInRunC * Line.fLinePoints.back().fPointFreq; - Line.fSumXX += Line.fLinePoints.back().fTimeInRunC * Line.fLinePoints.back().fTimeInRunC; + KTDiscriminatedPoints& points = Line.GetPoints(); + Line.SetSumX( Line.GetSumX() + points.rbegin()->fTimeInRunC) ; + Line.SetSumY( Line.GetSumY() + points.rbegin()->fFrequency); + Line.SetSumXY( Line.GetSumXY() + points.rbegin()->fTimeInRunC * points.rbegin()->fFrequency); + Line.SetSumXX( Line.GetSumXX() + points.rbegin()->fTimeInRunC * points.rbegin()->fTimeInRunC); - if (Line.fNPoints > 1) + if (Line.GetNPoints() > 1) { - Line.fSlope = (Line.fNPoints * Line.fSumXY - Line.fSumX * Line.fSumY)/(Line.fSumXX * Line.fNPoints - Line.fSumX * Line.fSumX); + Line.SetSlope( (Line.GetNPoints() * Line.GetSumXY() - Line.GetSumX() * Line.GetSumY())/(Line.GetSumXX() * Line.GetNPoints() - Line.GetSumX() * Line.GetSumX()) ); } else { - Line.fSlope = fInitialSlope; + Line.SetSlope( fInitialSlope ); } - KTDEBUG( stflog, "Unweighted slope method. New slope "< fNSlopePoints) - { - for(std::vector::iterator pointIt = Line.fLinePoints.end() - fNSlopePoints; pointIt != Line.fLinePoints.end(); ++pointIt) + //KTDEBUG(stflog, "Calculating line slope "< fNSlopePoints) + { + KTDiscriminatedPoints& points = Line.GetPoints(); + KTDiscriminatedPoints::iterator pointIt = points.end(); + std::advance(pointIt, -1); + Line.SetWeightedSlopeSum( Line.GetWeightedSlopeSum() + ( pointIt->fFrequency - Line.GetStartFrequency() ) / ( pointIt->fTimeInRunC - Line.GetStartTimeInRunC() ) * Line.GetSNRList().back() ); + + std::advance(pointIt, -(fNSlopePoints-1)); + Line.SetWeightedSlopeSum( Line.GetWeightedSlopeSum() - (pointIt->fFrequency - Line.GetStartFrequency() ) / ( pointIt->fTimeInRunC - Line.GetStartTimeInRunC() ) * Line.GetSNRList().rbegin()[fNSlopePoints-1] ); + Line.SetTotalWideSNR( Line.GetTotalWideSNR() - Line.GetSNRList().rbegin()[fNSlopePoints-1]); + Line.SetSlope(Line.GetWeightedSlopeSum()/Line.GetTotalWideSNR()); + /*KTDiscriminatedPoints& points = Line.GetPoints(); + KTDiscriminatedPoints::iterator pointIt = points.end(); + std::advance(pointIt, -fNSlopePoints); + while(pointIt != points.end()) { - if (pointIt->fPointFreq != Line.fStartFrequency) + if (pointIt->fFrequency != Line.GetStartFrequency()) { - weightedSlope += (pointIt->fPointFreq - Line.fStartFrequency)/(pointIt->fTimeInAcq - Line.fStartTimeInAcq) * pointIt->fAmplitude; + weightedSlope += (pointIt->fFrequency - Line.GetStartFrequency())/(pointIt->fTimeInAcq - Line.GetStartTimeInAcq()) * pointIt->fAmplitude; wSum += pointIt->fAmplitude; } + ++pointIt; } - Line.fSlope = weightedSlope/wSum; + Line.SetSlope( weightedSlope/wSum );*/ } - else if (Line.fNPoints > 1) + else if (Line.GetNPoints() > 1) { - for(std::vector::iterator pointIt = Line.fLinePoints.begin(); pointIt != Line.fLinePoints.end(); ++pointIt) + KTDiscriminatedPoints& points = Line.GetPoints(); + Line.SetWeightedSlopeSum( Line.GetWeightedSlopeSum() + ( points.rbegin()->fFrequency - Line.GetStartFrequency() ) / ( points.rbegin()->fTimeInRunC - Line.GetStartTimeInRunC() ) * Line.GetSNRList().back() ); + Line.SetSlope(Line.GetWeightedSlopeSum()/Line.GetTotalWideSNR()); + /*for(KTDiscriminatedPoints::iterator pointIt = points.begin(); pointIt != points.end(); ++pointIt) { - if (pointIt->fPointFreq != Line.fStartFrequency) + if (pointIt->fFrequency != Line.GetStartFrequency()) { - weightedSlope += (pointIt->fPointFreq - Line.fStartFrequency)/(pointIt->fTimeInAcq - Line.fStartTimeInAcq) * pointIt->fAmplitude; + weightedSlope += (pointIt->fFrequency - Line.GetStartFrequency())/(pointIt->fTimeInAcq - Line.GetStartTimeInAcq()) * pointIt->fAmplitude; wSum += pointIt->fAmplitude; } } - Line.fSlope = weightedSlope/wSum; + Line.SetSlope( weightedSlope/wSum );*/ } else { - Line.fSlope = fInitialSlope; + Line.SetSlope( fInitialSlope ); } - KTDEBUG(stflog, "Ref point slope method. New slope is " << Line.fSlope); + //KTDEBUG(stflog, "Ref point slope method. New slope is " << Line.GetSlope()); } - void KTSequentialTrackFinder::CalculateSlopeLastRef(LineRef& Line) + void KTSequentialTrackFinder::CalculateSlopeLastRef(KTSequentialLineData& Line) { //KTDEBUG(seqlog, "Calculating line slope"); double weightedSlope = 0.0; - double wSum = 0.0; - Line.fNPoints = Line.fLinePoints.size(); - if (Line.fNPoints > fNSlopePoints) + if (Line.GetNPoints() > fNSlopePoints) { - for(std::vector::iterator pointIt = Line.fLinePoints.end() - fNSlopePoints; pointIt != Line.fLinePoints.end(); ++pointIt) + double wSum = 0.0; + KTDiscriminatedPoints& points = Line.GetPoints(); + KTDiscriminatedPoints::iterator pointIt = points.end(); + std::advance(pointIt, -fNSlopePoints); + + while(pointIt != points.end()) { - if (pointIt->fPointFreq != Line.fEndFrequency) + if (pointIt->fFrequency != Line.GetEndFrequency()) { - weightedSlope += (Line.fEndFrequency - pointIt->fPointFreq)/(Line.fEndTimeInRunC - pointIt->fTimeInRunC) * pointIt->fAmplitude; - wSum += pointIt->fAmplitude; + weightedSlope += (Line.GetEndFrequency() - pointIt->fFrequency)/(Line.GetEndTimeInRunC() - pointIt->fTimeInRunC) * pointIt->fNeighborhoodAmplitude/pointIt->fMean; + wSum += pointIt->fNeighborhoodAmplitude/pointIt->fMean; } + ++pointIt; } - Line.fSlope = weightedSlope/wSum; + Line.SetSlope( weightedSlope/wSum ); } - else if (Line.fNPoints > 1) + else if (Line.GetNPoints() > 1) { - for(std::vector::iterator pointIt = Line.fLinePoints.begin(); pointIt != Line.fLinePoints.end(); ++pointIt) + KTDiscriminatedPoints& points = Line.GetPoints(); + for(KTDiscriminatedPoints::iterator pointIt = points.begin(); pointIt != points.end(); ++pointIt) { - if (pointIt->fPointFreq != Line.fEndFrequency) + if (pointIt->fFrequency != Line.GetEndFrequency()) { - weightedSlope += (Line.fEndFrequency - pointIt->fPointFreq)/(Line.fEndTimeInRunC - pointIt->fTimeInRunC) * pointIt->fAmplitude; - wSum += pointIt->fAmplitude; + weightedSlope += (Line.GetEndFrequency() - pointIt->fFrequency)/(Line.GetEndTimeInRunC() - pointIt->fTimeInRunC) * pointIt->fNeighborhoodAmplitude / pointIt->fMean; + //wSum += pointIt->fNeighborhoodAmplitude; } } - Line.fSlope = weightedSlope/wSum; + Line.SetSlope( weightedSlope/Line.GetTotalWideSNR() ); } else { - Line.fSlope = fInitialSlope; + Line.SetSlope( fInitialSlope ); } - KTDEBUG(stflog, "Ref point slope method. fNSlopePoints: "< #include @@ -30,48 +31,61 @@ namespace Katydid { /*! @class KTSeqTrackFinder - @author E. Christine + @author C. Claessens - @brief Implementation of a slightly modified version of Dan Furse's algorithm + @brief Implementation of Dan Furse's algorithm with some modifications @details Collects points on a linear track - Configuration name: "dans-track-finding-algorithm" + Configuration name: "sequential-track-finder" Available configuration values: - - "snr-threshold-power": discrimination snr for point candidates - "min-frequency": minimum allowed frequency (has to be set) - "max-frequency": max allowed frequency (has to be set) - "min-bin": can be set instead of min frequency - "max-bin": can be set instead of max frequency - - "trimming-factor": before a line is converted to a track its edges get trimmed. If the last or first line point power is less than the trimming-factor times the power threshold of the points frequency bins in the power spectrum slice, these points get cut off the line - - "line-power-radius": the power that is assigned to a line point is the sum of the power_spectrum[point_bin - line_width: point_bin + line_width] + - "trimming-threshold": before a line is converted to a sparse waterfall candidate its edges get trimmed. If the last or first line point snr is less than the trimming-threshold, they get removed + - "line-power-radius": only valid for disc1d-ps slot. the power that is assigned to a line point is the sum of the power_spectrum[point_bin - line_width: point_bin + line_width] - "time-gap-tolerance": maximum gap between points in a line (in seconds) - - "minimum-line-distance": if a point is less than this distance (in bins) away from the last point it will be skipped - - "search-radius": before a point is added to a line, the weighted average of the points frequency neighborhood (+/- search-radius in bins) is taken and the point updated until the frequency converges - - "converge-delta": defines when convergence has been reached (in bins) + - "minimum-line-distance": requires some thought for disc1d-slot!!! For disc1d-ps slot: if a point is less than this distance (in bins) away from the last point it will be skipped + - "search-radius": for disc1d-ps slot: before a point is added to a line, the weighted average of the points frequency neighborhood (+/- search-radius in bins) is taken and the point updated until the frequency converges + - "converge-delta": for disc1d-ps slot: defines when convergence has been reached (in bins) - "frequency-acceptance": maximum allowed frequency distance of point to an extrapolated line (in Hz) - - "slope-method": method to update the line slope after point collection + - "slope-method": method to update the line slope after point collection (see options below) - "initial-frequency-acceptance": if the line that a point is being compared to, only has a single point so far, this is the accepted frequency acceptance. Default isfrequency_acceptance - "initial-slope": if a line has only one point, this is the line's slope - "n-slope-points": maximum number of points to include in the slope calculation - "min-points": a line only gets converted to a track if it has collected more than this many number of points - "min-slope": a line only gets converted to a track if its slope is > than this slope (in Hz/s) - - "apply-power-cut" (bool): if true, a power threshold will be applied to a line before converting it to a processed track - - "apply-point-density-cut" (bool): if true, a number-of-points/time-length threshold will be applied to a line before converting it to a processed track - - "power-threshold": threshold for power cut - - "point-density-threshold": threshold for point density cut in points/millisecond + - "apply-power-cut": default false; if true, the summed-power has to be > total-power-threshold; uses fNeighborhoodAmplitude + - "apply-point-density-cut": default false; if true, the summed-power/time-length has to be > average-power-threshold; uses fNeighborhoodAmplitude + - "apply-total-snr-cut": default false; if true, the summed-snr has to be > total-snr-threshold; uses fNeighborhoodAmplitude + - "apply-average-snr-cut": default false; if true, the summed-snr/time-length has to be > average-snr-threshold; uses fNeighborhoodAmplitude + - "apply-total-residual-cut: default false; if true, the summed-unitless-residual has to be > total-residual-threshold; uses fNeighborhoodAmplitude + - "apply-average-residual-cut: default false; if true, the summed-unitless-residual/time-length has to be > average-residual-threshold; uses fNeighborhoodAmplitude + - "total-power-threshold": threshold for apply-total-power-cut + - "average-power-threshold": threshold for apply-average-power-cut + - "total-snr-threshold": threshold for apply-total-snr-cut + - "average-snr-threshold": threshold for apply-average-snr-cut + - "total-residual-threshold": threshold for apply-total-residual-cut + - "average-residual-threshold": threshold for apply-average-residual + + Slope method: + The slope-method controls which method is used for updating the line slope when a new point is added to the line. + There are 3 available options: + - "weighted-first-point-ref" -- slope is calculated by taking the snr-weighted average of df/dt of every point in reference to the line start + - "weighted-last-point-ref" -- slope is calculated by taking the snr-weighted average of df/dt of every point in reference to the line end. As the reference point changes with every new point, this method re-loops over n-slope-points. + - "unweighted" -- unweighted slope calculation. Does not take power or snr into account. Slots: - - "disc-1d": needs sparse spectrogram for thresholding - - "gv": needs gain variation for thresholding - - "ps-in": power spectrum to collect points from - - "done": connect with egg:done. Processes remaining active lines and emits clustering-done signal + - "disc1d": void (KTDataPtr) -- clusters discriminated points to sequential lines candidates + - "disc1d-ps": void (KTDataPtr) -- clusters discriminated points to sequential line candidates; updates point properties using power spectrum slice + - "done": void () -- connect with egg:done. Processes remaining active lines and emits clustering-done signal Signals: - - "pre-candidate": KTProcessedTrackData + - "seq-lines": void (KTDataPtr) -- KTSparseWaterfallCandidateData - "clustering-done": void () -- Emitted when track clustering is complete */ @@ -87,17 +101,44 @@ namespace Katydid unweighted }; - KTGainVariationData fGVData; + public: + struct KTDiscriminatedPointComparePower + { + bool operator() (const KTDiscriminatedPoint& lhs, const KTDiscriminatedPoint& rhs) const + { + return lhs.fAmplitude< rhs.fAmplitude || (lhs.fAmplitude == rhs.fAmplitude && lhs.fFrequency < rhs.fFrequency); + } + }; + + typedef std::set< KTDiscriminatedPoint, KTDiscriminatedPointComparePower > KTDiscriminatedPowerSortedPoints; + public: KTSequentialTrackFinder(const std::string& name = "seq-clustering"); virtual ~KTSequentialTrackFinder(); bool Configure(const scarab::param_node* node); + bool CollectDiscrimPointsFromSlice(KTSliceHeader& slHeader, KTPowerSpectrumData& spectrum, KTDiscriminatedPoints1DData& discrimPoints); + bool CollectDiscrimPointsFromSlice(KTSliceHeader& slHeader, KTDiscriminatedPoints1DData& discrimPoints); + bool CollectDiscrimPoints(const KTSliceHeader& slHeader, const KTPowerSpectrumData& spectrum, const KTDiscriminatedPoints1DData& discrimPoints); + bool CollectDiscrimPoints(const KTSliceHeader& slHeader, const KTDiscriminatedPoints1DData& discrimPoints); + bool LoopOverHighPowerPoints(KTPowerSpectrum& powerSpectrum, KTDiscriminatedPowerSortedPoints& points, uint64_t acqID, unsigned component); + bool LoopOverHighPowerPoints(KTDiscriminatedPowerSortedPoints& points, uint64_t acqID, unsigned component); + + void UpdateLinePoint(KTDiscriminatedPoint& point, KTPowerSpectrum& slice); + void WeightedAverage(const KTPowerSpectrum& slice, unsigned& frequencyBin, double& frequency); + void (KTSequentialTrackFinder::*fCalcSlope)(KTSequentialLineData& Line); + void CalculateSlopeFirstRef(KTSequentialLineData& Line); + void CalculateSlopeLastRef(KTSequentialLineData& Line); + //void CalculateWeightedSlope(LineRef& Line); + void CalculateUnweightedSlope(KTSequentialLineData& Line); + bool EmitPreCandidate(KTSequentialLineData& line); + void AcquisitionIsOver(); - public: - //MEMBERVARIABLE(ThresholdMode, Mode); + const std::set< Nymph::KTDataPtr >& GetCandidates() const; + + private: // Parameters for point update before adding point to line MEMBERVARIABLE(int, SearchRadius); MEMBERVARIABLE(double, ConvergeDelta); @@ -114,13 +155,22 @@ namespace Katydid MEMBERVARIABLE(double, TimeGapTolerance); // Parameters for line post-processing - MEMBERVARIABLE(double, TrimmingFactor); + //MEMBERVARIABLE(double, TrimmingFactor); + MEMBERVARIABLE(double, TrimmingThreshold); MEMBERVARIABLE(unsigned, MinPoints); MEMBERVARIABLE(double, MinSlope); - MEMBERVARIABLE(bool, ApplyPowerCut); - MEMBERVARIABLE(bool, ApplyDensityCut); - MEMBERVARIABLE(double, PowerThreshold); - MEMBERVARIABLE(double, DensityThreshold); + MEMBERVARIABLE(bool, ApplyTotalPowerCut); + MEMBERVARIABLE(bool, ApplyAveragePowerCut); + MEMBERVARIABLE(bool, ApplyTotalSNRCut); + MEMBERVARIABLE(bool, ApplyAverageSNRCut); + MEMBERVARIABLE(bool, ApplyTotalUnitlessResidualCut); + MEMBERVARIABLE(bool, ApplyAverageUnitlessResidualCut); + MEMBERVARIABLE(double, TotalPowerThreshold); + MEMBERVARIABLE(double, AveragePowerThreshold); + MEMBERVARIABLE(double, TotalSNRThreshold); + MEMBERVARIABLE(double, AverageSNRThreshold); + MEMBERVARIABLE(double, TotalUnitlessResidualThreshold); + MEMBERVARIABLE(double, AverageUnitlessResidualThreshold); // Others MEMBERVARIABLE(unsigned, NLines); @@ -134,27 +184,8 @@ namespace Katydid private: - std::vector< LineRef> fActiveLines; - - public: - //bool SetPreCalcGainVar(KTGainVariationData& gvData); - //bool CollectPointsFromSlice(KTSliceHeader& slHeader, KTPowerSpectrumData& spectrum); - bool CollectDiscrimPointsFromSlice(KTSliceHeader& slHeader, KTPowerSpectrumData& spectrum, KTDiscriminatedPoints1DData& discrimPoints); - //bool CollectPoints(const KTSliceHeader& slHeader, const KTPowerSpectrumData& spectrum, const KTGainVariationData& gvData); - bool CollectDiscrimPoints(const KTSliceHeader& slHeader, const KTPowerSpectrumData& spectrum, const KTDiscriminatedPoints1DData& discrimPoints); - //bool LoopOverHighPowerPoints(std::vector& slice, std::vector& points, unsigned component); - bool LoopOverHighPowerPoints(KTPowerSpectrum& powerSpectrum, std::vector& points, unsigned component); - - void UpdateLinePoint(Point& point, KTPowerSpectrum& slice); - void WeightedAverage(const KTPowerSpectrum& slice, unsigned& frequencyBin, double& frequency); - void (KTSequentialTrackFinder::*fCalcSlope)(LineRef& Line); - void CalculateSlopeFirstRef(LineRef& Line); - void CalculateSlopeLastRef(LineRef& Line); - //void CalculateWeightedSlope(LineRef& Line); - void CalculateUnweightedSlope(LineRef& Line); - void ProcessNewTrack( KTProcessedTrackData& myNewTrack ); - bool EmitPreCandidate(LineRef line); - void AcquisitionIsOver(); + std::vector< KTSequentialLineData > fActiveLines; + std::set< Nymph::KTDataPtr > fCandidates; @@ -163,7 +194,7 @@ namespace Katydid //*************** private: - Nymph::KTSignalData fTrackSignal; + Nymph::KTSignalData fLineSignal; Nymph::KTSignalOneArg< void > fClusterDoneSignal; //*************** @@ -171,13 +202,15 @@ namespace Katydid //*************** private: - //Nymph::KTSlotDataTwoTypes< KTSliceHeader, KTPowerSpectrumData > fSeqTrackSlot; - //Nymph::KTSlotDataOneType< KTGainVariationData > fGainVarSlot; - //Nymph::KTSlotDataTwoTypes< KTSliceHeader, KTPowerSpectrumData > fPSSlot; - Nymph::KTSlotDataThreeTypes < KTSliceHeader, KTPowerSpectrumData, KTDiscriminatedPoints1DData > fDiscrimSlot; + Nymph::KTSlotDataThreeTypes < KTSliceHeader, KTPowerSpectrumData, KTDiscriminatedPoints1DData > fDiscrimPowerSlot; + Nymph::KTSlotDataTwoTypes < KTSliceHeader, KTDiscriminatedPoints1DData > fDiscrimSlot; Nymph::KTSlotDone fDoneSlot; }; + inline const std::set< Nymph::KTDataPtr >& KTSequentialTrackFinder::GetCandidates() const + { + return fCandidates; + } } /* namespace Katydid */ #endif /* KTSEQUENTIALTRACKFinder_HH_ */ diff --git a/Source/SpectrumAnalysis/KTSpectrumDiscriminator.cc b/Source/SpectrumAnalysis/KTSpectrumDiscriminator.cc index 288fa1c5a..9d08c57f2 100644 --- a/Source/SpectrumAnalysis/KTSpectrumDiscriminator.cc +++ b/Source/SpectrumAnalysis/KTSpectrumDiscriminator.cc @@ -44,6 +44,7 @@ namespace Katydid fMaxFrequency(1.), fMinBin(0), fMaxBin(1), + fNeighborhoodRadius(0), fCalculateMinBin(true), fCalculateMaxBin(true), fDiscrim1DSignal("disc-1d", this), @@ -65,7 +66,10 @@ namespace Katydid bool KTSpectrumDiscriminator::Configure(const scarab::param_node* node) { if (node == NULL) return false; - + if (node->has("neighborhood-radius")) + { + SetNeighborhoodRadius(node->get_value< int >("neighborhood-radius")); + } if (node->has("snr-threshold-amplitude")) { SetSNRAmplitudeThreshold(node->get_value< double >("snr-threshold-amplitude")); @@ -208,10 +212,11 @@ namespace Katydid magnitude.resize(spectrum->size()); } - double mean = 0.; + double mean = 0., variance = 0.; if (! pcData.empty()) { mean = pcData[iComponent].fMean; + variance = pcData[iComponent].fVariance; } else { @@ -220,8 +225,10 @@ namespace Katydid { magnitude[iBin] = sqrt((*spectrum)(iBin)[0] * (*spectrum)(iBin)[0] + (*spectrum)(iBin)[1] * (*spectrum)(iBin)[1]); mean += magnitude[iBin]; + variance += magnitude[iBin] * magnitude[iBin]; } mean *= norm; + variance = variance*norm - mean*mean; } double threshold = 0.; @@ -239,32 +246,24 @@ namespace Katydid } else if (fThresholdMode == eSigma) { - double sigma = 0.; - if (! pcData.empty()) - { - sigma = sqrt(pcData[iComponent].fVariance); - } - else - { -#pragma omp parallel for reduction(+:sigma) - for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) - { - sigma += magnitude[iBin] * magnitude[iBin]; - } - sigma = sqrt(sigma*norm - mean*mean); - } - - threshold = mean + fSigmaThreshold * sigma; - KTDEBUG(sdlog, "Discriminator threshold for channel " << iComponent << " set at <" << threshold << "> (Sigma mode; mean = " << mean << "; sigma = " << sigma << ")"); + threshold = mean + fSigmaThreshold * sqrt(variance); + KTDEBUG(sdlog, "Discriminator threshold for channel " << iComponent << " set at <" << threshold << "> (Sigma mode; mean = " << mean << "; variance = " << variance << ")"); } // loop over bins, checking against the threshold - double value; #pragma omp parallel for private(value) for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) { - value = magnitude[iBin]; - if (value >= threshold) newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold), iComponent); + double value = magnitude[iBin]; + //if (value >= threshold) newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold), iComponent); + if (value >= threshold) + { + double neighborhoodAmplitude = 0.; + this->SumAdjacentBinAmplitude(spectrum, neighborhoodAmplitude, iBin); + neighborhoodAmplitude = neighborhoodAmplitude - (2* fNeighborhoodRadius ) * mean; + + newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold, mean, variance, neighborhoodAmplitude), iComponent); + } } KTDEBUG(sdlog, "Component " << iComponent << " has " << newData.GetSetOfPoints(iComponent).size() << " points above threshold"); @@ -306,18 +305,21 @@ namespace Katydid return false; } - double mean = 0.; + double mean = 0., variance = 0.; if (! pcData.empty()) { mean = pcData[iComponent].fMean; + variance = pcData[iComponent].fVariance; } else { for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) { mean += (*spectrum)(iBin).abs(); + variance += (*spectrum)(iBin).abs() * (*spectrum)(iBin).abs(); } mean *= norm; + variance = variance*norm - mean*mean; } double threshold = 0.; @@ -335,34 +337,25 @@ namespace Katydid } else if (fThresholdMode == eSigma) { - double sigma = 0.; - if (! pcData.empty()) - { - sigma = sqrt(pcData[iComponent].fVariance); - } - else - { - for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) - { - sigma += (*spectrum)(iBin).abs() * (*spectrum)(iBin).abs(); - } - sigma = sqrt(sigma*norm - mean*mean); - } - - threshold = mean + fSigmaThreshold * sigma; - KTDEBUG(sdlog, "Discriminator threshold for channel " << iComponent << " set at <" << threshold << "> (Sigma mode; mean = " << mean << "; sigma = " << sigma << ")"); + threshold = mean + fSigmaThreshold * sqrt(variance); + KTDEBUG(sdlog, "Discriminator threshold for channel " << iComponent << " set at <" << threshold << "> (Sigma mode; mean = " << mean << "; variance = " << variance << ")"); } // loop over bins, checking against the threshold - double value; + //std::stringstream printer; for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) { - value = (*spectrum)(iBin).abs(); + double value = (*spectrum)(iBin).abs(); if (value >= threshold) { //printer << " " << iBin << " -- " << value; - newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold), iComponent); + //newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold), iComponent); + double neighborhoodAmplitude = 0.; + this->SumAdjacentBinAmplitude(spectrum, neighborhoodAmplitude, iBin); + neighborhoodAmplitude = neighborhoodAmplitude - (2* fNeighborhoodRadius ) * mean; + + newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold, mean, variance, neighborhoodAmplitude), iComponent); } } @@ -406,10 +399,11 @@ namespace Katydid return false; } - double mean = 0.; + double mean = 0., variance = 0.; if (! pcData.empty()) { mean = pcData[iComponent].fMean; + variance = pcData[iComponent].fVariance; } else { @@ -417,8 +411,10 @@ namespace Katydid for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) { mean += (*spectrum)(iBin); + variance += (*spectrum)(iBin) * (*spectrum)(iBin); } mean *= norm; + variance = variance*norm - mean*mean; } double threshold = 0.; @@ -436,32 +432,24 @@ namespace Katydid } else if (fThresholdMode == eSigma) { - double sigma = 0.; - if (! pcData.empty()) - { - sigma = sqrt(pcData[iComponent].fVariance); - } - else - { -#pragma omp parallel for reduction(+:sigma) - for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) - { - sigma += (*spectrum)(iBin) * (*spectrum)(iBin); - } - sigma = sqrt(sigma*norm - mean*mean); - } - - threshold = mean + fSigmaThreshold * sigma; - KTDEBUG(sdlog, "Discriminator threshold for channel " << iComponent << " set at <" << threshold << "> (Sigma mode; mean = " << mean << "; sigma = " << sigma << ")"); + threshold = mean + fSigmaThreshold * sqrt(variance); + KTDEBUG(sdlog, "Discriminator threshold for channel " << iComponent << " set at <" << threshold << "> (Sigma mode; mean = " << mean << "; variance = " << variance << ")"); } // loop over bins, checking against the threshold - double value; + #pragma omp parallel for private(value) for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) { - value = (*spectrum)(iBin); - if (value >= threshold) newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold), iComponent); + double value = (*spectrum)(iBin); + if (value >= threshold) + { + double neighborhoodAmplitude = 0.; + this->SumAdjacentBinAmplitude(spectrum, neighborhoodAmplitude, iBin); + neighborhoodAmplitude = neighborhoodAmplitude - (2* fNeighborhoodRadius ) * mean; + + newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold, mean, variance, neighborhoodAmplitude), iComponent); + } } KTDEBUG(sdlog, "Component " << iComponent << " has " << newData.GetSetOfPoints(iComponent).size() << " points above threshold"); @@ -471,6 +459,30 @@ namespace Katydid return true; } + void KTSpectrumDiscriminator::SumAdjacentBinAmplitude(const KTPowerSpectrum* spectrum, double& neighborhoodAmplitude, const unsigned& iBin) + { + neighborhoodAmplitude = 0; + for (unsigned jBin = iBin-fNeighborhoodRadius; jBin<= iBin+fNeighborhoodRadius; ++jBin) + { + neighborhoodAmplitude += (*spectrum)(jBin); + } + } + void KTSpectrumDiscriminator::SumAdjacentBinAmplitude(const KTFrequencySpectrumFFTW* spectrum, double& neighborhoodAmplitude, const unsigned& iBin) + { + neighborhoodAmplitude = 0; + for (unsigned jBin = iBin-fNeighborhoodRadius; jBin<= iBin+fNeighborhoodRadius; ++jBin) + { + neighborhoodAmplitude += sqrt((*spectrum)(jBin)[0] * (*spectrum)(jBin)[0] + (*spectrum)(jBin)[1] * (*spectrum)(jBin)[1]); + } + } + void KTSpectrumDiscriminator::SumAdjacentBinAmplitude(const KTFrequencySpectrumPolar* spectrum, double& neighborhoodAmplitude, const unsigned& iBin) + { + neighborhoodAmplitude = 0; + for (unsigned jBin = iBin-fNeighborhoodRadius; jBin<= iBin+fNeighborhoodRadius; ++jBin) + { + neighborhoodAmplitude += (*spectrum)(jBin).abs(); + } + } } /* namespace Katydid */ diff --git a/Source/SpectrumAnalysis/KTSpectrumDiscriminator.hh b/Source/SpectrumAnalysis/KTSpectrumDiscriminator.hh index 2219f761a..c84faa849 100644 --- a/Source/SpectrumAnalysis/KTSpectrumDiscriminator.hh +++ b/Source/SpectrumAnalysis/KTSpectrumDiscriminator.hh @@ -19,13 +19,16 @@ namespace Katydid class KTCorrelationData; class KTDiscriminatedPoints1DData; + class KTFrequencySpectrumFFTW; class KTFrequencySpectrumDataFFTW; class KTFrequencySpectrumDataFFTWCore; + class KTFrequencySpectrumPolar; class KTFrequencySpectrumDataPolar; class KTFrequencySpectrumDataPolarCore; class KTNormalizedFSDataFFTW; class KTNormalizedFSDataPolar; class KTNormalizedPSData; + class KTPowerSpectrum; class KTPowerSpectrumData; class KTPowerSpectrumDataCore; class KTWignerVilleData; @@ -82,37 +85,27 @@ namespace Katydid bool Configure(const scarab::param_node* node); - double GetSNRThreshold() const; void SetSNRAmplitudeThreshold(double thresh); void SetSNRPowerThreshold(double thresh); - - double GetSigmaThreshold() const; void SetSigmaThreshold(double thresh); - - double GetMinFrequency() const; void SetMinFrequency(double freq); - - double GetMaxFrequency() const; void SetMaxFrequency(double freq); - - unsigned GetMinBin() const; void SetMinBin(unsigned bin); - - unsigned GetMaxBin() const; void SetMaxBin(unsigned bin); private: - double fSNRThreshold; - double fSigmaThreshold; - ThresholdMode fThresholdMode; + MEMBERVARIABLE_NOSET(double, SNRThreshold); + MEMBERVARIABLE_NOSET(double, SigmaThreshold); + MEMBERVARIABLE_NOSET(ThresholdMode, ThresholdMode); - double fMinFrequency; - double fMaxFrequency; - unsigned fMinBin; - unsigned fMaxBin; - bool fCalculateMinBin; - bool fCalculateMaxBin; + MEMBERVARIABLE_NOSET(double, MinFrequency); + MEMBERVARIABLE_NOSET(double, MaxFrequency); + MEMBERVARIABLE_NOSET(unsigned, MinBin); + MEMBERVARIABLE_NOSET(unsigned, MaxBin); + MEMBERVARIABLE(int, NeighborhoodRadius); + MEMBERVARIABLE_NOSET(bool, CalculateMinBin); + MEMBERVARIABLE_NOSET(bool, CalculateMaxBin); public: bool Discriminate(KTFrequencySpectrumDataPolar& data); @@ -135,6 +128,9 @@ namespace Katydid bool CoreDiscriminate(KTFrequencySpectrumDataFFTWCore& data, KTDiscriminatedPoints1DData& newData, std::vector< PerComponentInfo > pcData); bool CoreDiscriminate(KTPowerSpectrumDataCore& data, KTDiscriminatedPoints1DData& newData, std::vector< PerComponentInfo > pcData); + void SumAdjacentBinAmplitude(const KTPowerSpectrum* spectrum, double& neighborhoodAmplitude, const unsigned& iBin); + void SumAdjacentBinAmplitude(const KTFrequencySpectrumFFTW* spectrum, double& neighborhoodAmplitude, const unsigned& iBin); + void SumAdjacentBinAmplitude(const KTFrequencySpectrumPolar* spectrum, double& neighborhoodAmplitude, const unsigned& iBin); //*************** // Signals @@ -159,10 +155,6 @@ namespace Katydid }; - inline double KTSpectrumDiscriminator::GetSNRThreshold() const - { - return fSNRThreshold; - } inline void KTSpectrumDiscriminator::SetSNRAmplitudeThreshold(double thresh) { @@ -178,11 +170,6 @@ namespace Katydid return; } - inline double KTSpectrumDiscriminator::GetSigmaThreshold() const - { - return fSigmaThreshold; - } - inline void KTSpectrumDiscriminator::SetSigmaThreshold(double thresh) { fSigmaThreshold = thresh; @@ -190,11 +177,6 @@ namespace Katydid return; } - inline double KTSpectrumDiscriminator::GetMinFrequency() const - { - return fMinFrequency; - } - inline void KTSpectrumDiscriminator::SetMinFrequency(double freq) { fMinFrequency = freq; @@ -202,11 +184,6 @@ namespace Katydid return; } - inline double KTSpectrumDiscriminator::GetMaxFrequency() const - { - return fMaxFrequency; - } - inline void KTSpectrumDiscriminator::SetMaxFrequency(double freq) { fMaxFrequency = freq; @@ -214,11 +191,6 @@ namespace Katydid return; } - inline unsigned KTSpectrumDiscriminator::GetMinBin() const - { - return fMinBin; - } - inline void KTSpectrumDiscriminator::SetMinBin(unsigned bin) { fMinBin = bin; @@ -226,11 +198,6 @@ namespace Katydid return; } - inline unsigned KTSpectrumDiscriminator::GetMaxBin() const - { - return fMaxBin; - } - inline void KTSpectrumDiscriminator::SetMaxBin(unsigned bin) { fMaxBin = bin; diff --git a/Source/SpectrumAnalysis/KTVariableSpectrumDiscriminator.cc b/Source/SpectrumAnalysis/KTVariableSpectrumDiscriminator.cc index e8b7f8e52..b8a119135 100644 --- a/Source/SpectrumAnalysis/KTVariableSpectrumDiscriminator.cc +++ b/Source/SpectrumAnalysis/KTVariableSpectrumDiscriminator.cc @@ -49,6 +49,7 @@ namespace Katydid fMaxFrequency(1.), fMinBin(0), fMaxBin(1), + fNeighborhoodRadius(0), fCalculateMinBin(true), fCalculateMaxBin(true), fNormalize(false), @@ -80,7 +81,14 @@ namespace Katydid if (node == NULL) return false; // The if(has) pattern is used here so that Set[whatever] is only called if the particular parameter is present. - // These Set[whatever] functions also change the threshold mode, so we only want to call them if we are setting the value, and not just keeping the existing value. + + if (node->has("neighborhood-Radius")) + { + SetNeighborhoodRadius(node->get_value< int >("neighborhood-radius")); + } + + // These Set[whatever] functions also change the threshold mode, + // so we only want to call them if we are setting the value, and not just keeping the existing value. if (node->has("snr-threshold-amplitude")) { SetSNRAmplitudeThreshold(node->get_value< double >("snr-threshold-amplitude")); @@ -94,8 +102,8 @@ namespace Katydid SetSigmaThreshold(node->get_value< double >("sigma-threshold")); } - // The if(has) pattern is used here so that Set[whatever] is only called if the particular parameter is present. - // These Set[whatever] functions also set the flags to calculate the min/max bin, so we only want to call them if we are setting the value, and not just keeping the existing value. + // These Set[whatever] functions also set the flags to calculate the min/max bin, + // so we only want to call them if we are setting the value, and not just keeping the existing value. if (node->has("min-frequency")) { SetMinFrequency(node->get_value< double >("min-frequency")); @@ -105,8 +113,8 @@ namespace Katydid SetMaxFrequency(node->get_value< double >("max-frequency")); } - // The if(has) pattern is used here so that Set[whatever] is only called if the particular parameter is present. - // These Set[whatever] functions also set the flags to calculate the min/max bin, so we only want to call them if we are setting the value, and not just keeping the existing value. + // These Set[whatever] functions also set the flags to calculate the min/max bin, + // so we only want to call them if we are setting the value, and not just keeping the existing value. if (node->has("min-bin")) { SetMinBin(node->get_value< unsigned >("min-bin")); @@ -275,7 +283,7 @@ namespace Katydid // Iterate through the 1D points and add them to the 2D points for( KTDiscriminatedPoints1DData::SetOfPoints::const_iterator it = newDataSlice.GetSetOfPoints( sliceNumber ).begin(); it != newDataSlice.GetSetOfPoints( sliceNumber ).end(); ++it ) { - newData.AddPoint( sliceNumber, it->first, KTDiscriminatedPoints2DData::Point( XbinWidth * ((double)sliceNumber+0.5) + Xmin, YbinWidth * ((double)it->first+0.5) + Ymin, it->second.fOrdinate, it->second.fThreshold ), 0 ); + newData.AddPoint( sliceNumber, it->first, KTDiscriminatedPoints2DData::Point( XbinWidth * ((double)sliceNumber+0.5) + Xmin, YbinWidth * ((double)it->first+0.5) + Ymin, it->second.fOrdinate, it->second.fThreshold, it->second.fMean, it->second.fVariance, it->second.fNeighborhoodAmplitude ), 0 ); } sliceNumber++; @@ -421,21 +429,31 @@ namespace Katydid } // loop over bins, checking against the threshold - double mean = 0., variance = 0., threshold = 0., value = 0.; #pragma omp parallel for private(value) for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) { - value = (*spectrum)(iBin).abs(); - threshold = thresholdMult * (*splineImp)(iBin - fMinBin); + double value = (*spectrum)(iBin).abs(); + double threshold = thresholdMult * (*splineImp)(iBin - fMinBin); + double mean = (*splineImp)(iBin - fMinBin); + double variance = (*varSplineImp)(iBin - fMinBin); if (value >= threshold) { + double neighborhoodAmplitude = 0.; + this->SumAdjacentBinAmplitude(spectrum, neighborhoodAmplitude, iBin); + if( fNormalize ) { - mean = (*splineImp)(iBin - fMinBin); - variance = (*varSplineImp)(iBin - fMinBin); value = normalizedValue + (value - mean) * sqrt( normalizedVariance / variance ); + neighborhoodAmplitude = normalizedValue + ( neighborhoodAmplitude - ( 2 * fNeighborhoodRadius+1 ) * mean ) * sqrt( normalizedVariance / variance ); + mean = normalizedValue; + variance = normalizedVariance; } - newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold), component); + else + { + neighborhoodAmplitude = neighborhoodAmplitude - ( 2 * fNeighborhoodRadius ) * mean; + } + + newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold, mean, variance, neighborhoodAmplitude), component); } } } @@ -444,22 +462,31 @@ namespace Katydid //************** else if (fThresholdMode == eSigma) { - double mean = 0., variance = 0., threshold = 0., value = 0.; #pragma omp parallel for private(value) for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) { - mean = (*splineImp)(iBin - fMinBin); - variance = (*varSplineImp)(iBin - fMinBin); - threshold = mean + fSigmaThreshold * sqrt( variance ); - value = (*spectrum)(iBin).abs(); + double mean = (*splineImp)(iBin - fMinBin); + double variance = (*varSplineImp)(iBin - fMinBin); + double threshold = mean + fSigmaThreshold * sqrt( variance ); + double value = (*spectrum)(iBin).abs(); if (value >= threshold) { + double neighborhoodAmplitude = 0.; + this->SumAdjacentBinAmplitude(spectrum, neighborhoodAmplitude, iBin); if( fNormalize ) { value = normalizedValue + (value - mean) * sqrt( normalizedVariance / variance ); + neighborhoodAmplitude = normalizedValue + ( neighborhoodAmplitude - ( 2 * fNeighborhoodRadius+1 ) * mean ) * sqrt( normalizedVariance / variance ); + mean = normalizedValue; + variance = normalizedVariance; } - newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold), component); + else + { + neighborhoodAmplitude = neighborhoodAmplitude - ( 2 * fNeighborhoodRadius ) * mean; + } + + newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold, mean, variance, neighborhoodAmplitude), component); } } } @@ -506,21 +533,31 @@ namespace Katydid } // loop over bins, checking against the threshold - double mean = 0., variance = 0., threshold = 0., value = 0.; #pragma omp parallel for private(value) for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) { - value = sqrt((*spectrum)(iBin)[0] * (*spectrum)(iBin)[0] + (*spectrum)(iBin)[1] * (*spectrum)(iBin)[1]); - threshold = thresholdMult * (*splineImp)(iBin - fMinBin); + double value = sqrt((*spectrum)(iBin)[0] * (*spectrum)(iBin)[0] + (*spectrum)(iBin)[1] * (*spectrum)(iBin)[1]); + double threshold = thresholdMult * (*splineImp)(iBin - fMinBin); + double mean = (*splineImp)(iBin - fMinBin); + double variance = (*varSplineImp)(iBin - fMinBin); + if (value >= threshold) { + double neighborhoodAmplitude = 0.; + this->SumAdjacentBinAmplitude(spectrum, neighborhoodAmplitude, iBin); if( fNormalize ) { - mean = (*splineImp)(iBin - fMinBin); - variance = (*varSplineImp)(iBin - fMinBin); value = normalizedValue + (value - mean) * sqrt( normalizedVariance / variance ); + neighborhoodAmplitude = normalizedValue + ( neighborhoodAmplitude - ( 2 * fNeighborhoodRadius+1 ) * mean ) * sqrt( normalizedVariance / variance ); + mean = normalizedValue; + variance = normalizedVariance; + } + else + { + neighborhoodAmplitude = neighborhoodAmplitude - ( 2 * fNeighborhoodRadius ) * mean; } - newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold), component); + + newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold, mean, variance, neighborhoodAmplitude), component); } } } @@ -529,21 +566,30 @@ namespace Katydid //************** else if (fThresholdMode == eSigma) { - double mean = 0., variance = 0., threshold = 0., value = 0.; #pragma omp parallel for private(value) for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) { - mean = (*splineImp)(iBin - fMinBin); - variance = (*varSplineImp)(iBin - fMinBin); - threshold = mean + fSigmaThreshold * sqrt( variance ); - value = sqrt((*spectrum)(iBin)[0] * (*spectrum)(iBin)[0] + (*spectrum)(iBin)[1] * (*spectrum)(iBin)[1]); + double mean = (*splineImp)(iBin - fMinBin); + double variance = (*varSplineImp)(iBin - fMinBin); + double threshold = mean + fSigmaThreshold * sqrt( variance ); + double value = sqrt((*spectrum)(iBin)[0] * (*spectrum)(iBin)[0] + (*spectrum)(iBin)[1] * (*spectrum)(iBin)[1]); if (value >= threshold) { + double neighborhoodAmplitude = 0.; + this->SumAdjacentBinAmplitude(spectrum, neighborhoodAmplitude, iBin); if( fNormalize ) { value = normalizedValue + (value - mean) * sqrt( normalizedVariance / variance ); + neighborhoodAmplitude = normalizedValue + ( neighborhoodAmplitude - ( 2 * fNeighborhoodRadius+1 ) * mean ) * sqrt( normalizedVariance / variance ); + mean = normalizedValue; + variance = normalizedVariance; } - newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold), component); + else + { + neighborhoodAmplitude = neighborhoodAmplitude - ( 2 * fNeighborhoodRadius ) * mean; + } + + newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold, mean, variance, neighborhoodAmplitude), component); } } } @@ -590,21 +636,30 @@ namespace Katydid } // loop over bins, checking against the threshold - double mean = 0., variance = 0., threshold = 0., value = 0.; #pragma omp parallel for private(value) for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) { - value = (*spectrum)(iBin); - threshold = thresholdMult * (*splineImp)(iBin - fMinBin); + double value = (*spectrum)(iBin); + double mean = (*splineImp)(iBin - fMinBin); + double threshold = thresholdMult * mean; + double variance = (*varSplineImp)(iBin - fMinBin); if (value >= threshold) { + double neighborhoodAmplitude = 0.; + this->SumAdjacentBinAmplitude(spectrum, neighborhoodAmplitude, iBin); if( fNormalize ) { - mean = (*splineImp)(iBin - fMinBin); - variance = (*varSplineImp)(iBin - fMinBin); value = normalizedValue + (value - mean) * sqrt( normalizedVariance / variance ); + neighborhoodAmplitude = normalizedValue + ( neighborhoodAmplitude - ( 2 * fNeighborhoodRadius+1 ) * mean ) * sqrt( normalizedVariance / variance ); + mean = normalizedValue; + variance = normalizedVariance; } - newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold), component); + else + { + neighborhoodAmplitude = neighborhoodAmplitude - ( 2 * fNeighborhoodRadius ) * mean; + } + + newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold, mean, variance, neighborhoodAmplitude), component); } } } @@ -614,21 +669,30 @@ namespace Katydid //************** else if (fThresholdMode == eSigma) { - double mean = 0., variance = 0., threshold = 0., value = 0.; #pragma omp parallel for private(value) for (unsigned iBin=fMinBin; iBin<=fMaxBin; ++iBin) { - mean = (*splineImp)(iBin - fMinBin); - variance = (*varSplineImp)(iBin - fMinBin); - threshold = mean + fSigmaThreshold * sqrt( variance ); - value = (*spectrum)(iBin); + double mean = (*splineImp)(iBin - fMinBin); + double variance = (*varSplineImp)(iBin - fMinBin); + double threshold = mean + fSigmaThreshold * sqrt( variance ); + double value = (*spectrum)(iBin); if (value >= threshold) { + double neighborhoodAmplitude = 0.; + this->SumAdjacentBinAmplitude(spectrum, neighborhoodAmplitude, iBin); if( fNormalize ) { value = normalizedValue + (value - mean) * sqrt( normalizedVariance / variance ); + neighborhoodAmplitude = normalizedValue + ( neighborhoodAmplitude - ( 2 * fNeighborhoodRadius+1 ) * mean ) * sqrt( normalizedVariance / variance ); + mean = normalizedValue; + variance = normalizedVariance; + } + else + { + neighborhoodAmplitude = neighborhoodAmplitude - ( 2 * fNeighborhoodRadius ) * mean; } - newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold), component); + + newData.AddPoint(iBin, KTDiscriminatedPoints1DData::Point(binWidth * ((double)iBin + 0.5), value, threshold, mean, variance, neighborhoodAmplitude), component); } } } @@ -637,4 +701,30 @@ namespace Katydid } + void KTVariableSpectrumDiscriminator::SumAdjacentBinAmplitude(const KTPowerSpectrum* spectrum, double& neighborhoodAmplitude, const unsigned& iBin) + { + neighborhoodAmplitude = 0; + for (unsigned jBin = iBin-fNeighborhoodRadius; jBin <= iBin+fNeighborhoodRadius; ++jBin) + { + neighborhoodAmplitude += (*spectrum)(jBin); + } + } + void KTVariableSpectrumDiscriminator::SumAdjacentBinAmplitude(const KTFrequencySpectrumFFTW* spectrum, double& neighborhoodAmplitude, const unsigned& iBin) + { + neighborhoodAmplitude = 0; + for (unsigned jBin = iBin-fNeighborhoodRadius; jBin <= iBin+fNeighborhoodRadius; ++jBin) + { + neighborhoodAmplitude += sqrt((*spectrum)(jBin)[0] * (*spectrum)(jBin)[0] + (*spectrum)(jBin)[1] * (*spectrum)(jBin)[1]); + } + } + void KTVariableSpectrumDiscriminator::SumAdjacentBinAmplitude(const KTFrequencySpectrumPolar* spectrum, double& neighborhoodAmplitude, const unsigned& iBin) + { + neighborhoodAmplitude = 0; + for (unsigned jBin = iBin-fNeighborhoodRadius; jBin <= iBin+fNeighborhoodRadius; ++jBin) + { + neighborhoodAmplitude += (*spectrum)(jBin).abs(); + } + } + + } /* namespace Katydid */ diff --git a/Source/SpectrumAnalysis/KTVariableSpectrumDiscriminator.hh b/Source/SpectrumAnalysis/KTVariableSpectrumDiscriminator.hh index a9f36c6a4..f3346bf2d 100644 --- a/Source/SpectrumAnalysis/KTVariableSpectrumDiscriminator.hh +++ b/Source/SpectrumAnalysis/KTVariableSpectrumDiscriminator.hh @@ -110,41 +110,30 @@ namespace Katydid bool Configure(const scarab::param_node* node); - double GetSNRThreshold() const; void SetSNRAmplitudeThreshold(double thresh); void SetSNRPowerThreshold(double thresh); - - double GetSigmaThreshold() const; void SetSigmaThreshold(double thresh); - - double GetMinFrequency() const; void SetMinFrequency(double freq); - - double GetMaxFrequency() const; void SetMaxFrequency(double freq); - - unsigned GetMinBin() const; void SetMinBin(unsigned bin); - - unsigned GetMaxBin() const; void SetMaxBin(unsigned bin); - bool GetNormalize() const; - void SetNormalize(bool normalize); private: - double fSNRThreshold; - double fSigmaThreshold; - ThresholdMode fThresholdMode; + MEMBERVARIABLE_NOSET(double, SNRThreshold); + MEMBERVARIABLE_NOSET(double, SigmaThreshold); + MEMBERVARIABLE_NOSET(ThresholdMode, ThresholdMode); + + MEMBERVARIABLE_NOSET(double, MinFrequency); + MEMBERVARIABLE_NOSET(double, MaxFrequency); + MEMBERVARIABLE_NOSET(unsigned, MinBin); + MEMBERVARIABLE_NOSET(unsigned, MaxBin); + MEMBERVARIABLE_NOSET(bool, CalculateMinBin); + MEMBERVARIABLE_NOSET(bool, CalculateMaxBin); - double fMinFrequency; - double fMaxFrequency; - unsigned fMinBin; - unsigned fMaxBin; - bool fCalculateMinBin; - bool fCalculateMaxBin; - bool fNormalize; + MEMBERVARIABLE(bool, Normalize); + MEMBERVARIABLE(int, NeighborhoodRadius); public: bool CheckGVData(); @@ -173,6 +162,11 @@ namespace Katydid bool CoreDiscriminate(KTFrequencySpectrumDataFFTWCore& data, KTGainVariationData& gvData, KTDiscriminatedPoints1DData& newData); bool CoreDiscriminate(KTPowerSpectrumDataCore& data, KTGainVariationData& gvData, KTDiscriminatedPoints1DData& newData); + void SumAdjacentBinAmplitude(const KTPowerSpectrum* spectrum, double& neighborhoodAmplitude, const unsigned& iBin); + void SumAdjacentBinAmplitude(const KTFrequencySpectrumFFTW* spectrum, double& neighborhoodAmplitude, const unsigned& iBin); + void SumAdjacentBinAmplitude(const KTFrequencySpectrumPolar* spectrum, double& neighborhoodAmplitude, const unsigned& iBin); + + KTGainVariationData fGVData; std::vector< double > fMagnitudeCache; @@ -208,10 +202,6 @@ namespace Katydid }; - inline double KTVariableSpectrumDiscriminator::GetSNRThreshold() const - { - return fSNRThreshold; - } inline void KTVariableSpectrumDiscriminator::SetSNRAmplitudeThreshold(double thresh) { @@ -227,11 +217,6 @@ namespace Katydid return; } - inline double KTVariableSpectrumDiscriminator::GetSigmaThreshold() const - { - return fSigmaThreshold; - } - inline void KTVariableSpectrumDiscriminator::SetSigmaThreshold(double thresh) { fSigmaThreshold = thresh; @@ -239,11 +224,6 @@ namespace Katydid return; } - inline double KTVariableSpectrumDiscriminator::GetMinFrequency() const - { - return fMinFrequency; - } - inline void KTVariableSpectrumDiscriminator::SetMinFrequency(double freq) { fMinFrequency = freq; @@ -251,11 +231,6 @@ namespace Katydid return; } - inline double KTVariableSpectrumDiscriminator::GetMaxFrequency() const - { - return fMaxFrequency; - } - inline void KTVariableSpectrumDiscriminator::SetMaxFrequency(double freq) { fMaxFrequency = freq; @@ -263,11 +238,6 @@ namespace Katydid return; } - inline unsigned KTVariableSpectrumDiscriminator::GetMinBin() const - { - return fMinBin; - } - inline void KTVariableSpectrumDiscriminator::SetMinBin(unsigned bin) { fMinBin = bin; @@ -275,11 +245,6 @@ namespace Katydid return; } - inline unsigned KTVariableSpectrumDiscriminator::GetMaxBin() const - { - return fMaxBin; - } - inline void KTVariableSpectrumDiscriminator::SetMaxBin(unsigned bin) { fMaxBin = bin; @@ -287,16 +252,6 @@ namespace Katydid return; } - inline bool KTVariableSpectrumDiscriminator::GetNormalize() const - { - return fNormalize; - } - - inline void KTVariableSpectrumDiscriminator::SetNormalize(bool normalize) - { - fNormalize = normalize; - return; - } } /* namespace Katydid */ #endif /* KTVARIABLESPECTRUMDISCRIMINATOR_HH_ */