public PageSelect()
        {
            InitializeComponent();

            this.Zoom           = 1.0;
            viewBox.DataContext = this;

            CommandBinding cb = new CommandBinding(ApplicationCommands.Open);

            cb.Executed += new ExecutedRoutedEventHandler(cb_Executed);
            this.CommandBindings.Add(cb);

            CommandBinding cb1 = new CommandBinding(NavigationCommands.Zoom);

            cb1.Executed += new ExecutedRoutedEventHandler(cb1_Executed);
            this.CommandBindings.Add(cb1);

            ImageF image = ImageF.RandomPixelImage(10, 10, 1);

            Psf     = PSF.SymmetricGaussian(0.5);
            Picture = new ImageFWrapper(image);

            theImage.Source = Picture.Bitmap;
            viewBox.Width   = theImage.Width;
            viewBox.Height  = theImage.Height;
        }
        private void viewBox_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Point pos = e.GetPosition(theImage);

            Psf = PSF.FromBitmap(Picture.Image, new System.Drawing.Point((int)pos.X, (int)pos.Y));
            imgPsfPreview.Source = ToBitmap(Psf.ToRawImage());
        }
        public GPUSerialCD(Rectangle totalSize, float[,] psf, float[,] psfSquared, int nrBatchIterations)
        {
            this.totalSize  = totalSize;
            psf2            = psfSquared;
            aMap            = PSF.CalcAMap(psf, totalSize);
            MaxLipschitz    = Residuals.GetMax(psfSquared);
            batchIterations = nrBatchIterations;

            c = new Context(ContextFlags.FastMath);
            var gpuIds = Accelerator.Accelerators.Where(id => id.AcceleratorType != AcceleratorType.CPU);

            if (gpuIds.Any())
            {
                RunsOnGPU   = true;
                accelerator = new CudaAccelerator(c, gpuIds.First().DeviceId);
            }
            else
            {
                Console.WriteLine("GPU vendor not supported. ILGPU switches to a !!!!VERY!!!! slow CPU implementation");
                RunsOnGPU   = false;
                accelerator = new CPUAccelerator(c, 4);
            }

            shrink  = accelerator.LoadAutoGroupedStreamKernel <Index2, ArrayView2D <float>, ArrayView2D <float>, ArrayView2D <float>, ArrayView <float>, ArrayView <Pixel> >(ShrinkKernel);
            updateX = accelerator.LoadAutoGroupedStreamKernel <ILGPU.Index, ArrayView2D <float>, ArrayView <Pixel> >(UpdateXKernel);
            updateB = accelerator.LoadAutoGroupedStreamKernel <Index2, ArrayView2D <float>, ArrayView2D <float>, ArrayView <Pixel> >(UpdateBKernel);
        }
 public MPIGreedyCD(Intracommunicator comm, Rectangle totalSize, Rectangle imageSection, float[,] psf)
 {
     this.comm         = comm;
     this.imageSection = imageSection;
     psf2 = PSF.CalcPSFSquared(psf);
     aMap = PSF.CalcAMap(psf, totalSize, imageSection);
 }
        public static void CalcESOs()
        {
            int gridSize = 3072;
            var psfCuts  = new int[] { 4, 8, 16, 32, 64 };
            var psf      = new float[gridSize, gridSize];

            var factor = 4;

            foreach (var cut in psfCuts)
            {
                var psfCut = PSF.Cut(psf, cut);
                var ESO    = CalcESO(8, psfCut.Length * factor, gridSize * gridSize);
            }

            Console.WriteLine("");
            Console.WriteLine("");
            Console.WriteLine("");
            var processors = new int[] { 1, 4, 8, 16, 32, 64 };

            var psfCut32 = PSF.Cut(psf, 32);

            foreach (var p in processors)
            {
                var ESO = CalcESO(p, psfCut32.Length * factor, gridSize * gridSize);
                Console.WriteLine(ESO);
            }
        }
        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();
        }
Example #7
0
        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 FastSerialCD(Rectangle totalSize, Rectangle patchSize, float[,] psf, float[,] psfSquared, int processorLimit = -1)
        {
            this.patch   = patchSize;
            psf2         = psfSquared;
            aMap         = PSF.CalcAMap(psf, totalSize, patchSize);
            MaxLipschitz = Residuals.GetMax(psfSquared);

            parallelOptions = new ParallelOptions();
            parallelOptions.MaxDegreeOfParallelism = processorLimit;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="totalSize"></param>
        /// <param name="psf"></param>
        /// <param name="processorCount">Number of async. processors to use</param>
        /// <param name="concurrentIterations">Number of async iterations each processor performs in one active set iteration</param>
        /// <param name="searchFraction"></param>
        public ParallelCoordinateDescent(Rectangle totalSize, float[,] psf, int processorCount = 8, int concurrentIterations = 1000, float searchFraction = 0.1f)
        {
            this.totalSize = totalSize;
            this.psf       = psf;
            this.psf2      = PSF.CalcPSFSquared(psf);
            this.aMap      = PSF.CalcAMap(psf, totalSize);

            this.processorCount       = processorCount;
            this.concurrentIterations = concurrentIterations;
            this.searchFraction       = searchFraction;
        }
        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 ApproxFast(Rectangle totalSize, float[,] psf, int threadCount, int blockSize, float randomFraction, float searchFraction, bool useCDColdStart, bool useAcceleration = true, bool useRestarting = true)
        {
            this.totalSize = totalSize;
            this.psf       = psf;
            this.psf2      = PSF.CalcPSFSquared(psf);
            MaxLipschitz   = (float)PSF.CalcMaxLipschitz(psf);
            this.aMap      = PSF.CalcAMap(psf, totalSize);

            this.threadCount     = threadCount;
            this.blockSize       = blockSize;
            this.randomFraction  = randomFraction;
            this.searchFraction  = searchFraction;
            this.useAcceleration = useAcceleration;
            this.useRestarting   = useRestarting;
        }
        public void ResetLipschitzMap(float[,] psf)
        {
            var psf2Local = PSF.CalcPSFSquared(psf);
            var maxFull   = Residuals.GetMax(psf2Local);

            MaxLipschitz = maxFull;
            aMap         = PSF.CalcAMap(psf, patch);

            var maxCut = Residuals.GetMax(psf2);

            for (int i = 0; i < psf2.GetLength(0); i++)
            {
                for (int j = 0; j < psf2.GetLength(1); j++)
                {
                    psf2[i, j] *= (maxFull / maxCut);
                }
            }
        }
        public void ResetAMap(float[,] psf)
        {
            var psf2Local = PSF.CalcPSFSquared(psf);
            var maxFull   = Residuals.GetMax(psf2Local);

            aMap     = PSF.CalcAMap(psf, totalSize);
            this.psf = psf;

            var maxCut = Residuals.GetMax(psf2);

            for (int i = 0; i < psf2.GetLength(0); i++)
            {
                for (int j = 0; j < psf2.GetLength(1); j++)
                {
                    psf2[i, j] *= (maxFull / maxCut);
                }
            }
        }
Example #14
0
        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];
                }
            }
        }
        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);
        }
