예제 #1
0
        public static void StartLMCReconstruction()
        {
            var folder = Path.Combine(P9_DATA_FOLDER, "large/fits/meerkat_tiny/");
            var data   = MeasurementData.LoadLMC(folder);

            int    gridSize         = 3072;
            int    subgridsize      = 32;
            int    kernelSize       = 16;
            int    max_nr_timesteps = 1024;
            double cellSize         = 1.5 / 3600.0 * Math.PI / 180.0;
            int    wLayerCount      = 24;

            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]);
            double wStep = maxW / (wLayerCount);

            var griddingConstants = new GriddingConstants(data.VisibilitiesCount, gridSize, subgridsize, kernelSize, max_nr_timesteps, (float)cellSize, wLayerCount, wStep);

            var obsName        = "LMC";
            var lambda         = 1.0f;
            var alpha          = 0.01f;
            var epsilon        = 1e-5f;
            var maxMajorCycles = 5;

            MajorCycle.ReconstructSerialCD(obsName, data, griddingConstants, true, 16, maxMajorCycles, lambda, alpha, 30000, epsilon);
            MajorCycle.ReconstructPCDM(obsName, data, griddingConstants, 32, maxMajorCycles, 3, lambda, alpha, 30, epsilon);
        }
예제 #2
0
        private static void GenerateApproxRandomProblem(string outputFolder)
        {
            var folder = @"C:\dev\GitHub\p9-data\large\fits\meerkat_tiny\";

            Console.WriteLine("Generating approx random images");

            var    data             = MeasurementData.LoadLMC(folder);
            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;

            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]);
            double wStep = maxW / (wLayerCount);

            var c        = new GriddingConstants(data.VisibilitiesCount, gridSize, subgridsize, kernelSize, max_nr_timesteps, (float)cellSize, wLayerCount, wStep);
            var metadata = Partitioner.CreatePartition(c, data.UVW, data.Frequencies);

            var psfVis = new Complex[data.UVW.GetLength(0), data.UVW.GetLength(1), data.Frequencies.Length];

            for (int i = 0; i < data.Visibilities.GetLength(0); i++)
            {
                for (int j = 0; j < data.Visibilities.GetLength(1); j++)
                {
                    for (int k = 0; k < data.Visibilities.GetLength(2); k++)
                    {
                        if (!data.Flags[i, j, k])
                        {
                            psfVis[i, j, k] = new Complex(1.0, 0);
                        }
                        else
                        {
                            psfVis[i, j, k] = new Complex(0, 0);
                        }
                    }
                }
            }

            Console.WriteLine("gridding psf");
            var psfGrid = IDG.GridW(c, metadata, psfVis, data.UVW, data.Frequencies);
            var psf     = FFT.WStackIFFTFloat(psfGrid, c.VisibilitiesCount);

            FFT.Shift(psf);

            Directory.CreateDirectory(outputFolder);
            ReconstructRandom(data, c, psf, 1, 200, outputFolder + "/random__block1");
            ReconstructRandom(data, c, psf, 8, 50, outputFolder + "/random_10k_block8");
        }
        public static void RunSpeedLarge()
        {
            var folder = @"C:\dev\GitHub\p9-data\large\fits\meerkat_tiny\";

            var    data             = LMC.Load(folder);
            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;

            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++;
                        }
                    }
                }
            }
            double wStep = maxW / (wLayerCount);

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

            var psfVis = new Complex[data.uvw.GetLength(0), data.uvw.GetLength(1), data.frequencies.Length];

            for (int i = 0; i < data.visibilities.GetLength(0); i++)
            {
                for (int j = 0; j < data.visibilities.GetLength(1); j++)
                {
                    for (int k = 0; k < data.visibilities.GetLength(2); k++)
                    {
                        if (!data.flags[i, j, k])
                        {
                            psfVis[i, j, k] = new Complex(1.0, 0);
                        }
                        else
                        {
                            psfVis[i, j, k] = new Complex(0, 0);
                        }
                    }
                }
            }

            Console.WriteLine("gridding psf");
            var psfGrid = IDG.GridW(data.c, data.metadata, psfVis, data.uvw, data.frequencies);
            var psf     = FFT.WStackIFFTFloat(psfGrid, data.c.VisibilitiesCount);

            FFT.Shift(psf);

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


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

            outFolder += @"\";
            var fileHeader = "cycle;lambda;sidelobe;maxPixel;dataPenalty;regPenalty;currentRegPenalty;converged;iterCount;ElapsedTime";

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

            Directory.CreateDirectory("PSFSpeedExperimentApproxPSF");
            outFolder  = "PSFSpeedExperimentApproxPSF";
            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, 8, cut + "dirty", cut + "x", writer, 0.0, 1e-5f, true);
                    File.WriteAllText(outFolder + cut + "PsfTotal.txt", experimentInfo.totalDeconv.Elapsed.ToString());
                }
            }
        }
        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 static void Run()
        {
            var folder = @"C:\dev\GitHub\p9-data\large\fits\meerkat_tiny\";

            var    data             = MeasurementData.LoadLMC(folder);
            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;

            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]);
            double wStep = maxW / (wLayerCount);


            var c        = new GriddingConstants(data.VisibilitiesCount, gridSize, subgridsize, kernelSize, max_nr_timesteps, (float)cellSize, wLayerCount, wStep);
            var metadata = Partitioner.CreatePartition(c, data.UVW, data.Frequencies);

            var psfVis = new Complex[data.UVW.GetLength(0), data.UVW.GetLength(1), data.Frequencies.Length];

            for (int i = 0; i < data.Visibilities.GetLength(0); i++)
            {
                for (int j = 0; j < data.Visibilities.GetLength(1); j++)
                {
                    for (int k = 0; k < data.Visibilities.GetLength(2); k++)
                    {
                        if (!data.Flags[i, j, k])
                        {
                            psfVis[i, j, k] = new Complex(1.0, 0);
                        }
                        else
                        {
                            psfVis[i, j, k] = new Complex(0, 0);
                        }
                    }
                }
            }

            Console.WriteLine("gridding psf");
            var psfGrid = IDG.GridW(c, metadata, psfVis, data.UVW, data.Frequencies);
            var psf     = FFT.WStackIFFTFloat(psfGrid, c.VisibilitiesCount);

            FFT.Shift(psf);

            var outFolder = "ApproxExperiment";

            Directory.CreateDirectory(outFolder);
            FitsIO.Write(psf, Path.Combine(outFolder, "psfFull.fits"));

            //tryout with simply cutting the PSF
            RunPsfSize(data, c, psf, outFolder);
            //RunBlocksize(data, c, psf, outFolder);
            RunSearchPercent(data, c, psf, outFolder);
            //RunNotAccelerated(data, c, psf, outFolder);
        }
