From 98edd33d68c2e0edab723e4877cd37b04e0a7fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Offringa?= <offringa@astron.nl> Date: Mon, 17 Jan 2011 16:48:54 +0000 Subject: [PATCH] Bug 1491: directional filtering --- .../include/AOFlagger/gui/mswindow.h | 7 ++- .../AOFlagger/gui/timefrequencywidget.h | 1 + .../AOFlagger/msio/timefrequencymetadata.h | 16 ++++++ .../AOFlagger/rfi/strategy/cutareaaction.h | 30 ++++++++++ .../rfi/strategy/fouriertransformaction.h | 11 +++- .../include/AOFlagger/rfi/uvprojection.h | 11 +--- .../include/AOFlagger/util/ffttools.h | 1 + .../src/gui/complexplaneplotwindow.cpp | 6 -- CEP/DP3/AOFlagger/src/gui/mswindow.cpp | 5 ++ CEP/DP3/AOFlagger/src/util/ffttools.cpp | 56 +++++++++++++++++++ 10 files changed, 127 insertions(+), 17 deletions(-) diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/gui/mswindow.h b/CEP/DP3/AOFlagger/include/AOFlagger/gui/mswindow.h index 598b4922604..5a317bbb21a 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/gui/mswindow.h +++ b/CEP/DP3/AOFlagger/include/AOFlagger/gui/mswindow.h @@ -115,6 +115,11 @@ class MSWindow : public Gtk::Window { void onToggleFlags(); void onToggleMap(); void onToggleImage(); + void onWinsorizedColorsPressed() + { + _timeFrequencyWidget.SetWindorizedColors(_winsorizedColorsButton->get_active()); + _timeFrequencyWidget.Update(); + } void onCompress(); void onQuit() { hide(); } void onActionFileOpen(); @@ -206,7 +211,7 @@ class MSWindow : public Gtk::Window { Glib::RefPtr<Gtk::ToggleAction> _originalFlagsButton, _altFlagsButton, _originalImageButton, _backgroundImageButton, _diffImageButton, - _timeGraphButton; + _winsorizedColorsButton, _timeGraphButton; Glib::RefPtr<Gtk::RadioAction> _mapLogButton, _mapBWButton, _mapColorButton, _gaussianTestSetsButton, _rayleighTestSetsButton; diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/gui/timefrequencywidget.h b/CEP/DP3/AOFlagger/include/AOFlagger/gui/timefrequencywidget.h index a5ab6886664..e53baabc98e 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/gui/timefrequencywidget.h +++ b/CEP/DP3/AOFlagger/include/AOFlagger/gui/timefrequencywidget.h @@ -43,6 +43,7 @@ class TimeFrequencyWidget : public Gtk::DrawingArea { void SetShowOriginalFlagging(bool newValue) { _showOriginalFlagging = newValue; } void SetShowAlternativeFlagging(bool newValue) { _showAlternativeFlagging = newValue; } void SetColorMap(TFMap colorMap) { _colorMap = colorMap; } + void SetWindorizedColors(bool value) { _winsorizedStretch = value; } void Update(); void AddAlternativeFlagging(Mask2DCPtr mask); Image2DCPtr Image() { return _image; } diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/msio/timefrequencymetadata.h b/CEP/DP3/AOFlagger/include/AOFlagger/msio/timefrequencymetadata.h index f3644835d07..9ce213ac20d 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/msio/timefrequencymetadata.h +++ b/CEP/DP3/AOFlagger/include/AOFlagger/msio/timefrequencymetadata.h @@ -45,6 +45,22 @@ class TimeFrequencyMetaData _uvw(0) { } + TimeFrequencyMetaData(const TimeFrequencyMetaData &source) + : _antenna1(0), _antenna2(0), _band(0), _field(0), _observationTimes(0), _uvw(0) + { + if(source._antenna1 != 0) + _antenna1 = new AntennaInfo(*source._antenna1); + if(source._antenna2 != 0) + _antenna2 = new AntennaInfo(*source._antenna2); + if(source._band != 0) + _band = new BandInfo(*source._band); + if(source._field != 0) + _field = new FieldInfo(*source._field); + if(source._observationTimes != 0) + _observationTimes = new std::vector<double>(*source._observationTimes); + if(source._uvw != 0) + _uvw = new std::vector<class UVW>(*source._uvw); + } ~TimeFrequencyMetaData() { ClearAntenna1(); diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/rfi/strategy/cutareaaction.h b/CEP/DP3/AOFlagger/include/AOFlagger/rfi/strategy/cutareaaction.h index c5893321373..84874e31084 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/rfi/strategy/cutareaaction.h +++ b/CEP/DP3/AOFlagger/include/AOFlagger/rfi/strategy/cutareaaction.h @@ -21,6 +21,7 @@ #define CUTAREAACTION_H #include <AOFlagger/msio/timefrequencydata.h> +#include <AOFlagger/msio/timefrequencymetadata.h> #include "actionblock.h" #include "artifactset.h" @@ -60,11 +61,14 @@ namespace rfiStrategy { TimeFrequencyData oldOriginal(artifacts.OriginalData()); TimeFrequencyData oldRevised(artifacts.RevisedData()); TimeFrequencyData oldContaminated(artifacts.ContaminatedData()); + TimeFrequencyMetaDataCPtr oldMetaData = artifacts.MetaData(); Cut(artifacts.OriginalData()); Cut(artifacts.RevisedData()); Cut(artifacts.ContaminatedData()); + artifacts.SetMetaData(Cut(oldMetaData)); + ActionBlock::Perform(artifacts, progress); PlaceBack(artifacts.OriginalData(), oldOriginal); @@ -74,6 +78,7 @@ namespace rfiStrategy { artifacts.SetOriginalData(oldOriginal); artifacts.SetRevisedData(oldRevised); artifacts.SetContaminatedData(oldContaminated); + artifacts.SetMetaData(oldMetaData); } virtual ActionType Type() const { return CutAreaActionType; } @@ -84,6 +89,31 @@ namespace rfiStrategy { size_t endChannel = data.ImageHeight() - _bottomChannels; data.Trim(_startTimeSteps, _topChannels, endTime, endChannel); } + TimeFrequencyMetaDataPtr Cut(TimeFrequencyMetaDataCPtr &metaData) + { + TimeFrequencyMetaData *newMetaData = new TimeFrequencyMetaData(*metaData); + if(newMetaData->HasUVW()) + { + std::vector<UVW> newUVW; + newUVW.insert(newUVW.begin(), newMetaData->UVW().begin()+_startTimeSteps, newMetaData->UVW().end()-(_startTimeSteps+_endTimeSteps)); + newMetaData->SetUVW(newUVW); + } + if(newMetaData->HasObservationTimes()) + { + std::vector<double> times; + times.insert(times.begin(), newMetaData->ObservationTimes().begin() +_startTimeSteps, newMetaData->ObservationTimes().end()-(_startTimeSteps+_endTimeSteps)); + newMetaData->SetObservationTimes(times); + } + return TimeFrequencyMetaDataPtr(newMetaData); + if(newMetaData->HasBand()) + { + BandInfo band(newMetaData->Band()); + band.channelCount -= _topChannels - _bottomChannels; + band.channels.erase(band.channels.end() - (_topChannels+_bottomChannels), band.channels.end()); + band.channels.erase(band.channels.begin(), band.channels.begin() + _topChannels); + newMetaData->SetBand(band); + } + } void PlaceBack(class TimeFrequencyData &cuttedData, class TimeFrequencyData &oldData) { oldData.CopyFrom(cuttedData, _startTimeSteps, _topChannels); diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/rfi/strategy/fouriertransformaction.h b/CEP/DP3/AOFlagger/include/AOFlagger/rfi/strategy/fouriertransformaction.h index 88b98d5d461..9b9ad7481e1 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/rfi/strategy/fouriertransformaction.h +++ b/CEP/DP3/AOFlagger/include/AOFlagger/rfi/strategy/fouriertransformaction.h @@ -35,7 +35,7 @@ namespace rfiStrategy { class FourierTransformAction : public Action { public: - FourierTransformAction() : Action(), _inverse(false) + FourierTransformAction() : Action(), _inverse(false), _dynamic(false), _sections(64) { } virtual std::string Description() @@ -60,12 +60,19 @@ namespace rfiStrategy { Image2DPtr real = Image2D::CreateCopy(data.GetImage(0)), imaginary = Image2D::CreateCopy(data.GetImage(1)); - FFTTools::CreateHorizontalFFTImage(*real, *imaginary, _inverse); + if(_dynamic) + { + FFTTools::CreateDynamicHorizontalFFTImage(real, imaginary, _sections, _inverse); + } else { + FFTTools::CreateHorizontalFFTImage(*real, *imaginary, _inverse); + } data.SetImage(0, real); data.SetImage(1, imaginary); } bool _inverse; + bool _dynamic; + unsigned _sections; }; } // namespace diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/rfi/uvprojection.h b/CEP/DP3/AOFlagger/include/AOFlagger/rfi/uvprojection.h index 6b27e112e4c..b88c9e7443b 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/rfi/uvprojection.h +++ b/CEP/DP3/AOFlagger/include/AOFlagger/rfi/uvprojection.h @@ -152,15 +152,10 @@ class UVProjection rangeEnd = inputWidth - rangeStart; for(unsigned x=0;x<inputWidth;++x) { - if(x > rangeStart && x < rangeEnd) - { - if(weights->Value(x, y) != 0.0) - destination->SetValue(x, y, destination->Value(x, y) / weights->Value(x, y)); - else - AOLogger::Warn << "UV projection did not fill entire range\n"; - } else { + if(x > rangeStart && x < rangeEnd && weights->Value(x, y) != 0.0) + destination->SetValue(x, y, destination->Value(x, y) / weights->Value(x, y)); + else destination->SetValue(x, y, 0.0); - } } } } diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/util/ffttools.h b/CEP/DP3/AOFlagger/include/AOFlagger/util/ffttools.h index 740125ef626..251662fdf8c 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/util/ffttools.h +++ b/CEP/DP3/AOFlagger/include/AOFlagger/util/ffttools.h @@ -81,6 +81,7 @@ class FFTTools{ static void Multiply(Image2D &leftReal, Image2D &leftImaginary, const Image2D &rightReal, const Image2D &rightImaginary); static void Sqrt(Image2D &image); static void CreateHorizontalFFTImage(Image2D &real, Image2D &imaginary, bool inverse=false); + static void CreateDynamicHorizontalFFTImage(Image2DPtr real, Image2DPtr imaginary, unsigned sections, bool inverse=false); static Image2DPtr AngularTransform(Image2DCPtr input); static void FFT(SampleRowPtr realRow, SampleRowPtr imaginaryRow); private: diff --git a/CEP/DP3/AOFlagger/src/gui/complexplaneplotwindow.cpp b/CEP/DP3/AOFlagger/src/gui/complexplaneplotwindow.cpp index 558b9b5f29b..a99b72648b1 100644 --- a/CEP/DP3/AOFlagger/src/gui/complexplaneplotwindow.cpp +++ b/CEP/DP3/AOFlagger/src/gui/complexplaneplotwindow.cpp @@ -212,17 +212,12 @@ void ComplexPlanePlotWindow::onPlotPressed() else plot.StartLine("Fit (real)"); size_t middleY = (2*y + avgSize) / 2; - double timeStart = _observationTimes[x]; double deltaTime; if(_observationTimes.size()>1) deltaTime = _observationTimes[1] - _observationTimes[0]; else deltaTime = 1.0; - double timeEnd = _observationTimes[x+length-1]+deltaTime; - long double frequency = _msWindow.TimeFrequencyMetaData()->Band().channels[middleY].frequencyHz; Baseline baseline(_msWindow.TimeFrequencyMetaData()->Antenna1(), _msWindow.TimeFrequencyMetaData()->Antenna2()); - long double delayRA = _msWindow.TimeFrequencyMetaData()->Field().delayDirectionRA; - long double delayDec = _msWindow.TimeFrequencyMetaData()->Field().delayDirectionDec; long double fringeCount = UVImager::GetFringeCount(x, x+length, middleY, _msWindow.TimeFrequencyMetaData()); long double fringeFrequency = fringeCount / length; @@ -350,7 +345,6 @@ void ComplexPlanePlotWindow::setDetailsLabel() deltaTime = _observationTimes[1] - _observationTimes[0]; else deltaTime = 1.0; - double timeEnd = _observationTimes[x+length-1]+deltaTime; long double frequency = metaData->Band().channels[middleY].frequencyHz; Baseline baseline(metaData->Antenna1(), metaData->Antenna2()); long double delayRA = metaData->Field().delayDirectionRA; diff --git a/CEP/DP3/AOFlagger/src/gui/mswindow.cpp b/CEP/DP3/AOFlagger/src/gui/mswindow.cpp index 0dfb2d5cf11..1c154d973be 100644 --- a/CEP/DP3/AOFlagger/src/gui/mswindow.cpp +++ b/CEP/DP3/AOFlagger/src/gui/mswindow.cpp @@ -514,6 +514,9 @@ void MSWindow::createToolbar() _timeGraphButton = Gtk::ToggleAction::create("TimeGraph", "Time graph"); _timeGraphButton->set_active(false); _actionGroup->add(_timeGraphButton, sigc::mem_fun(*this, &MSWindow::onTimeGraphButtonPressed) ); + _winsorizedColorsButton = Gtk::ToggleAction::create("WinsorizedColors", "Winsorized colors"); + _winsorizedColorsButton->set_active(true); + _actionGroup->add(_winsorizedColorsButton, sigc::mem_fun(*this, &MSWindow::onWinsorizedColorsPressed) ); _actionGroup->add( Gtk::Action::create("PlotDist", "Plot _distribution"), sigc::mem_fun(*this, &MSWindow::onPlotDistPressed) ); @@ -681,6 +684,8 @@ void MSWindow::createToolbar() " <menuitem action='MapLog'/>" " <menuitem action='MapColor'/>" " <separator/>" + " <menuitem action='WinsorizedColors'/>" + " <separator/>" " <menuitem action='TimeGraph'/>" " </menu>" " <menu action='MenuPlot'>" diff --git a/CEP/DP3/AOFlagger/src/util/ffttools.cpp b/CEP/DP3/AOFlagger/src/util/ffttools.cpp index 60c9e3d8ce1..3143dcdd24e 100644 --- a/CEP/DP3/AOFlagger/src/util/ffttools.cpp +++ b/CEP/DP3/AOFlagger/src/util/ffttools.cpp @@ -302,6 +302,62 @@ void FFTTools::CreateHorizontalFFTImage(Image2D &real, Image2D &imaginary, bool fftw_free(in); } +void FFTTools::CreateDynamicHorizontalFFTImage(Image2DPtr real, Image2DPtr imaginary, unsigned sections, bool inverse) +{ + const size_t width = real->Width(); + if(real->Height() == 0 || width == 0) return; + SampleRowPtr + realRow = SampleRow::CreateFromRowSum(real, 0, real->Height()), + imaginaryRow = SampleRow::CreateFromRowSum(imaginary, 0, imaginary->Height()); + + Image2DPtr + destReal = Image2D::CreateEmptyImagePtr(real->Width(), real->Height()), + destImag = Image2D::CreateEmptyImagePtr(real->Width(), real->Height()); + + unsigned long n_in = width; + fftw_complex *in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n_in); + fftw_complex *out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n_in); + + int sign = -1; + if(inverse) + sign = 1; + + for(unsigned sec=0;sec<sections;++sec) + { + const unsigned + secStart = width * sec / (sections + 1), + secEnd = width * (sec + 2) / (sections + 1); + + for(unsigned x=secStart;x<secEnd;++x) { + in[x-secStart][0] = realRow->Value(x); + in[x-secStart][1] = imaginaryRow->Value(x); + } + + fftw_plan plan = fftw_plan_dft_1d(secEnd - secStart, in, out, sign, FFTW_ESTIMATE); + fftw_execute(plan); + fftw_destroy_plan(plan); + + size_t maxF = secEnd - secStart; + if(maxF > destReal->Height()) maxF = destReal->Height(); + unsigned xEnd = width*(sec+1)/sections; + for(unsigned long x=width*sec/sections;x<xEnd;++x) { + for(unsigned long y=0;y<maxF;++y) { + destReal->SetValue(x, y, out[y][0]); + destImag->SetValue(x, y, out[y][1]); + } + for(unsigned long y=maxF;y<destReal->Height();++y) + { + destReal->SetValue(x, y, 0.0); + destImag->SetValue(x, y, 0.0); + } + } + } + fftw_free(out); + fftw_free(in); + real->SetValues(destReal); + imaginary->SetValues(destImag); +} + Image2DPtr FFTTools::AngularTransform(Image2DCPtr image) { size_t minDim = image->Width() > image->Height() ? image->Height() : image->Width(); -- GitLab