public static Tuple <double, double> EstimateObjectives(float[,] xImage, float[,] residuals, float[,] psf, float[,] xExplore, float[,] xAccelerated, float lambda, float alpha, float[,] psfCut, float[,] bMap)
        {
            Tuple <double, double> output = null;

            var CONVKernel = PSF.CalcPaddedFourierConvolution(psf, new Rectangle(0, 0, residuals.GetLength(0), residuals.GetLength(1)));

            using (var residualsCalculator = new PaddedConvolver(CONVKernel, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))))
            {
                var residualsExplore     = new float[xImage.GetLength(0), xImage.GetLength(1)];
                var residualsAccelerated = new float[xImage.GetLength(0), xImage.GetLength(1)];
                for (int i = 0; i < xImage.GetLength(0); i++)
                {
                    for (int j = 0; j < xImage.GetLength(1); j++)
                    {
                        residualsExplore[i, j]     = xExplore[i, j] - xImage[i, j];
                        residualsAccelerated[i, j] = xAccelerated[i, j] - xImage[i, j];
                    }
                }
                residualsCalculator.ConvolveInPlace(residualsExplore);
                residualsCalculator.ConvolveInPlace(residualsAccelerated);

                for (int i = 0; i < xImage.GetLength(0); i++)
                {
                    for (int j = 0; j < xImage.GetLength(1); j++)
                    {
                        residualsExplore[i, j]     = residuals[i, j] - residualsExplore[i, j];
                        residualsAccelerated[i, j] = residuals[i, j] - residualsAccelerated[i, j];
                    }
                }

                var objectiveExplore     = Residuals.CalcPenalty(residualsExplore) + ElasticNet.CalcPenalty(xExplore, lambda, alpha);
                var objectiveAccelerated = Residuals.CalcPenalty(residualsAccelerated) + ElasticNet.CalcPenalty(xAccelerated, lambda, alpha);

                /*
                 * var CORRKernel = PSF.CalcPaddedFourierCorrelation(psfCut, new Rectangle(0, 0, residuals.GetLength(0), residuals.GetLength(1)));
                 * var bMapFull = Residuals.CalcBMap(residualsExplore, CORRKernel, new Rectangle(0, 0, psfCut.GetLength(0), psfCut.GetLength(1)));
                 * FitsIO.Write(bMap, "bMapOriginal.fits");
                 * FitsIO.Write(bMapFull, "bMapSanity.fits");
                 * var diff = new float[bMap.GetLength(0), bMap.GetLength(1)];
                 * for (int i = 0; i < xImage.GetLength(0); i++)
                 *  for (int j = 0; j < xImage.GetLength(1); j++)
                 *      diff[i, j] = bMap[i, j] - bMapFull[i, j];
                 * FitsIO.Write(diff, "bmapSanityDiff.fits");*/

                output = new Tuple <double, double>(objectiveExplore, objectiveAccelerated);
            }

            return(output);
        }
        public void ISTAStep(float[,] xImage, float[,] residuals, float[,] psf, float lambda, float alpha)
        {
            var xOld       = Copy(xImage);
            var corrKernel = PSF.CalcPaddedFourierCorrelation(psf, new Rectangle(0, 0, residuals.GetLength(0), residuals.GetLength(1)));
            var gradients  = Residuals.CalcGradientMap(residuals, corrKernel, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1)));

            var lipschitz = (float)PSF.CalcMaxLipschitz(psf) * xImage.Length;

            for (int i = 0; i < xImage.GetLength(0); i++)
            {
                for (int j = 0; j < xImage.GetLength(1); j++)
                {
                    var tmp = gradients[i, j] + xImage[i, j] * lipschitz;
                    tmp          = ElasticNet.ProximalOperator(tmp, lipschitz, lambda, alpha);
                    xImage[i, j] = tmp;
                }
            }

            //update residuals
            for (int i = 0; i < xImage.GetLength(0); i++)
            {
                for (int j = 0; j < xImage.GetLength(1); j++)
                {
                    xOld[i, j] = xImage[i, j] - xOld[i, j];
                }
            }

            var convKernel          = PSF.CalcPaddedFourierConvolution(psf, new Rectangle(0, 0, residuals.GetLength(0), residuals.GetLength(1)));
            var residualsCalculator = new PaddedConvolver(convKernel, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1)));

            residualsCalculator.ConvolveInPlace(xOld);
            for (int i = 0; i < xImage.GetLength(0); i++)
            {
                for (int j = 0; j < xImage.GetLength(1); j++)
                {
                    residuals[i, j] -= xOld[i, j];
                }
            }
        }
        private static Tuple <double, double> CalcObjectives(float[,] xImage, float[,] residuals, float[,] psf, float[,] xExplore, float[,] xAccelerated, float lambda, float alpha)
        {
            Tuple <double, double> output = null;

            var CONVKernel = PSF.CalcPaddedFourierConvolution(psf, new Rectangle(0, 0, residuals.GetLength(0), residuals.GetLength(1)));

            using (var residualsCalculator = new PaddedConvolver(CONVKernel, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))))
            {
                var residualsExplore     = new float[xImage.GetLength(0), xImage.GetLength(1)];
                var residualsAccelerated = new float[xImage.GetLength(0), xImage.GetLength(1)];
                for (int i = 0; i < xImage.GetLength(0); i++)
                {
                    for (int j = 0; j < xImage.GetLength(1); j++)
                    {
                        residualsExplore[i, j]     = xExplore[i, j] - xImage[i, j];
                        residualsAccelerated[i, j] = xAccelerated[i, j] - xImage[i, j];
                    }
                }

                residualsCalculator.ConvolveInPlace(residualsExplore);
                residualsCalculator.ConvolveInPlace(residualsAccelerated);
                for (int i = 0; i < xImage.GetLength(0); i++)
                {
                    for (int j = 0; j < xImage.GetLength(1); j++)
                    {
                        residualsExplore[i, j]     -= residuals[i, j];
                        residualsAccelerated[i, j] -= residuals[i, j];
                    }
                }

                var objectiveExplore     = Residuals.CalcPenalty(residualsExplore) + ElasticNet.CalcPenalty(xExplore, lambda, alpha);
                var objectiveAccelerated = Residuals.CalcPenalty(residualsAccelerated) + ElasticNet.CalcPenalty(xAccelerated, lambda, alpha);

                output = new Tuple <double, double>(objectiveExplore, objectiveAccelerated);
            }

            return(output);
        }