예제 #6
0
        public static void DebugdWStack()
        {
            var    frequencies  = FitsIO.ReadFrequencies(@"C:\dev\GitHub\p9-data\large\fits\meerkat_tiny\freq.fits");
            var    uvw          = FitsIO.ReadUVW(@"C:\dev\GitHub\p9-data\large\fits\meerkat_tiny\uvw0.fits");
            var    flags        = FitsIO.ReadFlags(@"C:\dev\GitHub\p9-data\large\fits\meerkat_tiny\flags0.fits", uvw.GetLength(0), uvw.GetLength(1), frequencies.Length);
            double norm         = 2.0;
            var    visibilities = FitsIO.ReadVisibilities(@"C:\dev\GitHub\p9-data\large\fits\meerkat_tiny\vis0.fits", uvw.GetLength(0), uvw.GetLength(1), frequencies.Length, norm);

            for (int i = 1; i < 8; i++)
            {
                var uvw0          = FitsIO.ReadUVW(@"C:\dev\GitHub\p9-data\large\fits\meerkat_tiny\uvw" + i + ".fits");
                var flags0        = FitsIO.ReadFlags(@"C:\dev\GitHub\p9-data\large\fits\meerkat_tiny\flags" + i + ".fits", uvw0.GetLength(0), uvw0.GetLength(1), frequencies.Length);
                var visibilities0 = FitsIO.ReadVisibilities(@"C:\dev\GitHub\p9-data\large\fits\meerkat_tiny\vis" + i + ".fits", uvw0.GetLength(0), uvw0.GetLength(1), frequencies.Length, norm);
                uvw          = FitsIO.Stitch(uvw, uvw0);
                flags        = FitsIO.Stitch(flags, flags0);
                visibilities = FitsIO.Stitch(visibilities, visibilities0);
            }

            var maxW = 0.0;

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

            var visCount2 = 0;

            for (int i = 0; i < flags.GetLength(0); i++)
            {
                for (int j = 0; j < flags.GetLength(1); j++)
                {
                    for (int k = 0; k < flags.GetLength(2); k++)
                    {
                        if (!flags[i, j, k])
                        {
                            visCount2++;
                        }
                    }
                }
            }
            var    visibilitiesCount = visCount2;
            int    gridSize          = 4096;
            int    subgridsize       = 16;
            int    kernelSize        = 8;
            int    max_nr_timesteps  = 1024;
            double cellSize          = 1.6 / 3600.0 * PI / 180.0;
            int    wLayerCount       = 32;
            double wStep             = maxW / (wLayerCount);
            var    c        = new GriddingConstants(visibilitiesCount, gridSize, subgridsize, kernelSize, max_nr_timesteps, (float)cellSize, wLayerCount, wStep);
            var    c2       = new GriddingConstants(visibilitiesCount, gridSize, subgridsize, kernelSize, max_nr_timesteps, (float)cellSize, 1, 0.0);
            var    metadata = Partitioner.CreatePartition(c, uvw, frequencies);

            var psfVis = new Complex[uvw.GetLength(0), uvw.GetLength(1), frequencies.Length];

            for (int i = 0; i < visibilities.GetLength(0); i++)
            {
                for (int j = 0; j < visibilities.GetLength(1); j++)
                {
                    for (int k = 0; k < visibilities.GetLength(2); k++)
                    {
                        if (!flags[i, j, k])
                        {
                            psfVis[i, j, k] = new Complex(1.0, 0);
                        }
                        else
                        {
                            psfVis[i, j, k] = new Complex(0, 0);
                        }
                    }
                }
            }

            var psfGrid = IDG.GridW(c, metadata, psfVis, uvw, frequencies);
            var psf     = FFT.WStackIFFTFloat(psfGrid, c.VisibilitiesCount);

            FFT.Shift(psf);

            FitsIO.Write(psf, "psfWStack.fits");

            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 fastCD         = new FastSerialCD(totalSize, psf);
            var lambda         = 0.4f * fastCD.MaxLipschitz;
            var alpha          = 0.1f;

            var xImage      = new float[gridSize, gridSize];
            var residualVis = visibilities;

            for (int cycle = 0; cycle < 8; cycle++)
            {
                var dirtyGrid = IDG.GridW(c, metadata, residualVis, uvw, frequencies);
                var dirty     = FFT.WStackIFFTFloat(dirtyGrid, c.VisibilitiesCount);
                FFT.Shift(dirty);

                FitsIO.Write(dirty, "dirty_" + cycle + ".fits");
                bMapCalculator.ConvolveInPlace(dirty);
                FitsIO.Write(dirty, "bMap_" + cycle + ".fits");
                var result = fastCD.Deconvolve(xImage, dirty, lambda, alpha, 10000, 1e-4f);

                FitsIO.Write(xImage, "xImageGreedy" + cycle + ".fits");

                FFT.Shift(xImage);
                var xGrid = FFT.Forward(xImage);
                FFT.Shift(xImage);
                var modelVis  = IDG.DeGridW(c, metadata, xGrid, uvw, frequencies);
                var modelGrid = IDG.GridW(c, metadata, modelVis, uvw, frequencies);
                var model     = FFT.WStackIFFTFloat(modelGrid, c.VisibilitiesCount);
                FFT.Shift(model);
                FitsIO.Write(model, "model_" + cycle + ".fits");
                residualVis = Visibilities.Substract(visibilities, modelVis, flags);
            }
        }
