public static void Run() { var folder = @"C:\dev\GitHub\p9-data\small\fits\simulation_point\"; var data = DataLoading.SimulatedPoints.Load(folder); var gridSizes = new int[] { 256, 512, 1024, 2048, 4096 }; Directory.CreateDirectory("GPUSpeedup"); var writer = new StreamWriter("GPUSpeedup/GPUSpeedup.txt", false); writer.WriteLine("imgSize;iterCPU;timeCPU;iterGPU;timeGPU"); foreach (var gridSize in gridSizes) { var visibilitiesCount = data.visibilitiesCount; int subgridsize = 8; int kernelSize = 4; int max_nr_timesteps = 1024; double cellSize = (1.0 * 256 / gridSize) / 3600.0 * Math.PI / 180.0; var c = new GriddingConstants(visibilitiesCount, gridSize, subgridsize, kernelSize, max_nr_timesteps, (float)cellSize, 1, 0.0f); var metadata = Partitioner.CreatePartition(c, data.uvw, data.frequencies); var frequencies = FitsIO.ReadFrequencies(Path.Combine(folder, "freq.fits")); var uvw = FitsIO.ReadUVW(Path.Combine(folder, "uvw.fits")); var flags = new bool[uvw.GetLength(0), uvw.GetLength(1), frequencies.Length]; double norm = 2.0; var visibilities = FitsIO.ReadVisibilities(Path.Combine(folder, "vis.fits"), uvw.GetLength(0), uvw.GetLength(1), frequencies.Length, norm); var psfGrid = IDG.GridPSF(c, metadata, uvw, flags, frequencies); var psf = FFT.BackwardFloat(psfGrid, c.VisibilitiesCount); FFT.Shift(psf); var residualVis = data.visibilities; var dirtyGrid = IDG.Grid(c, metadata, residualVis, data.uvw, data.frequencies); var dirtyImage = FFT.BackwardFloat(dirtyGrid, c.VisibilitiesCount); FFT.Shift(dirtyImage); var totalSize = new Rectangle(0, 0, gridSize, gridSize); var bMapCalculator = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(psf, totalSize), new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var bMapCPU = bMapCalculator.Convolve(dirtyImage); var bMapGPU = bMapCalculator.Convolve(dirtyImage); var fastCD = new FastSerialCD(totalSize, psf); var gpuCD = new GPUSerialCD(totalSize, psf, 1000); var lambda = 0.5f * fastCD.MaxLipschitz; var alpha = 0.5f; var xCPU = new float[gridSize, gridSize]; var cpuResult = fastCD.Deconvolve(xCPU, bMapCPU, lambda, alpha, 10000, 1e-8f); FitsIO.Write(xCPU, "GPUSpeedup/cpuResult" + gridSize + ".fits"); var xGPU = new float[gridSize, gridSize]; var gpuResult = gpuCD.Deconvolve(xGPU, bMapGPU, lambda, alpha, 10000, 1e-8f); FitsIO.Write(xCPU, "GPUSpeedup/gpuResult" + gridSize + ".fits"); writer.WriteLine(gridSize + ";" + cpuResult.IterationCount + ";" + cpuResult.ElapsedTime.TotalSeconds + ";" + gpuResult.IterationCount + ";" + gpuResult.ElapsedTime.TotalSeconds); writer.Flush(); } writer.Close(); }
private static void ReconstructRandom(MeasurementData input, GriddingConstants c, float[,] psf, int blockSize, int iterCount, string file) { var cutFactor = 8; var totalSize = new Rectangle(0, 0, c.GridSize, c.GridSize); var psfCut = PSF.Cut(psf, cutFactor); var maxSidelobe = PSF.CalcMaxSidelobe(psf, cutFactor); var maxLipschitzCut = PSF.CalcMaxLipschitz(psfCut); var lambda = (float)(LAMBDA * PSF.CalcMaxLipschitz(psfCut)); var lambdaTrue = (float)(LAMBDA * PSF.CalcMaxLipschitz(psf)); var alpha = ALPHA; ApproxFast.LAMBDA_TEST = lambdaTrue; ApproxFast.ALPHA_TEST = alpha; var metadata = Partitioner.CreatePartition(c, input.UVW, input.Frequencies); var random = new Random(123); var approx = new ApproxFast(totalSize, psfCut, 8, blockSize, 0.0f, 0.0f, false, true, false); var bMapCalculator = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(psfCut, totalSize), new Rectangle(0, 0, psfCut.GetLength(0), psfCut.GetLength(1))); var data = new ApproxFast.TestingData(new StreamWriter(file + "_tmp.txt")); var xImage = new float[c.GridSize, c.GridSize]; var xCorr = Copy(xImage); var residualVis = input.Visibilities; var dirtyGrid = IDG.GridW(c, metadata, residualVis, input.UVW, input.Frequencies); var dirtyImage = FFT.WStackIFFTFloat(dirtyGrid, c.VisibilitiesCount); FFT.Shift(dirtyImage); var maxDirty = Residuals.GetMax(dirtyImage); var bMap = bMapCalculator.Convolve(dirtyImage); var maxB = Residuals.GetMax(bMap); var correctionFactor = Math.Max(maxB / (maxDirty * maxLipschitzCut), 1.0f); var currentSideLobe = maxB * maxSidelobe * correctionFactor; var currentLambda = (float)Math.Max(currentSideLobe / alpha, lambda); var gCorr = new float[c.GridSize, c.GridSize]; var shared = new ApproxFast.SharedData(currentLambda, alpha, 1, 1, 8, CountNonZero(psfCut), approx.psf2, approx.aMap, xImage, xCorr, bMap, gCorr, new Random()); shared.ActiveSet = ApproxFast.GetActiveSet(xImage, bMap, shared.YBlockSize, shared.XBlockSize, lambda, alpha, shared.AMap); shared.BlockLock = new int[shared.ActiveSet.Count]; shared.maxLipschitz = (float)PSF.CalcMaxLipschitz(psfCut); shared.MaxConcurrentIterations = 1000; approx.DeconvolveConcurrentTest(data, 0, 0, 0.0, shared, 1, 1e-5f, Copy(xImage), dirtyImage, psfCut, psf); var output = Tools.LMC.CutN132Remnant(xImage); Tools.WriteToMeltCSV(output.Item1, file + "_1k.csv", output.Item2, output.Item3); FitsIO.Write(output.Item1, file + "_1k.fits"); FitsIO.Write(xImage, file + "_1k2.fits"); approx.DeconvolveConcurrentTest(data, 0, 0, 0.0, shared, iterCount, 1e-5f, Copy(xImage), dirtyImage, psfCut, psf); output = Tools.LMC.CutN132Remnant(xImage); Tools.WriteToMeltCSV(output.Item1, file + "_10k.csv", output.Item2, output.Item3); FitsIO.Write(output.Item1, file + "_10k.fits"); FitsIO.Write(xImage, file + "_10k2.fits"); }
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); }
private static ReconstructionInfo ReconstructGradientApprox(Data input, float[,] fullPsf, string folder, int cutFactor, int maxMajor, string dirtyPrefix, string xImagePrefix, StreamWriter writer, double objectiveCutoff, float epsilon) { var info = new ReconstructionInfo(); var psfCut = PSF.Cut(fullPsf, cutFactor); var maxSidelobe = PSF.CalcMaxSidelobe(fullPsf, cutFactor); var totalSize = new Rectangle(0, 0, input.c.GridSize, input.c.GridSize); var psfBMap = psfCut; var bMapCalculator = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(psfBMap, totalSize), new Rectangle(0, 0, psfBMap.GetLength(0), psfBMap.GetLength(1))); var bMapCalculator2 = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(fullPsf, totalSize), new Rectangle(0, 0, fullPsf.GetLength(0), fullPsf.GetLength(1))); var fastCD = new FastSerialCD(totalSize, psfCut); var fastCD2 = new FastSerialCD(totalSize, psfCut); fastCD2.ResetLipschitzMap(fullPsf); FitsIO.Write(psfCut, folder + cutFactor + "psf.fits"); var lambda = LAMBDA_GLOBAL * fastCD.MaxLipschitz; var lambdaTrue = (float)(LAMBDA_GLOBAL * PSF.CalcMaxLipschitz(fullPsf)); var xImage = new float[input.c.GridSize, input.c.GridSize]; var residualVis = input.visibilities; DeconvolutionResult lastResult = null; var firstTimeConverged = false; var lastLambda = 0.0f; for (int cycle = 0; cycle < maxMajor; cycle++) { Console.WriteLine("cycle " + cycle); var dirtyGrid = IDG.GridW(input.c, input.metadata, residualVis, input.uvw, input.frequencies); var dirtyImage = FFT.WStackIFFTFloat(dirtyGrid, input.c.VisibilitiesCount); FFT.Shift(dirtyImage); FitsIO.Write(dirtyImage, folder + dirtyPrefix + cycle + ".fits"); //calc data and reg penalty var dataPenalty = Residuals.CalcPenalty(dirtyImage); var regPenalty = ElasticNet.CalcPenalty(xImage, lambdaTrue, alpha); var regPenaltyCurrent = ElasticNet.CalcPenalty(xImage, lambda, alpha); info.lastDataPenalty = dataPenalty; info.lastRegPenalty = regPenalty; var maxDirty = Residuals.GetMax(dirtyImage); var bMap = bMapCalculator.Convolve(dirtyImage); FitsIO.Write(bMap, folder + dirtyPrefix + "bmap_" + cycle + ".fits"); var maxB = Residuals.GetMax(bMap); var correctionFactor = Math.Max(maxB / (maxDirty * fastCD.MaxLipschitz), 1.0f); var currentSideLobe = maxB * maxSidelobe * correctionFactor; var currentLambda = Math.Max(currentSideLobe / alpha, lambda); writer.Write(cycle + ";" + currentLambda + ";" + currentSideLobe + ";" + ";" + fastCD2.GetAbsMaxDiff(xImage, bMap, lambdaTrue, alpha) + ";" + dataPenalty + ";" + regPenalty + ";" + regPenaltyCurrent + ";");; writer.Flush(); //check wether we can minimize the objective further with the current psf var objectiveReached = (dataPenalty + regPenalty) < objectiveCutoff; var minimumReached = (lastResult != null && lastResult.Converged && fastCD2.GetAbsMaxDiff(xImage, dirtyImage, lambdaTrue, alpha) < MAJOR_EPSILON && currentLambda == lambda); if (lambda == lastLambda & !firstTimeConverged) { firstTimeConverged = true; minimumReached = false; } if (!objectiveReached & !minimumReached) { //writer.Write(firstTimeConverged + ";"); //writer.Flush(); info.totalDeconv.Start(); if (!firstTimeConverged) { lastResult = fastCD.Deconvolve(xImage, bMap, currentLambda, alpha, 30000, epsilon); } else { bMap = bMapCalculator2.Convolve(dirtyImage); //FitsIO.Write(bMap, folder + dirtyPrefix + "bmap_" + cycle + "_full.fits"); maxB = Residuals.GetMax(bMap); correctionFactor = Math.Max(maxB / (maxDirty * fastCD2.MaxLipschitz), 1.0f); currentSideLobe = maxB * maxSidelobe * correctionFactor; currentLambda = Math.Max(currentSideLobe / alpha, lambdaTrue); info.totalDeconv.Start(); lastResult = fastCD.Deconvolve(xImage, bMap, currentLambda, alpha, 30000, epsilon); info.totalDeconv.Stop(); } info.totalDeconv.Stop(); FitsIO.Write(xImage, folder + xImagePrefix + cycle + ".fits"); writer.Write(lastResult.Converged + ";" + lastResult.IterationCount + ";" + lastResult.ElapsedTime.TotalSeconds + "\n"); writer.Flush(); FFT.Shift(xImage); var xGrid = FFT.Forward(xImage); FFT.Shift(xImage); var modelVis = IDG.DeGridW(input.c, input.metadata, xGrid, input.uvw, input.frequencies); residualVis = Visibilities.Substract(input.visibilities, modelVis, input.flags); } else { writer.Write(false + ";0;0\n"); writer.Flush(); break; } lastLambda = currentLambda; } bMapCalculator.Dispose(); bMapCalculator2.Dispose(); return(info); }
private static void ReconstructMinorCycle(MeasurementData input, GriddingConstants c, int cutFactor, float[,] fullPsf, string folder, string file, int minorCycles, float searchPercent, bool useAccelerated = true, int blockSize = 1, int maxCycle = 6) { var metadata = Partitioner.CreatePartition(c, input.UVW, input.Frequencies); var totalSize = new Rectangle(0, 0, c.GridSize, c.GridSize); var psfCut = PSF.Cut(fullPsf, cutFactor); var maxSidelobe = PSF.CalcMaxSidelobe(fullPsf, cutFactor); var sidelobeHalf = PSF.CalcMaxSidelobe(fullPsf, 2); var random = new Random(123); var approx = new ApproxFast(totalSize, psfCut, 8, blockSize, 0.1f, searchPercent, false, useAccelerated); using (var bMapCalculator = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(psfCut, totalSize), new Rectangle(0, 0, psfCut.GetLength(0), psfCut.GetLength(1)))) using (var bMapCalculator2 = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(fullPsf, totalSize), new Rectangle(0, 0, fullPsf.GetLength(0), fullPsf.GetLength(1)))) using (var residualsConvolver = new PaddedConvolver(totalSize, fullPsf)) { var currentBMapCalculator = bMapCalculator; var maxLipschitz = PSF.CalcMaxLipschitz(psfCut); var lambda = (float)(LAMBDA * maxLipschitz); var lambdaTrue = (float)(LAMBDA * PSF.CalcMaxLipschitz(fullPsf)); var alpha = ALPHA; ApproxFast.LAMBDA_TEST = lambdaTrue; ApproxFast.ALPHA_TEST = alpha; var switchedToOtherPsf = false; var writer = new StreamWriter(folder + "/" + file + "_lambda.txt"); var data = new ApproxFast.TestingData(new StreamWriter(folder + "/" + file + ".txt")); var xImage = new float[c.GridSize, c.GridSize]; var residualVis = input.Visibilities; for (int cycle = 0; cycle < maxCycle; cycle++) { Console.WriteLine("cycle " + cycle); var dirtyGrid = IDG.GridW(c, metadata, residualVis, input.UVW, input.Frequencies); var dirtyImage = FFT.WStackIFFTFloat(dirtyGrid, c.VisibilitiesCount); FFT.Shift(dirtyImage); FitsIO.Write(dirtyImage, folder + "/dirty" + cycle + ".fits"); var minLambda = 0.0f; var dirtyCopy = Copy(dirtyImage); var xCopy = Copy(xImage); var currentLambda = 0f; //var residualsConvolver = new PaddedConvolver(PSF.CalcPaddedFourierConvolution(fullPsf, totalSize), new Rectangle(0, 0, fullPsf.GetLength(0), fullPsf.GetLength(1))); for (int minorCycle = 0; minorCycle < minorCycles; minorCycle++) { FitsIO.Write(dirtyImage, folder + "/dirtyMinor_" + minorCycle + ".fits"); var maxDirty = Residuals.GetMax(dirtyImage); var bMap = currentBMapCalculator.Convolve(dirtyImage); var maxB = Residuals.GetMax(bMap); var correctionFactor = Math.Max(maxB / (maxDirty * maxLipschitz), 1.0f); var currentSideLobe = maxB * maxSidelobe * correctionFactor; currentLambda = (float)Math.Max(currentSideLobe / alpha, lambda); if (minorCycle == 0) { minLambda = (float)(maxB * sidelobeHalf * correctionFactor / alpha); } if (currentLambda < minLambda) { currentLambda = minLambda; } writer.WriteLine(cycle + ";" + minorCycle + ";" + currentLambda + ";" + minLambda); writer.Flush(); approx.DeconvolveTest(data, cycle, minorCycle, xImage, dirtyImage, psfCut, fullPsf, currentLambda, alpha, random, 15, 1e-5f); FitsIO.Write(xImage, folder + "/xImageMinor_" + minorCycle + ".fits"); if (currentLambda == lambda | currentLambda == minLambda) { break; } Console.WriteLine("resetting residuals!!"); //reset dirtyImage with full PSF var residualsUpdate = new float[xImage.GetLength(0), xImage.GetLength(1)]; Parallel.For(0, xCopy.GetLength(0), (i) => { for (int j = 0; j < xCopy.GetLength(1); j++) { residualsUpdate[i, j] = xImage[i, j] - xCopy[i, j]; } }); residualsConvolver.ConvolveInPlace(residualsUpdate); Parallel.For(0, xCopy.GetLength(0), (i) => { for (int j = 0; j < xCopy.GetLength(1); j++) { dirtyImage[i, j] = dirtyCopy[i, j] - residualsUpdate[i, j]; } }); } if (currentLambda == lambda & !switchedToOtherPsf) { approx.ResetAMap(fullPsf); currentBMapCalculator = bMapCalculator2; lambda = lambdaTrue; switchedToOtherPsf = true; writer.WriteLine("switched"); writer.Flush(); } FitsIO.Write(xImage, folder + "/xImage_" + cycle + ".fits"); FFT.Shift(xImage); var xGrid = FFT.Forward(xImage); FFT.Shift(xImage); var modelVis = IDG.DeGridW(c, metadata, xGrid, input.UVW, input.Frequencies); residualVis = Visibilities.Substract(input.Visibilities, modelVis, input.Flags); } writer.Close(); } }
private static void Reconstruct(Data input, int cutFactor, float[,] fullPsf, string folder, string file, int threads, int blockSize, bool accelerated, float randomPercent, float searchPercent) { var totalSize = new Rectangle(0, 0, input.c.GridSize, input.c.GridSize); var psfCut = PSF.Cut(fullPsf, cutFactor); var maxSidelobe = PSF.CalcMaxSidelobe(fullPsf, cutFactor); var bMapCalculator = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(psfCut, totalSize), new Rectangle(0, 0, psfCut.GetLength(0), psfCut.GetLength(1))); var random = new Random(123); var approx = new ApproxFast(totalSize, psfCut, threads, blockSize, randomPercent, searchPercent, false, true); var maxLipschitzCut = PSF.CalcMaxLipschitz(psfCut); var lambda = (float)(LAMBDA * PSF.CalcMaxLipschitz(psfCut)); var lambdaTrue = (float)(LAMBDA * PSF.CalcMaxLipschitz(fullPsf)); var alpha = ALPHA; ApproxFast.LAMBDA_TEST = lambdaTrue; ApproxFast.ALPHA_TEST = alpha; var switchedToOtherPsf = false; var writer = new StreamWriter(folder + "/" + file + "_lambda.txt"); var data = new ApproxFast.TestingData(new StreamWriter(folder + "/" + file + ".txt")); var xImage = new float[input.c.GridSize, input.c.GridSize]; var residualVis = input.visibilities; for (int cycle = 0; cycle < 7; cycle++) { Console.WriteLine("cycle " + cycle); var dirtyGrid = IDG.GridW(input.c, input.metadata, residualVis, input.uvw, input.frequencies); var dirtyImage = FFT.WStackIFFTFloat(dirtyGrid, input.c.VisibilitiesCount); FFT.Shift(dirtyImage); FitsIO.Write(dirtyImage, folder + "/dirty" + cycle + ".fits"); var maxDirty = Residuals.GetMax(dirtyImage); var bMap = bMapCalculator.Convolve(dirtyImage); var maxB = Residuals.GetMax(bMap); var correctionFactor = Math.Max(maxB / (maxDirty * maxLipschitzCut), 1.0f); var currentSideLobe = maxB * maxSidelobe * correctionFactor; var currentLambda = (float)Math.Max(currentSideLobe / alpha, lambda); writer.WriteLine("cycle" + ";" + currentLambda); writer.Flush(); approx.DeconvolveTest(data, cycle, 0, xImage, dirtyImage, psfCut, fullPsf, currentLambda, alpha, random, 15, 1e-5f); FitsIO.Write(xImage, folder + "/xImage_" + cycle + ".fits"); if (currentLambda == lambda & !switchedToOtherPsf) { approx.ResetAMap(fullPsf); lambda = lambdaTrue; switchedToOtherPsf = true; writer.WriteLine("switched"); writer.Flush(); } FFT.Shift(xImage); var xGrid = FFT.Forward(xImage); FFT.Shift(xImage); var modelVis = IDG.DeGridW(input.c, input.metadata, xGrid, input.uvw, input.frequencies); residualVis = Visibilities.Substract(input.visibilities, modelVis, input.flags); } writer.Close(); }
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")); }
private static void ReconstructPCDM(MeasurementData input, GriddingConstants c, float[,] fullPsf, string folder, string file, int minorCycles, float searchPercent, int processorCount) { var totalWatch = new Stopwatch(); var currentWatch = new Stopwatch(); var totalSize = new Rectangle(0, 0, c.GridSize, c.GridSize); var psfCut = PSF.Cut(fullPsf, CUT_FACTOR_PCDM); var maxSidelobe = PSF.CalcMaxSidelobe(fullPsf, CUT_FACTOR_PCDM); var sidelobeHalf = PSF.CalcMaxSidelobe(fullPsf, 2); var random = new Random(123); var pcdm = new ParallelCoordinateDescent(totalSize, psfCut, 1, 1000, searchPercent); var metadata = Partitioner.CreatePartition(c, input.UVW, input.Frequencies); using (var bMapCalculator = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(psfCut, totalSize), new Rectangle(0, 0, psfCut.GetLength(0), psfCut.GetLength(1)))) using (var bMapCalculator2 = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(fullPsf, totalSize), new Rectangle(0, 0, fullPsf.GetLength(0), fullPsf.GetLength(1)))) using (var residualsConvolver = new PaddedConvolver(totalSize, fullPsf)) { var currentBMapCalculator = bMapCalculator; var maxLipschitz = PSF.CalcMaxLipschitz(psfCut); var lambda = (float)(LAMBDA * maxLipschitz); var lambdaTrue = (float)(LAMBDA * PSF.CalcMaxLipschitz(fullPsf)); var alpha = ALPHA; var switchedToOtherPsf = false; var writer = new StreamWriter(folder + "/" + file + ".txt"); var xImage = new float[c.GridSize, c.GridSize]; var residualVis = input.Visibilities; ParallelCoordinateDescent.PCDMStatistics lastResult = null; for (int cycle = 0; cycle < 6; cycle++) { Console.WriteLine("Beginning Major cycle " + cycle); var dirtyGrid = IDG.GridW(c, metadata, residualVis, input.UVW, input.Frequencies); var dirtyImage = FFT.WStackIFFTFloat(dirtyGrid, c.VisibilitiesCount); FFT.Shift(dirtyImage); FitsIO.Write(dirtyImage, folder + "/dirty" + cycle + ".fits"); currentWatch.Restart(); totalWatch.Start(); var breakMajor = false; var minLambda = 0.0f; var dirtyCopy = Copy(dirtyImage); var xCopy = Copy(xImage); var currentLambda = 0f; var currentObjective = 0.0; var absMax = 0.0f; for (int minorCycle = 0; minorCycle < minorCycles; minorCycle++) { Console.WriteLine("Beginning Minor Cycle " + minorCycle); var maxDirty = Residuals.GetMax(dirtyImage); var bMap = currentBMapCalculator.Convolve(dirtyImage); var maxB = Residuals.GetMax(bMap); var correctionFactor = Math.Max(maxB / (maxDirty * maxLipschitz), 1.0f); var currentSideLobe = maxB * maxSidelobe * correctionFactor; currentLambda = (float)Math.Max(currentSideLobe / alpha, lambda); if (minorCycle == 0) { minLambda = (float)(maxB * sidelobeHalf * correctionFactor / alpha); } if (currentLambda < minLambda) { currentLambda = minLambda; } currentObjective = Residuals.CalcPenalty(dirtyImage) + ElasticNet.CalcPenalty(xImage, lambdaTrue, alpha); absMax = pcdm.GetAbsMax(xImage, bMap, lambdaTrue, alpha); if (absMax < MAJOR_STOP) { breakMajor = true; break; } lastResult = pcdm.Deconvolve(xImage, bMap, currentLambda, alpha, 100, 1e-5f); if (currentLambda == lambda | currentLambda == minLambda) { break; } var residualsUpdate = new float[xImage.GetLength(0), xImage.GetLength(1)]; Parallel.For(0, xCopy.GetLength(0), (i) => { for (int j = 0; j < xCopy.GetLength(1); j++) { residualsUpdate[i, j] = xImage[i, j] - xCopy[i, j]; } }); residualsConvolver.ConvolveInPlace(residualsUpdate); Parallel.For(0, xCopy.GetLength(0), (i) => { for (int j = 0; j < xCopy.GetLength(1); j++) { dirtyImage[i, j] = dirtyCopy[i, j] - residualsUpdate[i, j]; } }); } currentWatch.Stop(); totalWatch.Stop(); writer.WriteLine(cycle + ";" + currentLambda + ";" + currentObjective + ";" + absMax + ";" + lastResult.IterationCount + ";" + totalWatch.Elapsed.TotalSeconds + ";" + currentWatch.Elapsed.TotalSeconds); writer.Flush(); FitsIO.Write(xImage, folder + "/xImage_pcdm_" + cycle + ".fits"); if (breakMajor) { break; } if (currentLambda == lambda & !switchedToOtherPsf) { pcdm.ResetAMap(fullPsf); currentBMapCalculator = bMapCalculator2; lambda = lambdaTrue; switchedToOtherPsf = true; writer.WriteLine("switched"); writer.Flush(); } FFT.Shift(xImage); var xGrid = FFT.Forward(xImage); FFT.Shift(xImage); var modelVis = IDG.DeGridW(c, metadata, xGrid, input.UVW, input.Frequencies); residualVis = Visibilities.Substract(input.Visibilities, modelVis, input.Flags); } writer.Close(); } }
public static bool Deconvolve2(double[,] xImage, double[,] residuals, double[,] psf, double lambda, double alpha, int blockSize, int maxIteration = 100, double epsilon = 1e-4) { var xImage2 = ToFloatImage(xImage); var PSFConvolution = CommonDeprecated.PSF.CalcPaddedFourierConvolution(psf, residuals.GetLength(0), residuals.GetLength(1)); var PSFCorrelation = CommonDeprecated.PSF.CalculateFourierCorrelation(psf, residuals.GetLength(0), residuals.GetLength(1)); var PSFSquared = Fourier2D.Multiply(PSFConvolution, PSFCorrelation); var bMapCalculator = new PaddedConvolver(PSFCorrelation, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var resUpdateCalculator = new PaddedConvolver(PSFConvolution, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var bMapUpdateCalculator = new PaddedConvolver(PSFSquared, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var yBlockSize = blockSize; var xBlockSize = blockSize; var bMap = ToFloatImage(residuals); bMapCalculator.ConvolveInPlace(bMap); var xDiff = new float[xImage.GetLength(0), xImage.GetLength(1)]; var startL2 = NaiveGreedyCD.CalcDataObjective(residuals); var theta = 2; //theta, also number of processors. var degreeOfSep = RandomCD.CountNonZero(psf); var blockCount = xImage.Length / (yBlockSize * xBlockSize); var beta = 1.0 + (degreeOfSep - 1.0) * (theta - 1.0) / (Math.Max(1.0, (blockCount - 1))); //arises from E.S.O of theta-nice sampling. Look at the original PCDM Paper for the explanation //Theta-nice sampling: take theta number of random pixels var lipschitz = RandomBlockCD2.ApproximateLipschitz(psf, yBlockSize, xBlockSize); lipschitz *= beta; lambda = lambda / (yBlockSize * xBlockSize * beta); var iter = 0; while (iter < maxIteration) { bool containsNonZero = false; var maxBlocks = GetMaxBlocks(bMap, xImage2, lipschitz, (float)lambda, (float)alpha, yBlockSize, xBlockSize, theta); foreach (var b in maxBlocks) { var yBlock = b.Item1; var xBlock = b.Item2; var block = RandomBlockCD2.CopyFrom(bMap, yBlock, xBlock, yBlockSize, xBlockSize); var update = block / lipschitz; var xOld = RandomBlockCD2.CopyFrom(xImage2, yBlock, xBlock, yBlockSize, xBlockSize); var optimized = xOld + update; //shrink for (int j = 0; j < optimized.Count; j++) { optimized[j] = CommonDeprecated.ShrinkElasticNet(optimized[j], lambda, alpha); containsNonZero |= (optimized[j] - xOld[j]) != 0.0; } var optDiff = optimized - xOld; RandomBlockCD2.AddInto(xDiff, optDiff, yBlock, xBlock, yBlockSize, xBlockSize); RandomBlockCD2.AddInto(xImage2, optDiff, yBlock, xBlock, yBlockSize, xBlockSize); } if (containsNonZero) { //FitsIO.Write(xImage2, "xImageBlock.fits"); //FitsIO.Write(xDiff, "xDiff.fits"); //update b-map bMapUpdateCalculator.ConvolveInPlace(xDiff); //FitsIO.Write(xDiff, "bMapUpdate.fits"); for (int i = 0; i < xDiff.GetLength(0); i++) { for (int j = 0; j < xDiff.GetLength(1); j++) { bMap[i, j] -= xDiff[i, j]; xDiff[i, j] = 0; } } //FitsIO.Write(bMap, "bMap2.fits"); //calc residuals for debug purposes /*if (maxBlock.Item3 < epsilon) * break;*/ //Console.WriteLine(maxBlock.Item3 + "\t yB = " + yB + "\t xB =" + xB); } iter++; } var elasticNet = 0.0; for (int i = 0; i < xImage.GetLength(0); i++) { for (int j = 0; j < xImage.GetLength(1); j++) { xDiff[i, j] = xImage2[i, j] - (float)xImage[i, j]; xImage[i, j] = xImage2[i, j]; elasticNet += lambda * 2 * lipschitz * GreedyBlockCD.ElasticNetPenalty(xImage2[i, j], (float)alpha); } } resUpdateCalculator.ConvolveInPlace(xDiff); //FitsIO.Write(xDiff, "residualsUpdate.fits"); for (int i = 0; i < xDiff.GetLength(0); i++) { for (int j = 0; j < xDiff.GetLength(1); j++) { residuals[i, j] -= xDiff[i, j]; xDiff[i, j] = 0; } } var l2Penalty = NaiveGreedyCD.CalcDataObjective(residuals); Console.WriteLine("-------------------------"); Console.WriteLine((l2Penalty + elasticNet)); var io = System.IO.File.AppendText("penalty" + yBlockSize + ".txt"); io.WriteLine("l2: " + l2Penalty + "\telastic: " + elasticNet + "\t " + (l2Penalty + elasticNet)); io.Close(); Console.WriteLine("-------------------------"); return(false); }
/// <summary> /// Major cycle implementation for the Serial CD /// </summary> /// <param name="obsName"></param> /// <param name="data"></param> /// <param name="c"></param> /// <param name="useGPU"></param> /// <param name="psfCutFactor"></param> /// <param name="maxMajorCycle"></param> /// <param name="lambda"></param> /// <param name="alpha"></param> /// <param name="deconvIterations"></param> /// <param name="deconvEpsilon"></param> public static void ReconstructSerialCD(string obsName, MeasurementData data, GriddingConstants c, bool useGPU, int psfCutFactor, int maxMajorCycle, float lambda, float alpha, int deconvIterations, float deconvEpsilon) { var metadata = Partitioner.CreatePartition(c, data.UVW, data.Frequencies); var psfVis = new Complex[data.UVW.GetLength(0), data.UVW.GetLength(1), data.Frequencies.Length]; for (int i = 0; i < data.Visibilities.GetLength(0); i++) { for (int j = 0; j < data.Visibilities.GetLength(1); j++) { for (int k = 0; k < data.Visibilities.GetLength(2); k++) { if (!data.Flags[i, j, k]) { psfVis[i, j, k] = new Complex(1.0, 0); } else { psfVis[i, j, k] = new Complex(0, 0); } } } } Console.WriteLine("gridding psf"); var psfGrid = IDG.GridW(c, metadata, psfVis, data.UVW, data.Frequencies); var psf = FFT.WStackIFFTFloat(psfGrid, c.VisibilitiesCount); FFT.Shift(psf); var totalWatch = new Stopwatch(); var currentWatch = new Stopwatch(); var totalSize = new Rectangle(0, 0, c.GridSize, c.GridSize); var psfCut = PSF.Cut(psf, psfCutFactor); var maxSidelobe = PSF.CalcMaxSidelobe(psf, psfCutFactor); IDeconvolver deconvolver = null; if (useGPU & GPUSerialCD.IsGPUSupported()) { deconvolver = new GPUSerialCD(totalSize, psfCut, 1000); } else if (useGPU & !GPUSerialCD.IsGPUSupported()) { Console.WriteLine("GPU not supported by library. Switching to CPU implementation"); deconvolver = new FastSerialCD(totalSize, psfCut); } else { deconvolver = new FastSerialCD(totalSize, psfCut); } var psfBMap = psfCut; using (var gCalculator = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(psfBMap, totalSize), new Rectangle(0, 0, psfBMap.GetLength(0), psfBMap.GetLength(1)))) using (var gCalculator2 = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(psf, totalSize), new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1)))) { var currentGCalculator = gCalculator; var maxLipschitz = PSF.CalcMaxLipschitz(psfCut); var lambdaLipschitz = (float)(lambda * maxLipschitz); var lambdaTrue = (float)(lambda * PSF.CalcMaxLipschitz(psf)); var switchedToOtherPsf = false; var xImage = new float[c.GridSize, c.GridSize]; var residualVis = data.Visibilities; DeconvolutionResult lastResult = null; for (int cycle = 0; cycle < maxMajorCycle; cycle++) { Console.WriteLine("Beginning Major cycle " + cycle); var dirtyGrid = IDG.GridW(c, metadata, residualVis, data.UVW, data.Frequencies); var dirtyImage = FFT.WStackIFFTFloat(dirtyGrid, c.VisibilitiesCount); FFT.Shift(dirtyImage); FitsIO.Write(dirtyImage, obsName + "_dirty_serial_majorCycle" + cycle + ".fits"); currentWatch.Restart(); totalWatch.Start(); var maxDirty = Residuals.GetMax(dirtyImage); var gradients = gCalculator.Convolve(dirtyImage); var maxB = Residuals.GetMax(gradients); var correctionFactor = Math.Max(maxB / (maxDirty * maxLipschitz), 1.0f); var currentSideLobe = maxB * maxSidelobe * correctionFactor; var currentLambda = (float)Math.Max(currentSideLobe / alpha, lambdaLipschitz); var objective = Residuals.CalcPenalty(dirtyImage) + ElasticNet.CalcPenalty(xImage, lambdaTrue, alpha); var absMax = deconvolver.GetAbsMaxDiff(xImage, gradients, lambdaTrue, alpha); if (absMax >= MAJOR_EPSILON) { lastResult = deconvolver.Deconvolve(xImage, gradients, currentLambda, alpha, deconvIterations, deconvEpsilon); } if (lambda == currentLambda & !switchedToOtherPsf) { currentGCalculator = gCalculator2; lambda = lambdaTrue; maxLipschitz = PSF.CalcMaxLipschitz(psf); switchedToOtherPsf = true; } FitsIO.Write(xImage, obsName + "_model_serial_majorCycle" + cycle + ".fits"); currentWatch.Stop(); totalWatch.Stop(); if (absMax < MAJOR_EPSILON) { break; } FFT.Shift(xImage); var xGrid = FFT.Forward(xImage); FFT.Shift(xImage); var modelVis = IDG.DeGridW(c, metadata, xGrid, data.UVW, data.Frequencies); residualVis = Visibilities.Substract(data.Visibilities, modelVis, data.Flags); } Console.WriteLine("Reconstruction finished in (seconds): " + totalWatch.Elapsed.TotalSeconds); } }
/// <summary> /// Major cycle implemnentation for the parallel coordinate descent algorithm /// </summary> /// <param name="data"></param> /// <param name="c"></param> /// <param name="psfCutFactor"></param> /// <param name="maxMajorCycle"></param> /// <param name="maxMinorCycle"></param> /// <param name="lambda"></param> /// <param name="alpha"></param> /// <param name="deconvIterations"></param> /// <param name="deconvEpsilon"></param> public static void ReconstructPCDM(string obsName, MeasurementData data, GriddingConstants c, int psfCutFactor, int maxMajorCycle, int maxMinorCycle, float lambda, float alpha, int deconvIterations, float deconvEpsilon) { var metadata = Partitioner.CreatePartition(c, data.UVW, data.Frequencies); var psfVis = new Complex[data.UVW.GetLength(0), data.UVW.GetLength(1), data.Frequencies.Length]; for (int i = 0; i < data.Visibilities.GetLength(0); i++) { for (int j = 0; j < data.Visibilities.GetLength(1); j++) { for (int k = 0; k < data.Visibilities.GetLength(2); k++) { if (!data.Flags[i, j, k]) { psfVis[i, j, k] = new Complex(1.0, 0); } else { psfVis[i, j, k] = new Complex(0, 0); } } } } Console.WriteLine("gridding psf"); var psfGrid = IDG.Grid(c, metadata, psfVis, data.UVW, data.Frequencies); var psf = FFT.BackwardFloat(psfGrid, c.VisibilitiesCount); FFT.Shift(psf); var totalWatch = new Stopwatch(); var currentWatch = new Stopwatch(); var totalSize = new Rectangle(0, 0, c.GridSize, c.GridSize); var psfCut = PSF.Cut(psf, psfCutFactor); var maxSidelobe = PSF.CalcMaxSidelobe(psf, psfCutFactor); var sidelobeHalf = PSF.CalcMaxSidelobe(psf, 2); var pcdm = new ParallelCoordinateDescent(totalSize, psfCut, Environment.ProcessorCount, 1000); using (var gCalculator = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(psfCut, totalSize), new Rectangle(0, 0, psfCut.GetLength(0), psfCut.GetLength(1)))) using (var gCalculator2 = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(psf, totalSize), new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1)))) using (var residualsConvolver = new PaddedConvolver(totalSize, psf)) { var currentGCalculator = gCalculator; var maxLipschitz = PSF.CalcMaxLipschitz(psfCut); var lambdaLipschitz = (float)(lambda * maxLipschitz); var lambdaTrue = (float)(lambda * PSF.CalcMaxLipschitz(psf)); var switchedToOtherPsf = false; var xImage = new float[c.GridSize, c.GridSize]; var residualVis = data.Visibilities; ParallelCoordinateDescent.PCDMStatistics lastResult = null; for (int cycle = 0; cycle < maxMajorCycle; cycle++) { Console.WriteLine("Beginning Major cycle " + cycle); var dirtyGrid = IDG.GridW(c, metadata, residualVis, data.UVW, data.Frequencies); var dirtyImage = FFT.WStackIFFTFloat(dirtyGrid, c.VisibilitiesCount); FFT.Shift(dirtyImage); FitsIO.Write(dirtyImage, obsName + "_dirty_pcdm_majorCycle" + cycle + ".fits"); currentWatch.Restart(); totalWatch.Start(); var breakMajor = false; var minLambda = 0.0f; var dirtyCopy = Copy(dirtyImage); var xCopy = Copy(xImage); var currentLambda = 0f; var currentObjective = 0.0; var absMax = 0.0f; for (int minorCycle = 0; minorCycle < maxMinorCycle; minorCycle++) { Console.WriteLine("Beginning Minor Cycle " + minorCycle); var maxDirty = Residuals.GetMax(dirtyImage); var bMap = currentGCalculator.Convolve(dirtyImage); var maxB = Residuals.GetMax(bMap); var correctionFactor = Math.Max(maxB / (maxDirty * maxLipschitz), 1.0f); var currentSideLobe = maxB * maxSidelobe * correctionFactor; currentLambda = (float)Math.Max(currentSideLobe / alpha, lambdaLipschitz); if (minorCycle == 0) { minLambda = (float)(maxB * sidelobeHalf * correctionFactor / alpha); } if (currentLambda < minLambda) { currentLambda = minLambda; } currentObjective = Residuals.CalcPenalty(dirtyImage) + ElasticNet.CalcPenalty(xImage, lambdaTrue, alpha); absMax = pcdm.GetAbsMax(xImage, bMap, lambdaTrue, alpha); if (absMax < MAJOR_EPSILON) { breakMajor = true; break; } lastResult = pcdm.Deconvolve(xImage, bMap, currentLambda, alpha, 40, deconvEpsilon); if (currentLambda == lambda | currentLambda == minLambda) { break; } var residualsUpdate = new float[xImage.GetLength(0), xImage.GetLength(1)]; Parallel.For(0, xCopy.GetLength(0), (i) => { for (int j = 0; j < xCopy.GetLength(1); j++) { residualsUpdate[i, j] = xImage[i, j] - xCopy[i, j]; } }); residualsConvolver.ConvolveInPlace(residualsUpdate); Parallel.For(0, xCopy.GetLength(0), (i) => { for (int j = 0; j < xCopy.GetLength(1); j++) { dirtyImage[i, j] = dirtyCopy[i, j] - residualsUpdate[i, j]; } }); } currentWatch.Stop(); totalWatch.Stop(); if (breakMajor) { break; } if (currentLambda == lambda & !switchedToOtherPsf) { pcdm.ResetAMap(psf); currentGCalculator = gCalculator2; lambda = lambdaTrue; switchedToOtherPsf = true; } FitsIO.Write(xImage, obsName + "_model_pcdm_majorCycle" + cycle + ".fits"); FFT.Shift(xImage); var xGrid = FFT.Forward(xImage); FFT.Shift(xImage); var modelVis = IDG.DeGridW(c, metadata, xGrid, data.UVW, data.Frequencies); residualVis = Visibilities.Substract(data.Visibilities, modelVis, data.Flags); } Console.WriteLine("Reconstruction finished in (seconds): " + totalWatch.Elapsed.TotalSeconds); } }
public static bool Deconvolve2(double[,] xImage, double[,] residuals, double[,] psf, double lambda, double alpha, int blockSize, int maxIteration = 100, double epsilon = 1e-4) { var xImage2 = ToFloatImage(xImage); var PSFConvolution = CommonDeprecated.PSF.CalcPaddedFourierConvolution(psf, residuals.GetLength(0), residuals.GetLength(1)); var PSFCorrelation = CommonDeprecated.PSF.CalculateFourierCorrelation(psf, residuals.GetLength(0), residuals.GetLength(1)); var PSFSquared = Fourier2D.Multiply(PSFConvolution, PSFCorrelation); var bMapCalculator = new PaddedConvolver(PSFCorrelation, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var resUpdateCalculator = new PaddedConvolver(PSFConvolution, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var bMapUpdateCalculator = new PaddedConvolver(PSFSquared, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var yBlockSize = blockSize; var xBlockSize = blockSize; lambda = lambda / (yBlockSize * xBlockSize); var bMap = ToFloatImage(residuals); bMapCalculator.ConvolveInPlace(bMap); FitsIO.Write(bMap, "bmapFirst.fits"); var xDiff = new float[xImage.GetLength(0), xImage.GetLength(1)]; var lipschitz = ApproximateLipschitz(psf, yBlockSize, xBlockSize); var startL2 = NaiveGreedyCD.CalcDataObjective(residuals); var iter = 0; while (iter < maxIteration) { var maxBlock = GetMaxBlock(bMap, xImage2, lipschitz, (float)lambda, (float)alpha, yBlockSize, xBlockSize); var yB = maxBlock.Item1; var xB = maxBlock.Item2; //yB = 64 / yBlockSize; //xB = 64 / xBlockSize; var block = CopyFrom(bMap, yB, xB, yBlockSize, xBlockSize); //var optimized = block * blockInversion; var update = block / lipschitz; var xOld = CopyFrom(xImage2, yB, xB, yBlockSize, xBlockSize); var optimized = xOld + update; //shrink bool containsNonZero = false; for (int i = 0; i < optimized.Count; i++) { optimized[i] = CommonDeprecated.ShrinkElasticNet(optimized[i], lambda, alpha); containsNonZero |= (optimized[i] - xOld[i]) != 0.0; } var optDiff = optimized - xOld; if (containsNonZero) { AddInto(xDiff, optDiff, yB, xB, yBlockSize, xBlockSize); AddInto(xImage2, optDiff, yB, xB, yBlockSize, xBlockSize); //FitsIO.Write(xImage2, "xImageBlock.fits"); //FitsIO.Write(xDiff, "xDiff.fits"); //update b-map bMapUpdateCalculator.ConvolveInPlace(xDiff); //FitsIO.Write(xDiff, "bMapUpdate.fits"); for (int i = 0; i < xDiff.GetLength(0); i++) { for (int j = 0; j < xDiff.GetLength(1); j++) { bMap[i, j] -= xDiff[i, j]; xDiff[i, j] = 0; } } //FitsIO.Write(bMap, "bMap2.fits"); //calc residuals for debug purposes /*if (maxBlock.Item3 < epsilon) * break;*/ Console.WriteLine(maxBlock.Item3 + "\t yB = " + yB + "\t xB =" + xB); } iter++; } var elasticNet = 0.0; for (int i = 0; i < xImage.GetLength(0); i++) { for (int j = 0; j < xImage.GetLength(1); j++) { xDiff[i, j] = xImage2[i, j] - (float)xImage[i, j]; xImage[i, j] = xImage2[i, j]; elasticNet += lambda * 2 * lipschitz * ElasticNetPenalty(xImage2[i, j], (float)alpha); } } resUpdateCalculator.ConvolveInPlace(xDiff); //FitsIO.Write(xDiff, "residualsUpdate.fits"); for (int i = 0; i < xDiff.GetLength(0); i++) { for (int j = 0; j < xDiff.GetLength(1); j++) { residuals[i, j] -= xDiff[i, j]; xDiff[i, j] = 0; } } var l2Penalty = NaiveGreedyCD.CalcDataObjective(residuals); Console.WriteLine("-------------------------"); Console.WriteLine((l2Penalty + elasticNet)); var io = System.IO.File.AppendText("penalty" + yBlockSize + ".txt"); io.WriteLine("l2: " + l2Penalty + "\telastic: " + elasticNet + "\t " + (l2Penalty + elasticNet)); io.Close(); Console.WriteLine("-------------------------"); return(false); }
private static ReconstructionInfo Reconstruct(Data input, float fullLipschitz, float[,] maskedPsf, string folder, float maskFactor, int maxMajor, string dirtyPrefix, string xImagePrefix, StreamWriter writer, double objectiveCutoff, float epsilon, bool maskPsf2) { var info = new ReconstructionInfo(); var totalSize = new Rectangle(0, 0, input.c.GridSize, input.c.GridSize); var bMapCalculator = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(maskedPsf, totalSize), new Rectangle(0, 0, maskedPsf.GetLength(0), maskedPsf.GetLength(1))); var maskedPsf2 = PSF.CalcPSFSquared(maskedPsf); if (maskPsf2) { Mask(maskedPsf2, 1e-5f); } writer.WriteLine((CountNonZero(maskedPsf2) - maskedPsf2.Length) / (double)maskedPsf2.Length); var fastCD = new FastSerialCD(totalSize, totalSize, maskedPsf, maskedPsf2); FitsIO.Write(maskedPsf, folder + maskFactor + "psf.fits"); var lambda = 0.4f * fastCD.MaxLipschitz; var lambdaTrue = 0.4f * fullLipschitz; var alpha = 0.1f; var xImage = new float[input.c.GridSize, input.c.GridSize]; var residualVis = input.visibilities; DeconvolutionResult lastResult = null; for (int cycle = 0; cycle < maxMajor; cycle++) { Console.WriteLine("cycle " + cycle); var dirtyGrid = IDG.GridW(input.c, input.metadata, residualVis, input.uvw, input.frequencies); var dirtyImage = FFT.WStackIFFTFloat(dirtyGrid, input.c.VisibilitiesCount); FFT.Shift(dirtyImage); FitsIO.Write(dirtyImage, folder + dirtyPrefix + cycle + ".fits"); //calc data and reg penalty var dataPenalty = Residuals.CalcPenalty(dirtyImage); var regPenalty = ElasticNet.CalcPenalty(xImage, lambdaTrue, alpha); var regPenaltyCurrent = ElasticNet.CalcPenalty(xImage, lambda, alpha); info.lastDataPenalty = dataPenalty; info.lastRegPenalty = regPenalty; bMapCalculator.ConvolveInPlace(dirtyImage); //FitsIO.Write(dirtyImage, folder + dirtyPrefix + "bmap_" + cycle + ".fits"); var currentLambda = lambda; writer.Write(cycle + ";" + currentLambda + ";" + Residuals.GetMax(dirtyImage) + ";" + dataPenalty + ";" + regPenalty + ";" + regPenaltyCurrent + ";"); writer.Flush(); //check wether we can minimize the objective further with the current psf var objectiveReached = (dataPenalty + regPenalty) < objectiveCutoff; var minimumReached = (lastResult != null && lastResult.IterationCount < 100 && lastResult.Converged); if (!objectiveReached & !minimumReached) { info.totalDeconv.Start(); lastResult = fastCD.Deconvolve(xImage, dirtyImage, currentLambda, alpha, 50000, epsilon); info.totalDeconv.Stop(); FitsIO.Write(xImage, folder + xImagePrefix + cycle + ".fits"); writer.Write(lastResult.Converged + ";" + lastResult.IterationCount + ";" + lastResult.ElapsedTime.TotalSeconds + "\n"); writer.Flush(); FFT.Shift(xImage); var xGrid = FFT.Forward(xImage); FFT.Shift(xImage); var modelVis = IDG.DeGridW(input.c, input.metadata, xGrid, input.uvw, input.frequencies); residualVis = Visibilities.Substract(input.visibilities, modelVis, input.flags); } else { writer.Write(false + ";0;0"); writer.Flush(); break; } } return(info); }
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); }
public static bool Deconvolve2(double[,] xImage, double[,] residuals, double[,] psf, double lambda, double alpha, Random random, int maxIteration = 100, double epsilon = 1e-4) { var xImage2 = ToFloatImage(xImage); var PSFConvolution = CommonDeprecated.PSF.CalcPaddedFourierConvolution(psf, residuals.GetLength(0), residuals.GetLength(1)); var PSFCorrelation = CommonDeprecated.PSF.CalculateFourierCorrelation(psf, residuals.GetLength(0), residuals.GetLength(1)); var PSFSquared = Fourier2D.Multiply(PSFConvolution, PSFCorrelation); var bMapCalculator = new PaddedConvolver(PSFCorrelation, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var resUpdateCalculator = new PaddedConvolver(PSFConvolution, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var bMapUpdateCalculator = new PaddedConvolver(PSFSquared, new Rectangle(0, 0, psf.GetLength(0), psf.GetLength(1))); var yBlockSize = 2; var xBlockSize = 2; var bMap = ToFloatImage(residuals); bMapCalculator.ConvolveInPlace(bMap); FitsIO.Write(bMap, "bmapFirst.fits"); var xDiff = new float[xImage.GetLength(0), xImage.GetLength(1)]; var lipschitz = ApproximateLipschitz(psf, yBlockSize, xBlockSize); var startL2 = NaiveGreedyCD.CalcDataObjective(residuals); var iter = 0; while (iter < maxIteration) { var yB = random.Next(xImage.GetLength(0) / yBlockSize); var xB = random.Next(xImage.GetLength(1) / xBlockSize); //yB = 64 / yBlockSize; //xB = 64 / xBlockSize; var block = CopyFrom(bMap, yB, xB, yBlockSize, xBlockSize); //var optimized = block * blockInversion; var update = block / lipschitz; var xOld = CopyFrom(xImage2, yB, xB, yBlockSize, xBlockSize); var optimized = xOld + update; //shrink bool containsNonZero = false; for (int i = 0; i < optimized.Count; i++) { optimized[i] = CommonDeprecated.ShrinkElasticNet(optimized[i], lambda, alpha); containsNonZero |= (optimized[i] - xOld[i]) != 0.0; } var optDiff = optimized - xOld; if (containsNonZero) { AddInto(xDiff, optDiff, yB, xB, yBlockSize, xBlockSize); AddInto(xImage2, optDiff, yB, xB, yBlockSize, xBlockSize); //FitsIO.Write(xImage2, "xImageBlock.fits"); //FitsIO.Write(xDiff, "xDiff.fits"); //update b-map bMapUpdateCalculator.ConvolveInPlace(xDiff); //FitsIO.Write(xDiff, "bMapUpdate.fits"); for (int i = 0; i < xDiff.GetLength(0); i++) { for (int j = 0; j < xDiff.GetLength(1); j++) { bMap[i, j] -= xDiff[i, j]; xDiff[i, j] = 0; } } //FitsIO.Write(bMap, "bMap2.fits"); //calc residuals for debug purposes AddInto(xDiff, optDiff, yB, xB, yBlockSize, xBlockSize); resUpdateCalculator.ConvolveInPlace(xDiff); //FitsIO.Write(xDiff, "residualsUpdate.fits"); for (int i = 0; i < xDiff.GetLength(0); i++) { for (int j = 0; j < xDiff.GetLength(1); j++) { residuals[i, j] -= xDiff[i, j]; xDiff[i, j] = 0; } } //FitsIO.Write(residuals, "residuals2.fits"); var l2 = NaiveGreedyCD.CalcDataObjective(residuals); Console.WriteLine(l2); } iter++; } for (int i = 0; i < xImage.GetLength(0); i++) { for (int j = 0; j < xImage.GetLength(1); j++) { xImage[i, j] = xImage2[i, j]; } } return(false); }
private static void ReconstructSerial(MeasurementData input, GriddingConstants c, float[,] fullPsf, string folder, string file, int processorCount) { var totalWatch = new Stopwatch(); var currentWatch = new Stopwatch(); var totalSize = new Rectangle(0, 0, c.GridSize, c.GridSize); var psfCut = PSF.Cut(fullPsf, CUT_FACTOR_SERIAL); var maxSidelobe = PSF.CalcMaxSidelobe(fullPsf, CUT_FACTOR_SERIAL); var fastCD = new FastSerialCD(totalSize, psfCut, processorCount); var metadata = Partitioner.CreatePartition(c, input.UVW, input.Frequencies); var writer = new StreamWriter(folder + "/" + file + ".txt"); var psfBMap = psfCut; using (var bMapCalculator = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(psfBMap, totalSize), new Rectangle(0, 0, psfBMap.GetLength(0), psfBMap.GetLength(1)))) using (var bMapCalculator2 = new PaddedConvolver(PSF.CalcPaddedFourierCorrelation(fullPsf, totalSize), new Rectangle(0, 0, fullPsf.GetLength(0), fullPsf.GetLength(1)))) { var currentBMapCalculator = bMapCalculator; var maxLipschitz = PSF.CalcMaxLipschitz(psfCut); var lambda = (float)(LAMBDA * maxLipschitz); var lambdaTrue = (float)(LAMBDA * PSF.CalcMaxLipschitz(fullPsf)); var alpha = ALPHA; var switchedToOtherPsf = false; var xImage = new float[c.GridSize, c.GridSize]; var residualVis = input.Visibilities; DeconvolutionResult lastResult = null; for (int cycle = 0; cycle < 6; cycle++) { Console.WriteLine("cycle " + cycle); var dirtyGrid = IDG.GridW(c, metadata, residualVis, input.UVW, input.Frequencies); var dirtyImage = FFT.WStackIFFTFloat(dirtyGrid, c.VisibilitiesCount); FFT.Shift(dirtyImage); FitsIO.Write(dirtyImage, folder + "/dirty" + cycle + ".fits"); currentWatch.Restart(); totalWatch.Start(); var maxDirty = Residuals.GetMax(dirtyImage); var bMap = bMapCalculator.Convolve(dirtyImage); var maxB = Residuals.GetMax(bMap); var correctionFactor = Math.Max(maxB / (maxDirty * fastCD.MaxLipschitz), 1.0f); var currentSideLobe = maxB * maxSidelobe * correctionFactor; var currentLambda = Math.Max(currentSideLobe / alpha, lambda); var objective = Residuals.CalcPenalty(dirtyImage) + ElasticNet.CalcPenalty(xImage, lambdaTrue, alpha); var absMax = fastCD.GetAbsMaxDiff(xImage, bMap, lambdaTrue, alpha); if (absMax >= MAJOR_STOP) { lastResult = fastCD.Deconvolve(xImage, bMap, currentLambda, alpha, 30000, 1e-5f); } if (lambda == currentLambda & !switchedToOtherPsf) { currentBMapCalculator = bMapCalculator2; lambda = lambdaTrue; switchedToOtherPsf = true; } currentWatch.Stop(); totalWatch.Stop(); writer.WriteLine(cycle + ";" + currentLambda + ";" + objective + ";" + absMax + ";" + lastResult.IterationCount + ";" + totalWatch.Elapsed.TotalSeconds + ";" + currentWatch.Elapsed.TotalSeconds); writer.Flush(); if (absMax < MAJOR_STOP) { break; } FFT.Shift(xImage); var xGrid = FFT.Forward(xImage); FFT.Shift(xImage); var modelVis = IDG.DeGridW(c, metadata, xGrid, input.UVW, input.Frequencies); residualVis = Visibilities.Substract(input.Visibilities, modelVis, input.Flags); } } }