Example #17
0
		public virtual void UpdateSavedataHashes(PSF psf, sbyte[] data, int size, sbyte[] @params, sbyte[] key)
		{
			// Setup the params, hash and mode.
			sbyte[] hash = new sbyte[0x10];

			// Determine the hashing mode.
			int mode = 0;
			int check_bit = 1;
			if (!isNullKey(key))
			{
				if (Emulator.Instance.FirmwareVersion > 271)
				{
					mode = 4;
				}
				else
				{
					mode = 2;
				}
			}

			// Check for previous SAVEDATA_PARAMS.
			if (@params != null)
			{
				for (int i = 0; i < @params.Length; i++)
				{
					if (@params[i] != 0)
					{
						// Extract the mode setup from the already existing data.
						mode = ((@params[0] >> 4) & 0xF);
						check_bit = ((@params[0]) & 0xF);
						break;
					}
				}
			}

			// New mode (after firmware 2.7.1).
			if ((mode & 0x4) == 0x4)
			{
				// Generate a type 6 hash.
				hash = GenerateSavedataHash(data, size, 6);
				Array.Copy(hash, 0, data, 0x11B0 + 0x20, 0x10);
				// Set the SAVEDATA_PARAMS byte to 0x41.
				data[0x11B0] |= 0x01;
				data[0x11B0] |= 0x40;
				// Generate a type 5 hash.
				hash = GenerateSavedataHash(data, size, 5);
				Array.Copy(hash, 0, data, 0x11B0 + 0x70, 0x10);
			}
			else if ((mode & 0x2) == 0x2)
			{ // Last old mode (firmware 2.0.0 to 2.7.1).
				// Generate a type 4 hash.
				hash = GenerateSavedataHash(data, size, 4);
				Array.Copy(hash, 0, data, 0x11B0 + 0x20, 0x10);
				// Set the SAVEDATA_PARAMS byte to 0x21.
				data[0x11B0] |= 0x01;
				data[0x11B0] |= 0x20;
				// Generate a type 3 hash.
				hash = GenerateSavedataHash(data, size, 3);
				Array.Copy(hash, 0, data, 0x11B0 + 0x70, 0x10);
			}
			else
			{ // First old mode (before firmware 2.0.0).
				// Generate a type 2 hash.
				hash = GenerateSavedataHash(data, size, 2);
				Array.Copy(hash, 0, data, 0x11B0 + 0x20, 0x10);
				// Set the SAVEDATA_PARAMS byte to 0x01.
				data[0x11B0] |= 0x01;
			}

			if ((check_bit & 0x1) == 0x1)
			{
				// Generate a type 1 hash.
				hash = GenerateSavedataHash(data, size, 1);
				Array.Copy(hash, 0, data, 0x11B0 + 0x10, 0x10);
			}

			// Output the sealed override PSF file containing the SAVEDATA_PARAMS and file hashes.
			try
			{
				// Update the SAVEDATA_PARAMS.
				sbyte[] savedataParams = new sbyte[0x80];
				for (int i = 0; i < 0x80; i++)
				{
					savedataParams[i] = data[0x11B0 + i];
				}
				psf.put("SAVEDATA_PARAMS", savedataParams);
			}
			catch (Exception)
			{
				// Ignore...
			}
		}
 public GPUSerialCD(Rectangle totalSize, float[,] psf, int nrBatchIterations) :
     this(totalSize, psf, PSF.CalcPSFSquared(psf), nrBatchIterations)
 {
 }
        public static float[,] Reconstruct(Intracommunicator comm, DistributedData.LocalDataset local, GriddingConstants c, int maxCycle, float lambda, float alpha, int iterPerCycle = 1000, bool usePathDeconvolution = false)
        {
            var watchTotal    = new Stopwatch();
            var watchForward  = new Stopwatch();
            var watchBackward = new Stopwatch();
            var watchDeconv   = new Stopwatch();

            watchTotal.Start();

            var metadata = Partitioner.CreatePartition(c, local.UVW, local.Frequencies);

            var patchSize = CalculateLocalImageSection(comm.Rank, comm.Size, c.GridSize, c.GridSize);
            var totalSize = new Rectangle(0, 0, c.GridSize, c.GridSize);

            //calculate psf and prepare for correlation in the Fourier space
            var psf = CalculatePSF(comm, c, metadata, local.UVW, local.Flags, local.Frequencies);

            Complex[,] PsfCorrelation = null;
            var maxSidelobe = PSF.CalcMaxSidelobe(psf);

            lambda = (float)(lambda * PSF.CalcMaxLipschitz(psf));

            StreamWriter writer = null;

            if (comm.Rank == 0)
            {
                FitsIO.Write(psf, "psf.fits");
                Console.WriteLine("done PSF gridding ");
                PsfCorrelation = PSF.CalcPaddedFourierCorrelation(psf, totalSize);
                writer         = new StreamWriter(comm.Size + "runtimestats.txt");
            }

            var deconvovler = new MPIGreedyCD(comm, totalSize, patchSize, psf);

            var residualVis = local.Visibilities;
            var xLocal      = new float[patchSize.YEnd - patchSize.Y, patchSize.XEnd - patchSize.X];


            for (int cycle = 0; cycle < maxCycle; cycle++)
            {
                if (comm.Rank == 0)
                {
                    Console.WriteLine("cycle " + cycle);
                }
                var dirtyImage = ForwardCalculateB(comm, c, metadata, residualVis, local.UVW, local.Frequencies, PsfCorrelation, psf, maxSidelobe, watchForward);

                var bLocal = GetImgSection(dirtyImage.Image, patchSize);

                MPIGreedyCD.Statistics lastRun;
                if (usePathDeconvolution)
                {
                    var currentLambda = Math.Max(1.0f / alpha * dirtyImage.MaxSidelobeLevel, lambda);
                    lastRun = deconvovler.DeconvolvePath(xLocal, bLocal, currentLambda, 4.0f, alpha, 5, iterPerCycle, 2e-5f);
                }
                else
                {
                    lastRun = deconvovler.Deconvolve(xLocal, bLocal, lambda, alpha, iterPerCycle, 1e-5f);
                }

                if (comm.Rank == 0)
                {
                    WriteToFile(cycle, lastRun, writer);
                    if (lastRun.Converged)
                    {
                        Console.WriteLine("-----------------------------CONVERGED!!!!------------------------");
                    }
                    else
                    {
                        Console.WriteLine("-------------------------------not converged----------------------");
                    }
                }
                comm.Barrier();
                if (comm.Rank == 0)
                {
                    watchDeconv.Stop();
                }

                float[][,] totalX = null;
                comm.Gather(xLocal, 0, ref totalX);
                Complex[,] modelGrid = null;
                if (comm.Rank == 0)
                {
                    watchBackward.Start();
                    var x = new float[c.GridSize, c.GridSize];
                    StitchImage(totalX, x, comm.Size);
                    FitsIO.Write(x, "xImage_" + cycle + ".fits");
                    FFT.Shift(x);
                    modelGrid = FFT.Forward(x);
                }
                comm.Broadcast(ref modelGrid, 0);

                var modelVis = IDG.DeGrid(c, metadata, modelGrid, local.UVW, local.Frequencies);
                residualVis = Visibilities.Substract(local.Visibilities, modelVis, local.Flags);
            }
            writer.Close();

            float[][,] gatherX = null;
            comm.Gather(xLocal, 0, ref gatherX);
            float[,] reconstructed = null;
            if (comm.Rank == 0)
            {
                reconstructed = new float[c.GridSize, c.GridSize];;
                StitchImage(gatherX, reconstructed, comm.Size);
            }

            return(reconstructed);
        }
 public PageDeconvolve(ImageFWrapper image, PSF psf) : this()
 {
     BaseImage   = image;
     Rc          = new RichardsonLucyDeconvolution(image.Image, psf);
     ResultImage = new ImageFWrapper(Rc.Sn);
 }
 public FastSerialCD(Rectangle totalSize, float[,] psf, int processorLimit = -1) :
     this(totalSize, totalSize, psf, PSF.CalcPSFSquared(psf), processorLimit)
 {
 }
