private static DirtyImage ForwardCalculateB(Intracommunicator comm, GriddingConstants c, List <List <Subgrid> > metadata, Complex[,,] visibilities, double[,,] uvw, double[] frequencies, Complex[,] PsfCorrelation, float[,] psfCut, float maxSidelobe, Stopwatch watchIdg) { Stopwatch another = new Stopwatch(); comm.Barrier(); if (comm.Rank == 0) { watchIdg.Start(); } var localGrid = IDG.Grid(c, metadata, visibilities, uvw, frequencies); float[,] image = null; float maxSideLobeLevel = 0.0f; var grid_total = comm.Reduce <Complex[, ]>(localGrid, SequentialSum, 0); if (comm.Rank == 0) { var dirtyImage = FFT.BackwardFloat(grid_total, c.VisibilitiesCount); FFT.Shift(dirtyImage); if (comm.Rank == 0) { FitsIO.Write(dirtyImage, "dirtyImage.fits"); } maxSideLobeLevel = maxSidelobe * Residuals.GetMax(dirtyImage); //remove spheroidal image = Residuals.CalcGradientMap(dirtyImage, PsfCorrelation, new Rectangle(0, 0, psfCut.GetLength(0), psfCut.GetLength(1))); watchIdg.Stop(); } comm.Broadcast(ref maxSideLobeLevel, 0); comm.Broadcast(ref image, 0); return(new DirtyImage(image, maxSideLobeLevel)); }
public static void GenerateSerialCDExample(string simulatedLocation, string outputFolder) { var data = MeasurementData.LoadSimulatedPoints(simulatedLocation); var cellSize = 1.0 / 3600.0 * Math.PI / 180.0; var c = new GriddingConstants(data.VisibilitiesCount, 256, 8, 4, 512, (float)cellSize, 1, 0.0); 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); var corrKernel = PSF.CalcPaddedFourierCorrelation(psf, new Rectangle(0, 0, c.GridSize, c.GridSize)); Directory.CreateDirectory(outputFolder); var reconstruction = new float[c.GridSize, c.GridSize]; var residualVis = data.Visibilities; var totalSize = new Rectangle(0, 0, c.GridSize, c.GridSize); var fastCD = new FastSerialCD(totalSize, psf); var lambda = 0.50f * fastCD.MaxLipschitz; var alpha = 0.2f; for (int cycle = 0; cycle < 100; 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); Tools.WriteToMeltCSV(Common.PSF.Cut(reconstruction), Path.Combine(outputFolder, "model_CD_" + cycle + ".csv")); Tools.WriteToMeltCSV(gradients, Path.Combine(outputFolder, "gradients_CD_" + cycle + ".csv")); fastCD.Deconvolve(reconstruction, gradients, lambda, alpha, 4); 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); } }
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]; } } }
public bool DeconvolveApprox(float[,] xImage, float[,] residuals, float[,] psf, float lambda, float alpha, Random random, int blockSize, int threadCount, int maxIteration = 100, float epsilon = 1e-4f, bool coldStart = false) { var xExplore = Copy(xImage); var xCorrection = new float[xImage.GetLength(0), xImage.GetLength(1)]; //calculate gradients for each pixel var PSFCorr = PSF.CalcPaddedFourierCorrelation(psf, new Rectangle(0, 0, residuals.GetLength(0), residuals.GetLength(1))); 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); if (coldStart) { var rec = new Rectangle(0, 0, xImage.GetLength(0), xImage.GetLength(1)); var fastCD = new FastSerialCD(rec, rec, psf, psf2); fastCD.Deconvolve(xExplore, gExplore, lambda, alpha, xImage.GetLength(0)); } yBlockSize = blockSize; xBlockSize = blockSize; degreeOfSeperability = CountNonZero(psf); tau = threadCount; //number of processors var maxLipschitz = (float)PSF.CalcMaxLipschitz(psf); var activeSet = GetActiveSet(xExplore, gExplore, lambda, alpha, maxLipschitz); var theta = DeconvolveAccelerated(xExplore, xCorrection, gExplore, gCorrection, psf2, ref activeSet, maxLipschitz, lambda, alpha, random, maxIteration, epsilon); var theta0 = tau / (float)activeSet.Count; var tmpTheta = theta < 1.0f ? ((theta * theta) / (1.0f - theta)) : theta0; for (int i = 0; i < xImage.GetLength(0); i++) { for (int j = 0; j < xImage.GetLength(1); j++) { xCorrection[i, j] = tmpTheta * xCorrection[i, j] + xExplore[i, j]; } } var objectives = CalcObjectives(xImage, residuals, psf, xExplore, xCorrection, lambda, alpha); //decide whether we take the correction or explore version if (objectives.Item2 < objectives.Item1) { //correction has the lower objective than explore 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(objectives.Item2 < objectives.Item1); }
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); }