예제 #7
0
        public static void Run()
        {
            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          = 2048;
            int    subgridsize       = 32;
            int    kernelSize        = 16;
            int    max_nr_timesteps  = 1024;
            double cellSize          = 2.0 / 3600.0 * PI / 180.0;
            int    wLayerCount       = 32;
            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);
            var objectiveCutoff = REFERENCE_L2_PENALTY + REFERENCE_ELASTIC_PENALTY;
            var actualLipschitz = (float)PSF.CalcMaxLipschitz(psf);

            Console.WriteLine("Calc Histogram");
            var histPsf     = GetHistogram(psf, 256, 0.05f);
            var experiments = new float[] { 0.5f, /*0.4f, 0.2f, 0.1f, 0.05f*/ };

            Console.WriteLine("Done Histogram");

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

            //reconstruct with full psf and find reference objective value
            ReconstructionInfo experimentInfo = null;
            var outFolder  = "";
            var fileHeader = "cycle;lambda;sidelobe;dataPenalty;regPenalty;currentRegPenalty;converged;iterCount;ElapsedTime";

            foreach (var maskPercent in experiments)
            {
                using (var writer = new StreamWriter(outFolder + maskPercent + "Psf.txt", false))
                {
                    var maskedPSF    = Common.Copy(psf);
                    var maskedPixels = MaskPSF(maskedPSF, histPsf, maskPercent);
                    writer.WriteLine(maskedPixels + ";" + maskedPixels / (double)maskedPSF.Length);
                    FitsIO.Write(maskedPSF, outFolder + maskPercent + "Psf.fits");

                    writer.WriteLine(fileHeader);
                    writer.Flush();
                    experimentInfo = Reconstruct(data, actualLipschitz, maskedPSF, outFolder, 1, 10, maskPercent + "dirty", maskPercent + "x", writer, objectiveCutoff, 1e-5f, false);
                    File.WriteAllText(outFolder + maskPercent + "PsfTotal.txt", experimentInfo.totalDeconv.Elapsed.ToString());
                }
            }

            Directory.SetCurrentDirectory(rootFolder);
        }
        public static void RunProcessorComparison()
        {
            var folder = @"C:\dev\GitHub\p9-data\large\fits\meerkat_tiny\";

            var    data             = MeasurementData.LoadLMC(folder);
            int    gridSize         = 3072;
            int    subgridsize      = 32;
            int    kernelSize       = 16;
            int    max_nr_timesteps = 1024;
            double cellSize         = 1.5 / 3600.0 * Math.PI / 180.0;
            int    wLayerCount      = 24;

            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++;
                        }
                    }
                }
            }
            double wStep = maxW / (wLayerCount);

            var c        = new GriddingConstants(data.VisibilitiesCount, gridSize, subgridsize, kernelSize, max_nr_timesteps, (float)cellSize, wLayerCount, wStep);
            var metadata = Partitioner.CreatePartition(c, data.UVW, data.Frequencies);
            var psfVis   = new Complex[data.UVW.GetLength(0), data.UVW.GetLength(1), data.Frequencies.Length];

            for (int i = 0; i < data.Visibilities.GetLength(0); i++)
            {
                for (int j = 0; j < data.Visibilities.GetLength(1); j++)
                {
                    for (int k = 0; k < data.Visibilities.GetLength(2); k++)
                    {
                        if (!data.Flags[i, j, k])
                        {
                            psfVis[i, j, k] = new Complex(1.0, 0);
                        }
                        else
                        {
                            psfVis[i, j, k] = new Complex(0, 0);
                        }
                    }
                }
            }

            Console.WriteLine("gridding psf");
            var psfGrid = IDG.GridW(c, metadata, psfVis, data.UVW, data.Frequencies);
            var psf     = FFT.WStackIFFTFloat(psfGrid, c.VisibilitiesCount);

            FFT.Shift(psf);

            Directory.CreateDirectory("PCDMComparison/processors");
            var processorCount = new int[] { 1, 4, 8, 16, 32 };

            foreach (var count in processorCount)
            {
                ReconstructPCDM(data, c, psf, "PCDMComparison/processors", "pcdm" + count, 3, 0.1f, count);
                ReconstructSerial(data, c, psf, "PCDMComparison/processors", "serial" + count, count);
            }
        }