Example #22
0
        public bool LoadRom(string path, CoreComm nextComm, bool forceAccurateCore = false,
                            int recursiveCount = 0) // forceAccurateCore is currently just for Quicknes vs Neshawk but could be used for other situations
        {
            if (recursiveCount > 1)                 // hack to stop recursive calls from endlessly rerunning if we can't load it
            {
                DoLoadErrorCallback("Failed multiple attempts to load ROM.", "");
                return(false);
            }

            bool cancel = false;

            if (path == null)
            {
                return(false);
            }

            using (var file = new HawkFile())
            {
                //only try mounting a file if a filename was given
                if (!string.IsNullOrEmpty(path))
                {
                    // lets not use this unless we need to
                    // file.NonArchiveExtensions = romExtensions;
                    file.Open(path);

                    // if the provided file doesnt even exist, give up!
                    if (!file.Exists)
                    {
                        return(false);
                    }
                }

                CanonicalFullPath = file.CanonicalFullPath;

                IEmulator nextEmulator = null;
                RomGame   rom          = null;
                GameInfo  game         = null;

                try
                {
                    string ext = null;

                    if (AsLibretro)
                    {
                        string codePathPart = Path.GetFileNameWithoutExtension(nextComm.LaunchLibretroCore);

                        var retro = new LibRetroEmulator(nextComm, nextComm.LaunchLibretroCore);
                        nextEmulator = retro;

                        //kind of dirty.. we need to stash this, and then we can unstash it in a moment, in case the core doesnt fail
                        var oldGame = Global.Game;

                        if (retro.Description.SupportsNoGame && string.IsNullOrEmpty(path))
                        {
                            //must be done before LoadNoGame (which triggers retro_init and the paths to be consumed by the core)
                            //game name == name of core
                            var gameName = codePathPart;
                            Global.Game = game = new GameInfo {
                                Name = gameName, System = "Libretro"
                            };

                            //if we are allowed to run NoGame and we dont have a game, boot up the core that way
                            bool ret = retro.LoadNoGame();

                            Global.Game = oldGame;

                            if (!ret)
                            {
                                DoLoadErrorCallback("LibretroNoGame failed to load. This is weird", "Libretro");
                                retro.Dispose();
                                return(false);
                            }
                        }
                        else
                        {
                            bool ret;

                            //must be done before LoadNoGame (which triggers retro_init and the paths to be consumed by the core)
                            //game name == name of core + extensionless_game_filename
                            var gameName = Path.Combine(codePathPart, Path.GetFileNameWithoutExtension(file.Name));
                            Global.Game = game = new GameInfo {
                                Name = gameName, System = "Libretro"
                            };

                            //if the core requires an archive file, then try passing the filename of the archive
                            //(but do we ever need to actually load the contents of the archive file into ram?)
                            if (retro.Description.NeedsArchives)
                            {
                                if (file.IsArchiveMember)
                                {
                                    throw new InvalidOperationException("Should not have bound file member for libretro block_extract core");
                                }
                                ret = retro.LoadPath(file.FullPathWithoutMember);
                            }
                            else
                            {
                                //otherwise load the data or pass the filename, as requested. but..
                                if (retro.Description.NeedsRomAsPath && file.IsArchiveMember)
                                {
                                    throw new InvalidOperationException("Cannot pass archive member to libretro needs_fullpath core");
                                }

                                if (retro.Description.NeedsRomAsPath)
                                {
                                    ret = retro.LoadPath(file.FullPathWithoutMember);
                                }
                                else
                                {
                                    ret = HandleArchiveBinding(file);
                                    if (ret)
                                    {
                                        ret = retro.LoadData(file.ReadAllBytes());
                                    }
                                }
                            }

                            Global.Game = oldGame;

                            if (!ret)
                            {
                                DoLoadErrorCallback("Libretro failed to load the given file. This is probably due to a core/content mismatch. Moreover, the process is now likely to be hosed. We suggest you restart the program.", "Libretro");
                                retro.Dispose();
                                return(false);
                            }
                        }
                    }
                    else
                    {
                        //if not libretro:

                        //do extension checknig
                        ext = file.Extension.ToLowerInvariant();

                        //do the archive binding we had to skip
                        if (!HandleArchiveBinding(file))
                        {
                            return(false);
                        }
                    }

                    if (string.IsNullOrEmpty(ext))
                    {
                    }
                    else if (ext == ".m3u")
                    {
                        //HACK ZONE - currently only psx supports m3u
                        M3U_File m3u;
                        using (var sr = new StreamReader(path))
                            m3u = M3U_File.Read(sr);
                        if (m3u.Entries.Count == 0)
                        {
                            throw new InvalidOperationException("Can't load an empty M3U");
                        }
                        //load discs for all the m3u
                        m3u.Rebase(Path.GetDirectoryName(path));
                        List <Disc>   discs     = new List <Disc>();
                        List <string> discNames = new List <string>();
                        StringWriter  sw        = new StringWriter();
                        foreach (var e in m3u.Entries)
                        {
                            Disc   disc     = null;
                            string discPath = e.Path;

                            //--- load the disc in a context which will let us abort if it's going to take too long
                            var discMountJob = new DiscMountJob {
                                IN_FromPath = discPath
                            };
                            discMountJob.IN_SlowLoadAbortThreshold = 8;
                            discMountJob.Run();
                            disc = discMountJob.OUT_Disc;

                            if (discMountJob.OUT_SlowLoadAborted)
                            {
                                DoLoadErrorCallback("This disc would take too long to load. Run it through discohawk first, or find a new rip because this one is probably junk", "", LoadErrorType.DiscError);
                                return(false);
                            }

                            if (discMountJob.OUT_ErrorLevel)
                            {
                                throw new InvalidOperationException("\r\n" + discMountJob.OUT_Log);
                            }

                            if (disc == null)
                            {
                                throw new InvalidOperationException("Can't load one of the files specified in the M3U");
                            }

                            var discName = Path.GetFileNameWithoutExtension(discPath);
                            discNames.Add(discName);
                            discs.Add(disc);

                            var discType = new DiscIdentifier(disc).DetectDiscType();
                            sw.WriteLine("{0}", Path.GetFileName(discPath));
                            if (discType == DiscType.SonyPSX)
                            {
                                string discHash = new DiscHasher(disc).Calculate_PSX_BizIDHash().ToString("X8");
                                game = Database.CheckDatabase(discHash);
                                if (game == null || game.IsRomStatusBad() || game.Status == RomStatus.NotInDatabase)
                                {
                                    sw.WriteLine("Disc could not be identified as known-good. Look for a better rip.");
                                }
                                else
                                {
                                    sw.WriteLine("Disc was identified (99.99% confidently) as known good with disc id hash CRC32:{0:X8}", discHash);
                                    sw.WriteLine("Nonetheless it could be an unrecognized romhack or patched version.");
                                    sw.WriteLine("According to redump.org, the ideal hash for entire disc is: CRC32:{0:X8}", game.GetStringValue("dh"));
                                    sw.WriteLine("The file you loaded hasn't been hashed entirely (it would take too long)");
                                    sw.WriteLine("Compare it with the full hash calculated by the PSX menu's Hash Discs tool");
                                }
                            }
                            else
                            {
                                sw.WriteLine("Not a PSX disc");
                            }
                            sw.WriteLine("-------------------------");
                        }

                        nextEmulator = new Octoshock(nextComm, discs, discNames, null, GetCoreSettings <Octoshock>(), GetCoreSyncSettings <Octoshock>());
                        nextEmulator.CoreComm.RomStatusDetails = sw.ToString();
                        game = new GameInfo {
                            Name = Path.GetFileNameWithoutExtension(file.Name)
                        };
                        game.System = "PSX";
                    }
                    else if (ext == ".iso" || ext == ".cue" || ext == ".ccd")
                    {
                        if (file.IsArchive)
                        {
                            throw new InvalidOperationException("Can't load CD files from archives!");
                        }

                        string discHash = null;

                        //--- load the disc in a context which will let us abort if it's going to take too long
                        var discMountJob = new DiscMountJob {
                            IN_FromPath = path
                        };
                        discMountJob.IN_SlowLoadAbortThreshold = 8;
                        discMountJob.Run();

                        if (discMountJob.OUT_SlowLoadAborted)
                        {
                            DoLoadErrorCallback("This disc would take too long to load. Run it through discohawk first, or find a new rip because this one is probably junk", "", LoadErrorType.DiscError);
                            return(false);
                        }

                        if (discMountJob.OUT_ErrorLevel)
                        {
                            throw new InvalidOperationException("\r\n" + discMountJob.OUT_Log);
                        }

                        var disc = discMountJob.OUT_Disc;
                        //-----------

                        //TODO - use more sophisticated IDer
                        var discType = new DiscIdentifier(disc).DetectDiscType();
                        if (discType == DiscType.SonyPSX)
                        {
                            discHash = new DiscHasher(disc).Calculate_PSX_BizIDHash().ToString("X8");
                        }
                        else
                        {
                            discHash = new DiscHasher(disc).OldHash();
                        }

                        game = Database.CheckDatabase(discHash);
                        if (game == null)
                        {
                            // try to use our wizard methods
                            game = new GameInfo {
                                Name = Path.GetFileNameWithoutExtension(file.Name), Hash = discHash
                            };

                            switch (new DiscIdentifier(disc).DetectDiscType())
                            {
                            case DiscType.SegaSaturn:
                                game.System = "SAT";
                                break;

                            case DiscType.SonyPSP:
                                game.System = "PSP";
                                break;

                            default:
                            case DiscType.SonyPSX:
                                game.System = "PSX";
                                break;

                            case DiscType.MegaCD:
                                game.System = "GEN";
                                break;

                            case DiscType.AudioDisc:
                            case DiscType.TurboCD:
                            case DiscType.UnknownCDFS:
                            case DiscType.UnknownFormat:
                                game.System = "PCECD";
                                break;
                            }
                        }

                        switch (game.System)
                        {
                        case "GEN":
                            var genesis = new GPGX(
                                nextComm, null, disc, GetCoreSettings <GPGX>(), GetCoreSyncSettings <GPGX>());
                            nextEmulator = genesis;
                            break;

                        case "SAT":
                            nextEmulator = new Yabause(nextComm, disc, GetCoreSyncSettings <Yabause>());
                            break;

                        case "PSP":
                            nextEmulator = new PSP(nextComm, file.Name);
                            break;

                        case "PSX":
                            nextEmulator = new Octoshock(nextComm, new List <Disc>(new[] { disc }), new List <string>(new[] { Path.GetFileNameWithoutExtension(path) }), null, GetCoreSettings <Octoshock>(), GetCoreSyncSettings <Octoshock>());
                            if (game.IsRomStatusBad() || game.Status == RomStatus.NotInDatabase)
                            {
                                nextEmulator.CoreComm.RomStatusDetails = "Disc could not be identified as known-good. Look for a better rip.";
                            }
                            else
                            {
                                StringWriter sw = new StringWriter();
                                sw.WriteLine("Disc was identified (99.99% confidently) as known good with disc id hash CRC32:{0:X8}", discHash);
                                sw.WriteLine("Nonetheless it could be an unrecognized romhack or patched version.");
                                sw.WriteLine("According to redump.org, the ideal hash for entire disc is: CRC32:{0:X8}", game.GetStringValue("dh"));
                                sw.WriteLine("The file you loaded hasn't been hashed entirely (it would take too long)");
                                sw.WriteLine("Compare it with the full hash calculated by the PSX menu's Hash Discs tool");
                                nextEmulator.CoreComm.RomStatusDetails = sw.ToString();
                            }
                            break;

                        case "PCE":
                        case "PCECD":
                            nextEmulator = new PCEngine(nextComm, game, disc, GetCoreSettings <PCEngine>(), GetCoreSyncSettings <PCEngine>());
                            break;
                        }
                    }
                    else if (file.Extension.ToLowerInvariant() == ".xml")
                    {
                        try
                        {
                            var xmlGame = XmlGame.Create(file);                             // if load fails, are we supposed to retry as a bsnes XML????????
                            game = xmlGame.GI;

                            switch (game.System)
                            {
                            case "GB":
                            case "DGB":
                                // adelikat: remove need for tags to be hardcoded to left and right, we should clean this up, also maybe the DGB core should just take the xml file and handle it itself
                                var leftBytes  = xmlGame.Assets.First().Value;
                                var rightBytes = xmlGame.Assets.Skip(1).First().Value;

                                var left  = Database.GetGameInfo(leftBytes, "left.gb");
                                var right = Database.GetGameInfo(rightBytes, "right.gb");
                                nextEmulator = new GambatteLink(
                                    nextComm,
                                    left,
                                    leftBytes,
                                    right,
                                    rightBytes,
                                    GetCoreSettings <GambatteLink>(),
                                    GetCoreSyncSettings <GambatteLink>(),
                                    Deterministic);

                                // other stuff todo
                                break;

                            case "AppleII":
                                var assets = xmlGame.Assets.Select(a => Database.GetGameInfo(a.Value, a.Key));
                                var roms   = xmlGame.Assets.Select(a => a.Value);
                                nextEmulator = new AppleII(
                                    nextComm,
                                    assets,
                                    roms,
                                    (AppleII.Settings)GetCoreSettings <AppleII>());
                                break;

                            case "C64":
                                nextEmulator = new C64(
                                    nextComm,
                                    xmlGame.Assets.Select(a => a.Value),
                                    (C64.C64Settings)GetCoreSettings <C64>(),
                                    (C64.C64SyncSettings)GetCoreSyncSettings <C64>()
                                    );
                                break;

                            case "PSX":
                                var entries   = xmlGame.AssetFullPaths;
                                var discs     = new List <Disc>();
                                var discNames = new List <string>();
                                var sw        = new StringWriter();
                                foreach (var e in entries)
                                {
                                    Disc   disc     = null;
                                    string discPath = e;

                                    //--- load the disc in a context which will let us abort if it's going to take too long
                                    var discMountJob = new DiscMountJob {
                                        IN_FromPath = discPath
                                    };
                                    discMountJob.IN_SlowLoadAbortThreshold = 8;
                                    discMountJob.Run();
                                    disc = discMountJob.OUT_Disc;

                                    if (discMountJob.OUT_SlowLoadAborted)
                                    {
                                        DoLoadErrorCallback("This disc would take too long to load. Run it through discohawk first, or find a new rip because this one is probably junk", "PSX", LoadErrorType.DiscError);
                                        return(false);
                                    }

                                    if (discMountJob.OUT_ErrorLevel)
                                    {
                                        throw new InvalidOperationException("\r\n" + discMountJob.OUT_Log);
                                    }

                                    if (disc == null)
                                    {
                                        throw new InvalidOperationException("Can't load one of the files specified in the M3U");
                                    }

                                    var discName = Path.GetFileNameWithoutExtension(discPath);
                                    discNames.Add(discName);
                                    discs.Add(disc);

                                    var discType = new DiscIdentifier(disc).DetectDiscType();
                                    sw.WriteLine("{0}", Path.GetFileName(discPath));
                                    if (discType == DiscType.SonyPSX)
                                    {
                                        string discHash = new DiscHasher(disc).Calculate_PSX_BizIDHash().ToString("X8");
                                        game = Database.CheckDatabase(discHash);
                                        if (game == null || game.IsRomStatusBad() || game.Status == RomStatus.NotInDatabase)
                                        {
                                            sw.WriteLine("Disc could not be identified as known-good. Look for a better rip.");
                                        }
                                        else
                                        {
                                            sw.WriteLine("Disc was identified (99.99% confidently) as known good with disc id hash CRC32:{0:X8}", discHash);
                                            sw.WriteLine("Nonetheless it could be an unrecognized romhack or patched version.");
                                            sw.WriteLine("According to redump.org, the ideal hash for entire disc is: CRC32:{0:X8}", game.GetStringValue("dh"));
                                            sw.WriteLine("The file you loaded hasn't been hashed entirely (it would take too long)");
                                            sw.WriteLine("Compare it with the full hash calculated by the PSX menu's Hash Discs tool");
                                        }
                                    }
                                    else
                                    {
                                        sw.WriteLine("Not a PSX disc");
                                    }
                                    sw.WriteLine("-------------------------");
                                }

                                // todo: copy pasta from PSX .cue section
                                nextEmulator = new Octoshock(nextComm, discs, discNames, null, GetCoreSettings <Octoshock>(), GetCoreSyncSettings <Octoshock>());
                                nextEmulator.CoreComm.RomStatusDetails = sw.ToString();
                                game = new GameInfo {
                                    Name = Path.GetFileNameWithoutExtension(file.Name)
                                };
                                game.System = "PSX";

                                break;

                            default:
                                return(false);
                            }
                        }
                        catch (Exception ex)
                        {
                            try
                            {
                                // need to get rid of this hack at some point
                                rom = new RomGame(file);
                                ((CoreFileProvider)nextComm.CoreFileProvider).SubfileDirectory = Path.GetDirectoryName(path.Replace("|", string.Empty));                                 // Dirty hack to get around archive filenames (since we are just getting the directory path, it is safe to mangle the filename
                                byte[] romData = null;
                                byte[] xmlData = rom.FileData;

                                game        = rom.GameInfo;
                                game.System = "SNES";

                                var snes = new LibsnesCore(game, romData, Deterministic, xmlData, nextComm, GetCoreSettings <LibsnesCore>(), GetCoreSyncSettings <LibsnesCore>());
                                nextEmulator = snes;
                            }
                            catch
                            {
                                DoLoadErrorCallback(ex.ToString(), "DGB", LoadErrorType.XML);
                                return(false);
                            }
                        }
                    }
                    else if (file.Extension.ToLowerInvariant() == ".psf" || file.Extension.ToLowerInvariant() == ".minipsf")
                    {
                        Func <Stream, int, byte[]> cbDeflater = (Stream instream, int size) =>
                        {
                            var          inflater = new ICSharpCode.SharpZipLib.Zip.Compression.Inflater(false);
                            var          iis      = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(instream, inflater);
                            MemoryStream ret      = new MemoryStream();
                            iis.CopyTo(ret);
                            return(ret.ToArray());
                        };
                        PSF psf = new PSF();
                        psf.Load(path, cbDeflater);
                        nextEmulator = new Octoshock(nextComm, psf, GetCoreSettings <Octoshock>(), GetCoreSyncSettings <Octoshock>());
                        nextEmulator.CoreComm.RomStatusDetails = "It's a PSF, what do you want. Oh, tags maybe?";

                        //total garbage, this
                        rom  = new RomGame(file);
                        game = rom.GameInfo;
                    }
                    else if (ext != null)                     // most extensions
                    {
                        rom = new RomGame(file);

                        //hacky for now
                        if (file.Extension.ToLowerInvariant() == ".exe")
                        {
                            rom.GameInfo.System = "PSX";
                        }
                        else if (file.Extension.ToLowerInvariant() == ".nsf")
                        {
                            rom.GameInfo.System = "NES";
                        }


                        if (string.IsNullOrEmpty(rom.GameInfo.System))
                        {
                            // Has the user picked a preference for this extension?
                            if (PreferredPlatformIsDefined(rom.Extension.ToLowerInvariant()))
                            {
                                rom.GameInfo.System = Global.Config.PreferredPlatformsForExtensions[rom.Extension.ToLowerInvariant()];
                            }
                            else if (ChoosePlatform != null)
                            {
                                var result = ChoosePlatform(rom);
                                if (!string.IsNullOrEmpty(result))
                                {
                                    rom.GameInfo.System = result;
                                }
                                else
                                {
                                    cancel = true;
                                }
                            }
                        }

                        game = rom.GameInfo;

                        var isXml = false;

                        // other xml has already been handled
                        if (file.Extension.ToLowerInvariant() == ".xml")
                        {
                            game.System = "SNES";
                            isXml       = true;
                        }


                        CoreInventory.Core core = null;

                        switch (game.System)
                        {
                        default:
                            core = CoreInventory.Instance[game.System];
                            break;

                        case null:
                            // The user picked nothing in the Core picker
                            break;

                        case "83P":
                            var ti83Bios     = ((CoreFileProvider)nextComm.CoreFileProvider).GetFirmware("TI83", "Rom", true);
                            var ti83BiosPath = ((CoreFileProvider)nextComm.CoreFileProvider).GetFirmwarePath("TI83", "Rom", true);
                            using (var ti83AsHawkFile = new HawkFile())
                            {
                                ti83AsHawkFile.Open(ti83BiosPath);
                                var ti83BiosAsRom = new RomGame(ti83AsHawkFile);
                                var ti83          = new TI83(nextComm, ti83BiosAsRom.GameInfo, ti83Bios, GetCoreSettings <TI83>());
                                ti83.LinkPort.SendFileToCalc(File.OpenRead(path), false);
                                nextEmulator = ti83;
                            }
                            break;

                        case "SNES":
                            if (Global.Config.SNES_InSnes9x && VersionInfo.DeveloperBuild)
                            {
                                core = CoreInventory.Instance["SNES", "Snes9x"];
                            }
                            else
                            {
                                // need to get rid of this hack at some point
                                ((CoreFileProvider)nextComm.CoreFileProvider).SubfileDirectory = Path.GetDirectoryName(path.Replace("|", String.Empty));                                         // Dirty hack to get around archive filenames (since we are just getting the directory path, it is safe to mangle the filename
                                var romData = isXml ? null : rom.FileData;
                                var xmlData = isXml ? rom.FileData : null;
                                var snes    = new LibsnesCore(game, romData, Deterministic, xmlData, nextComm, GetCoreSettings <LibsnesCore>(), GetCoreSyncSettings <LibsnesCore>());
                                nextEmulator = snes;
                            }

                            break;

                        case "NES":
                            if (!Global.Config.NES_InQuickNES || forceAccurateCore)
                            {
                                core = CoreInventory.Instance["NES", "NesHawk"];
                            }
                            else
                            {
                                core = CoreInventory.Instance["NES", "QuickNes"];
                            }

                            break;

                        case "GB":
                        case "GBC":
                            if (!Global.Config.GB_AsSGB)
                            {
                                core = CoreInventory.Instance["GB", "Gambatte"];
                            }
                            else
                            {
                                try
                                {
                                    game.System = "SNES";
                                    game.AddOption("SGB");
                                    var snes = new LibsnesCore(game, rom.FileData, Deterministic, null, nextComm, GetCoreSettings <LibsnesCore>(), GetCoreSyncSettings <LibsnesCore>());
                                    nextEmulator = snes;
                                }
                                catch
                                {
                                    // failed to load SGB bios or game does not support SGB mode.
                                    // To avoid catch-22, disable SGB mode
                                    Global.Config.GB_AsSGB = false;
                                    throw;
                                }
                            }

                            break;

                        case "A78":
                            var gamedbpath = Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "EMU7800.csv");
                            nextEmulator = new Atari7800(nextComm, game, rom.RomData, gamedbpath);
                            break;

                        case "C64":
                            var c64 = new C64(nextComm, Enumerable.Repeat(rom.RomData, 1), GetCoreSettings <C64>(), GetCoreSyncSettings <C64>());
                            nextEmulator = c64;
                            break;

                        case "GBA":
                            //core = CoreInventory.Instance["GBA", "Meteor"];
                            if (Global.Config.GBA_UsemGBA)
                            {
                                core = CoreInventory.Instance["GBA", "mGBA"];
                            }
                            else
                            {
                                core = CoreInventory.Instance["GBA", "VBA-Next"];
                            }
                            break;

                        case "PSX":
                            nextEmulator = new Octoshock(nextComm, null, null, rom.FileData, GetCoreSettings <Octoshock>(), GetCoreSyncSettings <Octoshock>());
                            nextEmulator.CoreComm.RomStatusDetails = "PSX etc.";
                            break;
                        }

                        if (core != null)
                        {
                            // use coreinventory
                            nextEmulator = core.Create(nextComm, game, rom.RomData, rom.FileData, Deterministic, GetCoreSettings(core.Type), GetCoreSyncSettings(core.Type));
                        }
                    }

                    if (nextEmulator == null)
                    {
                        if (!cancel)
                        {
                            DoLoadErrorCallback("No core could load the rom.", null);
                        }
                        return(false);
                    }
                }
                catch (Exception ex)
                {
                    string system = null;
                    if (game != null)
                    {
                        system = game.System;
                    }

                    // all of the specific exceptions we're trying to catch here aren't expected to have inner exceptions,
                    // so drill down in case we got a TargetInvocationException or something like that
                    while (ex.InnerException != null)
                    {
                        ex = ex.InnerException;
                    }

                    // Specific hack here, as we get more cores of the same system, this isn't scalable
                    if (ex is UnsupportedGameException)
                    {
                        if (system == "NES")
                        {
                            DoMessageCallback("Unable to use quicknes, using NESHawk instead");
                        }

                        return(LoadRom(path, nextComm, true, recursiveCount + 1));
                    }
                    else if (ex is MissingFirmwareException)
                    {
                        DoLoadErrorCallback(ex.Message, system, path, Deterministic, LoadErrorType.MissingFirmware);
                    }
                    else if (ex is CGBNotSupportedException)
                    {
                        // Note: GB as SGB was set to false by this point, otherwise we would want to do it here
                        DoMessageCallback("Failed to load a GB rom in SGB mode.  Disabling SGB Mode.");
                        return(LoadRom(path, nextComm, false, recursiveCount + 1));
                    }
                    else
                    {
                        DoLoadErrorCallback("A core accepted the rom, but threw an exception while loading it:\n\n" + ex, system);
                    }

                    return(false);
                }

                Rom            = rom;
                LoadedEmulator = nextEmulator;
                Game           = game;
                return(true);
            }
        }
        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);
        }
        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);
        }
        public static void RunApproximationMethods()
        {
            var folder     = @"C:\dev\GitHub\p9-data\large\fits\meerkat_tiny\";
            var data       = LMC.Load(folder);
            var rootFolder = Directory.GetCurrentDirectory();

            var maxW = 0.0;

            for (int i = 0; i < data.uvw.GetLength(0); i++)
            {
                for (int j = 0; j < data.uvw.GetLength(1); j++)
                {
                    maxW = Math.Max(maxW, Math.Abs(data.uvw[i, j, 2]));
                }
            }
            maxW = Partitioner.MetersToLambda(maxW, data.frequencies[data.frequencies.Length - 1]);

            var visCount2 = 0;

            for (int i = 0; i < data.flags.GetLength(0); i++)
            {
                for (int j = 0; j < data.flags.GetLength(1); j++)
                {
                    for (int k = 0; k < data.flags.GetLength(2); k++)
                    {
                        if (!data.flags[i, j, k])
                        {
                            visCount2++;
                        }
                    }
                }
            }
            var    visibilitiesCount = visCount2;
            int    gridSize          = 3072;
            int    subgridsize       = 32;
            int    kernelSize        = 16;
            int    max_nr_timesteps  = 1024;
            double cellSize          = 1.5 / 3600.0 * PI / 180.0;
            int    wLayerCount       = 24;
            double wStep             = maxW / (wLayerCount);

            data.c                 = new GriddingConstants(visibilitiesCount, gridSize, subgridsize, kernelSize, max_nr_timesteps, (float)cellSize, wLayerCount, wStep);
            data.metadata          = Partitioner.CreatePartition(data.c, data.uvw, data.frequencies);
            data.visibilitiesCount = visibilitiesCount;

            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(data.c, data.metadata, psfVis, data.uvw, data.frequencies);
            var psf     = FFT.WStackIFFTFloat(psfGrid, data.c.VisibilitiesCount);

            FFT.Shift(psf);

            Directory.CreateDirectory("PSFSizeExperimentLarge");
            Directory.SetCurrentDirectory("PSFSizeExperimentLarge");
            FitsIO.Write(psf, "psfFull.fits");

            Console.WriteLine(PSF.CalcMaxLipschitz(psf));
            Console.WriteLine(visCount2);

            //reconstruct with full psf and find reference objective value
            var fileHeader         = "cycle;lambda;sidelobe;maxPixel;dataPenalty;regPenalty;currentRegPenalty;converged;iterCount;ElapsedTime";
            var objectiveCutoff    = REFERENCE_L2_PENALTY + REFERENCE_ELASTIC_PENALTY;
            var recalculateFullPSF = true;

            if (recalculateFullPSF)
            {
                ReconstructionInfo referenceInfo = null;
                using (var writer = new StreamWriter("1Psf.txt", false))
                {
                    writer.WriteLine(fileHeader);
                    referenceInfo = ReconstructSimple(data, psf, "", 1, 12, "dirtyReference", "xReference", writer, 0.0, 1e-5f, false);
                    File.WriteAllText("1PsfTotal.txt", referenceInfo.totalDeconv.Elapsed.ToString());
                }
                objectiveCutoff = referenceInfo.lastDataPenalty + referenceInfo.lastRegPenalty;
            }

            //tryout with simply cutting the PSF
            ReconstructionInfo experimentInfo = null;
            var psfCuts   = new int[] { 16, 32 };
            var outFolder = "cutPsf";

            Directory.CreateDirectory(outFolder);
            outFolder += @"\";
            foreach (var cut in psfCuts)
            {
                using (var writer = new StreamWriter(outFolder + cut + "Psf.txt", false))
                {
                    writer.WriteLine(fileHeader);
                    experimentInfo = ReconstructSimple(data, psf, outFolder, cut, 12, cut + "dirty", cut + "x", writer, 0.0, 1e-5f, false);
                    File.WriteAllText(outFolder + cut + "PsfTotal.txt", experimentInfo.totalDeconv.Elapsed.ToString());
                }
            }

            //Tryout with cutting the PSF, but starting from the true bMap
            outFolder = "cutPsf2";
            Directory.CreateDirectory(outFolder);
            outFolder += @"\";
            foreach (var cut in psfCuts)
            {
                using (var writer = new StreamWriter(outFolder + cut + "Psf.txt", false))
                {
                    writer.WriteLine(fileHeader);
                    experimentInfo = ReconstructSimple(data, psf, outFolder, cut, 12, cut + "dirty", cut + "x", writer, 0.0, 1e-5f, true);
                    File.WriteAllText(outFolder + cut + "PsfTotal.txt", experimentInfo.totalDeconv.Elapsed.ToString());
                }
            }

            //combined, final solution. Cut the psf in half, optimize until convergence, and then do one more major cycle with the second method
            outFolder = "properSolution";
            Directory.CreateDirectory(outFolder);
            outFolder += @"\";
            foreach (var cut in psfCuts)
            {
                using (var writer = new StreamWriter(outFolder + cut + "Psf.txt", false))
                {
                    writer.WriteLine(fileHeader);
                    experimentInfo = ReconstructGradientApprox(data, psf, outFolder, cut, 12, cut + "dirty", cut + "x", writer, 0.0, 1e-5f);
                    File.WriteAllText(outFolder + cut + "PsfTotal.txt", experimentInfo.totalDeconv.Elapsed.ToString());
                }
            }

            Directory.SetCurrentDirectory(rootFolder);
        }
        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);
        }
        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();
        }