Esempio n. 4
0
        public static void GeneratePSFs(string simulatedLocation, string outputFolder)
        {
            var data     = MeasurementData.LoadSimulatedPoints(simulatedLocation);
            var c        = MeasurementData.CreateSimulatedStandardParams(data.VisibilitiesCount);
            var metadata = Partitioner.CreatePartition(c, data.UVW, data.Frequencies);

            var psfGrid = IDG.GridPSF(c, metadata, data.UVW, data.Flags, data.Frequencies);
            var psf     = FFT.BackwardFloat(psfGrid, c.VisibilitiesCount);

            FFT.Shift(psf);

            Directory.CreateDirectory(outputFolder);

            var maskedPsf = Copy(psf);

            Tools.Mask(maskedPsf, 2);
            var reverseMasked = Copy(psf);

            Tools.ReverseMask(reverseMasked, 2);
            var psf2    = PSF.CalcPSFSquared(psf);
            var psf2Cut = PSF.CalcPSFSquared(maskedPsf);

            Tools.WriteToMeltCSV(psf, Path.Combine(outputFolder, "psf.csv"));
            Tools.WriteToMeltCSV(maskedPsf, Path.Combine(outputFolder, "psfCut.csv"));
            Tools.WriteToMeltCSV(reverseMasked, Path.Combine(outputFolder, "psfReverseCut.csv"));
            Tools.WriteToMeltCSV(psf2, Path.Combine(outputFolder, "psfSquared.csv"));
            Tools.WriteToMeltCSV(psf2Cut, Path.Combine(outputFolder, "psfSquaredCut.csv"));

            var x = new float[c.GridSize, c.GridSize];

            x[10, 10] = 1.0f;

            var convKernel = PSF.CalcPaddedFourierConvolution(psf, new Rectangle(0, 0, c.GridSize, c.GridSize));
            var corrKernel = PSF.CalcPaddedFourierCorrelation(psf, new Rectangle(0, 0, c.GridSize, c.GridSize));

            using (var convolver = new PaddedConvolver(convKernel, new Rectangle(0, 0, c.GridSize, c.GridSize)))
                using (var correlator = new PaddedConvolver(corrKernel, new Rectangle(0, 0, c.GridSize, c.GridSize)))
                {
                    var zeroPadded = convolver.Convolve(x);
                    var psf2Edge   = correlator.Convolve(zeroPadded);
                    Tools.WriteToMeltCSV(zeroPadded, Path.Combine(outputFolder, "psfZeroPadding.csv"));
                    Tools.WriteToMeltCSV(psf2Edge, Path.Combine(outputFolder, "psfSquaredEdge.csv"));
                }
            convKernel = PSF.CalcPaddedFourierConvolution(psf, new Rectangle(0, 0, 0, 0));
            using (var convolver = new PaddedConvolver(convKernel, new Rectangle(0, 0, 0, 0)))
                Tools.WriteToMeltCSV(convolver.Convolve(x), Path.Combine(outputFolder, "psfCircular.csv"));

            //================================================= Reconstruct =============================================================
            var totalSize      = new Rectangle(0, 0, c.GridSize, c.GridSize);
            var reconstruction = new float[c.GridSize, c.GridSize];
            var fastCD         = new FastSerialCD(totalSize, psf);
            var lambda         = 0.50f * fastCD.MaxLipschitz;
            var alpha          = 0.2f;

            var residualVis = data.Visibilities;

            for (int cycle = 0; cycle < 5; cycle++)
            {
                Console.WriteLine("in cycle " + cycle);
                var dirtyGrid  = IDG.Grid(c, metadata, residualVis, data.UVW, data.Frequencies);
                var dirtyImage = FFT.BackwardFloat(dirtyGrid, c.VisibilitiesCount);
                FFT.Shift(dirtyImage);

                var gradients = Residuals.CalcGradientMap(dirtyImage, corrKernel, totalSize);

                if (cycle == 0)
                {
                    Tools.WriteToMeltCSV(dirtyImage, Path.Combine(outputFolder, "dirty.csv"));
                    Tools.WriteToMeltCSV(gradients, Path.Combine(outputFolder, "gradients.csv"));
                }

                fastCD.Deconvolve(reconstruction, gradients, lambda, alpha, 10000, 1e-5f);

                FFT.Shift(reconstruction);
                var xGrid = FFT.Forward(reconstruction);
                FFT.Shift(reconstruction);
                var modelVis = IDG.DeGrid(c, metadata, xGrid, data.UVW, data.Frequencies);
                residualVis = Visibilities.Substract(data.Visibilities, modelVis, data.Flags);
            }

            //FitsIO.Write(reconstruction, Path.Combine(outputFolder,"xImage.fits"));
            Tools.WriteToMeltCSV(reconstruction, Path.Combine(outputFolder, "elasticNet.csv"));
        }
        public bool DeconvolveGreedy(float[,] xImage, float[,] residuals, float[,] psf, float lambda, float alpha, Random random, int blockSize, int threadCount, int maxIteration = 100, float epsilon = 1e-4f)
        {
            var xExplore    = Copy(xImage);
            var xCorrection = new float[xImage.GetLength(0), xImage.GetLength(1)];

            var PSFCorr = PSF.CalcPaddedFourierCorrelation(psf, new Rectangle(0, 0, residuals.GetLength(0), residuals.GetLength(1)));

            //calculate gradients for each pixel
            var gExplore    = Residuals.CalcGradientMap(residuals, PSFCorr, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1)));
            var gCorrection = new float[residuals.GetLength(0), residuals.GetLength(1)];
            var psf2        = PSF.CalcPSFSquared(psf);

            FitsIO.Write(gExplore, "gExplore.fits");

            yBlockSize           = blockSize;
            xBlockSize           = blockSize;
            degreeOfSeperability = CountNonZero(psf);
            tau = threadCount; //number of processors
            var maxLipschitz = (float)PSF.CalcMaxLipschitz(psf);

            var theta = Greedy(xExplore, xCorrection, gExplore, gCorrection, psf2, maxLipschitz, lambda, alpha, random, maxIteration, epsilon);

            //decide which version should be taken#
            var CONVKernel          = PSF.CalcPaddedFourierConvolution(psf, new Rectangle(0, 0, residuals.GetLength(0), residuals.GetLength(1)));
            var residualsCalculator = new PaddedConvolver(CONVKernel, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1)));
            var theta0   = tau / (float)(xExplore.Length / (yBlockSize * xBlockSize));
            var tmpTheta = theta < 1.0f ? ((theta * theta) / (1.0f - theta)) : theta0;

            //calculate residuals
            var residualsExplore     = Copy(xExplore);
            var residualsAccelerated = Copy(xExplore);

            for (int i = 0; i < xImage.GetLength(0); i++)
            {
                for (int j = 0; j < xImage.GetLength(1); j++)
                {
                    residualsExplore[i, j]     -= xImage[i, j];
                    residualsAccelerated[i, j] += tmpTheta * xCorrection[i, j] - xImage[i, j];
                    xCorrection[i, j]           = tmpTheta * xCorrection[i, j] + xExplore[i, j];
                }
            }

            FitsIO.Write(xExplore, "xExplore.fits");
            FitsIO.Write(xCorrection, "xAcc.fits");

            residualsCalculator.ConvolveInPlace(residualsExplore);
            residualsCalculator.ConvolveInPlace(residualsAccelerated);
            for (int i = 0; i < xImage.GetLength(0); i++)
            {
                for (int j = 0; j < xImage.GetLength(1); j++)
                {
                    residualsExplore[i, j]     -= residuals[i, j];
                    residualsAccelerated[i, j] -= residuals[i, j];
                }
            }

            var objectiveExplore = Residuals.CalcPenalty(residualsExplore) + ElasticNet.CalcPenalty(xExplore, lambda, alpha);
            var objectiveAcc     = Residuals.CalcPenalty(residualsAccelerated) + ElasticNet.CalcPenalty(xCorrection, lambda, alpha);

            if (objectiveAcc < objectiveExplore)
            {
                for (int i = 0; i < xImage.GetLength(0); i++)
                {
                    for (int j = 0; j < xImage.GetLength(1); j++)
                    {
                        xImage[i, j] = xCorrection[i, j];
                    }
                }
            }
            else
            {
                for (int i = 0; i < xImage.GetLength(0); i++)
                {
                    for (int j = 0; j < xImage.GetLength(1); j++)
                    {
                        xImage[i, j] = xExplore[i, j];
                    }
                }
            }

            return(objectiveAcc < objectiveExplore);
        }