Example #29
0
        public static void GenerateCLEANExample(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);

            Directory.CreateDirectory(outputFolder);
            var reconstruction = new float[c.GridSize, c.GridSize];

            var residualVis = data.Visibilities;

            for (int cycle = 0; cycle < 10; 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);
                //FitsIO.Write(dirtyImage, Path.Combine(outputFolder, "dirty_CLEAN_" + cycle + ".fits"));
                Tools.WriteToMeltCSV(dirtyImage, Path.Combine(outputFolder, "dirty_CLEAN_" + cycle + ".csv"));

                var maxY = -1;
                var maxX = -1;
                var max  = 0.0f;
                for (int y = 0; y < dirtyImage.GetLength(0); y++)
                {
                    for (int x = 0; x < dirtyImage.GetLength(1); x++)
                    {
                        if (max < Math.Abs(dirtyImage[y, x]))
                        {
                            maxY = y;
                            maxX = x;
                            max  = Math.Abs(dirtyImage[y, x]);
                        }
                    }
                }

                //FitsIO.Write(reconstruction, Path.Combine(outputFolder, "model_CLEAN_" + cycle + ".fits"));
                Tools.WriteToMeltCSV(PSF.Cut(reconstruction), Path.Combine(outputFolder, "model_CLEAN_" + cycle + ".csv"));

                reconstruction[maxY, maxX] += 0.5f * dirtyImage[maxY, maxX];

                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);
            }

            var cleanbeam = new float[c.GridSize, c.GridSize];
            var x0        = c.GridSize / 2;
            var y0        = c.GridSize / 2;

            for (int y = 0; y < cleanbeam.GetLength(0); y++)
            {
                for (int x = 0; x < cleanbeam.GetLength(1); x++)
                {
                    cleanbeam[y, x] = (float)(1.0 * Math.Exp(-(Math.Pow(x0 - x, 2) / 16 + Math.Pow(y0 - y, 2) / 16)));
                }
            }

            FitsIO.Write(cleanbeam, Path.Combine(outputFolder, "clbeam.fits"));

            FFT.Shift(cleanbeam);
            var CL      = FFT.Forward(cleanbeam);
            var REC     = FFT.Forward(reconstruction);
            var CONF    = Common.Fourier2D.Multiply(REC, CL);
            var cleaned = FFT.BackwardFloat(CONF, reconstruction.Length);

            //FFT.Shift(cleaned);
            //FitsIO.Write(cleaned, Path.Combine(outputFolder, "rec_CLEAN.fits"));
            Tools.WriteToMeltCSV(PSF.Cut(cleaned), Path.Combine(outputFolder, "rec_CLEAN.csv"));
        }
Example #30
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"));
        }