private static void UpdateB(double[,] b, double[,] bUpdate, Common.Rectangle imageSection, int yPixel, int xPixel, double xDiff)
        {
            var yBHalf = bUpdate.GetLength(0) / 2;
            var xBHalf = bUpdate.GetLength(1) / 2;

            var yBMin = Math.Max(yPixel - yBHalf, imageSection.Y);
            var xBMin = Math.Max(xPixel - xBHalf, imageSection.X);
            var yBMax = Math.Min(yPixel - yBHalf + bUpdate.GetLength(0), imageSection.YEnd);
            var xBMax = Math.Min(xPixel - xBHalf + bUpdate.GetLength(1), imageSection.XEnd);

            for (int i = yBMin; i < yBMax; i++)
            {
                for (int j = xBMin; j < xBMax; j++)
                {
                    var yLocal   = i - imageSection.Y;
                    var xLocal   = j - imageSection.X;
                    var yBUpdate = i + yBHalf - yPixel;
                    var xBUpdate = j + xBHalf - xPixel;
                    b[yLocal, xLocal] += bUpdate[yBUpdate, xBUpdate] * xDiff;
                }
            }
        }
Ejemplo n.º 2
0
 public void Dirty(Common.Rectangle dr)
 {
     dobs.Dirty(dr);
 }
Ejemplo n.º 3
0
 public void Dirty(Common.Rectangle rect)
 {
     lock (lock_dirty)
         dirty.Add(rect);
 }
        public static bool Deconvolve(double[,] xImage, double[,] b, double[,] psf, double lambda, double alpha, int maxIteration = 100, double epsilon = 1e-4)
        {
            var yPsfHalf     = psf.GetLength(0) / 2;
            var xPsfHalf     = psf.GetLength(1) / 2;
            var aMap         = CommonDeprecated.PSF.CalcAMap(xImage, psf);
            var imageSection = new Common.Rectangle(0, 0, xImage.GetLength(0), xImage.GetLength(1));

            //invert the PSF, since we actually do want to correlate the psf with the residuals. (The FFT already inverts the psf, so we need to invert it again to not invert it. Trust me.)
            var psfTmp = new double[psf.GetLength(0) + +psf.GetLength(0), psf.GetLength(1) + psf.GetLength(1)];

            for (int y = 0; y < psf.GetLength(0); y++)
            {
                for (int x = 0; x < psf.GetLength(1); x++)
                {
                    psfTmp[y + yPsfHalf + 1, x + xPsfHalf + 1] = psf[psf.GetLength(0) - y - 1, psf.GetLength(1) - x - 1];
                }
            }
            FFT.Shift(psfTmp);
            var PsfCorr = FFT.Forward(psfTmp, 1.0);

            psfTmp = new double[psf.GetLength(0) + psf.GetLength(0), psf.GetLength(1) + psf.GetLength(1)];
            CommonDeprecated.PSF.SetPSFInWindow(psfTmp, xImage, psf, xImage.GetLength(0) / 2, xImage.GetLength(1) / 2);
            var tmp  = FFT.Forward(psfTmp, 1.0);
            var tmp2 = Common.Fourier2D.Multiply(tmp, PsfCorr);

            //cached bUpdate. When the PSF is not masked
            var bUpdateCache = FFT.Backward(tmp2, (double)(tmp2.GetLength(0) * tmp2.GetLength(1)));

            //masked psf
            var maskedPsf = new double[psf.GetLength(0) + +psf.GetLength(0), psf.GetLength(1) + psf.GetLength(1)];

            double[,] bUpdateMasked;

            int  iter      = 0;
            bool converged = false;
            var  watch     = new System.Diagnostics.Stopwatch();

            watch.Start();
            while (!converged & iter < maxIteration)
            {
                var yPixel = -1;
                var xPixel = -1;
                var xMax   = 0.0;
                var xNew   = 0.0;
                for (int y = 0; y < b.GetLength(0); y++)
                {
                    for (int x = 0; x < b.GetLength(1); x++)
                    {
                        var yLocal   = y;
                        var xLocal   = x;
                        var currentA = aMap[y, x];
                        var old      = xImage[yLocal, xLocal];
                        var xTmp     = old + b[y, x] / currentA;
                        xTmp = CommonDeprecated.ShrinkElasticNet(xTmp, lambda, alpha);
                        var xDiff = old - xTmp;

                        if (Math.Abs(xDiff) > xMax)
                        {
                            yPixel = y;
                            xPixel = x;
                            xMax   = Math.Abs(xDiff);
                            xNew   = xTmp;
                        }
                    }
                }

                converged = Math.Abs(xMax) < epsilon;
                if (!converged)
                {
                    var yLocal2 = yPixel;
                    var xLocal2 = xPixel;
                    var xOld    = xImage[yLocal2, xLocal2];
                    xImage[yLocal2, xLocal2] = xNew;

                    Console.WriteLine(iter + "\t" + (xNew - xOld) + "\t" + yLocal2 + "\t" + xLocal2);

                    if (yPixel - yPsfHalf >= 0 & yPixel + yPsfHalf < xImage.GetLength(0) & xPixel - xPsfHalf >= 0 & xPixel + xPsfHalf < xImage.GetLength(0))
                    {
                        UpdateB(b, bUpdateCache, imageSection, yPixel, xPixel, xOld - xNew);
                    }
                    else
                    {
                        /*CommonMethods.PSF.SetPSFInWindow(maskedPsf, xImage, psf, yPixel, xPixel);
                         * tmp = FFT.FFTDebug(maskedPsf, 1.0);
                         * tmp2 = Common.Fourier2D.Multiply(tmp, PsfCorr);
                         * bUpdateMasked = FFT.IFFTDebug(tmp2, tmp2.GetLength(0) * tmp2.GetLength(1));
                         * UpdateB(b, bUpdateMasked, imageSection, yPixel, xPixel, xOld - xNew);*/
                        UpdateB(b, bUpdateCache, imageSection, yPixel, xPixel, xOld - xNew);
                    }
                    iter++;

                    if (iter == 1000)
                    {
                        //FitsIO.Write(shrinked, "shrinkedReal.fits");
                        //FitsIO.Write(b, "candidatesGreedy2.fits");
                        //FitsIO.Write(xImage, "xImageGreedy2.fits");
                    }
                }
            }
            watch.Stop();
            Console.WriteLine(watch.Elapsed);
            return(converged);
        }
Ejemplo n.º 5
0
        public static bool Deconvolve(double[,] xImage, double[,] bMap, double[,] psf, double lambda, double alpha, int maxIteration = 100, double epsilon = 1e-4)
        {
            bool converged     = false;
            var  aMap          = CommonDeprecated.PSF.CalcAMap(xImage, psf);
            var  padding       = new Rectangle(0, 0, xImage.GetLength(0), xImage.GetLength(1));
            var  psfCorrelated = PSF.CalcPaddedFourierCorrelation(ToFloatImage(psf), padding);
            var  psf2          = Common.PSF.CalcPSFSquared(ToFloatImage(psf));
            var  xDiff         = new double[xImage.GetLength(0), xImage.GetLength(1)];
            var  imageSection  = new Common.Rectangle(0, 0, xImage.GetLength(0), xImage.GetLength(1));

            var rand        = new Random(33);
            var iter        = 0;
            var theta       = 1; //2; //theta, also number of processors.
            var degreeOfSep = CountNonZero(psf);
            var blockCount  = xImage.Length;
            var beta        = 1.0 + (degreeOfSep - 1) * (theta - 1) / (Math.Max(1.0, (blockCount - 1))); //arises from E.S.O of theta-nice sampling

            /*
             * Theta-nice sampling := take theta number of random pixels
             */

            var yPsfHalf = psf.GetLength(0) / 2;
            var xPsfHalf = psf.GetLength(1) / 2;
            var psfTmp   = new double[psf.GetLength(0) + +psf.GetLength(0), psf.GetLength(1) + psf.GetLength(1)];

            for (int y = 0; y < psf.GetLength(0); y++)
            {
                for (int x = 0; x < psf.GetLength(1); x++)
                {
                    psfTmp[y + yPsfHalf + 1, x + xPsfHalf + 1] = psf[psf.GetLength(0) - y - 1, psf.GetLength(1) - x - 1];
                }
            }
            FFT.Shift(psfTmp);
            var PsfCorr = FFT.Forward(psfTmp, 1.0);

            psfTmp = new double[psf.GetLength(0) + psf.GetLength(0), psf.GetLength(1) + psf.GetLength(1)];
            CommonDeprecated.PSF.SetPSFInWindow(psfTmp, xImage, psf, xImage.GetLength(0) / 2, xImage.GetLength(1) / 2);
            var tmp        = FFT.Forward(psfTmp, 1.0);
            var tmp2       = Common.Fourier2D.Multiply(tmp, PsfCorr);
            var pixelAcces = new double[xImage.GetLength(0), xImage.GetLength(1)];


            while (!converged & iter < maxIteration)
            {
                // create sampling
                var samples = CreateSamples(xImage.Length, theta, rand);
                for (int i = 0; i < samples.Length; i++)
                {
                    var yPixel = samples[i] / xImage.GetLength(1);
                    var xPixel = samples[i] % xImage.GetLength(1);

                    //update with E.S.O
                    //var xDiffPixel = 2.0 * bMap[y, x] / (beta * aMap[y, x]);

                    //update without E.S.O
                    var xDiffPixel = bMap[yPixel, xPixel] / (aMap[yPixel, xPixel]);

                    var old         = xImage[yPixel, xPixel];
                    var xDiffShrink = CommonDeprecated.ShrinkElasticNet(old + xDiffPixel, lambda, alpha);
                    xDiff[yPixel, xPixel]       = xDiffShrink;
                    pixelAcces[yPixel, xPixel] += 1;
                }

                //update B-map
                //reset xDiff
                for (int i = 0; i < samples.Length; i++)
                {
                    var yPixel = samples[i] / xImage.GetLength(1);
                    var xPixel = samples[i] % xImage.GetLength(1);

                    var bla = xDiff[yPixel, xPixel];
                    if (bla != 0.0)
                    {
                        if (yPixel - yPsfHalf >= 0 & yPixel + yPsfHalf < xImage.GetLength(0) & xPixel - xPsfHalf >= 0 & xPixel + xPsfHalf < xImage.GetLength(0))
                        {
                            UpdateB(bMap, psf2, imageSection, yPixel, xPixel, -xDiff[yPixel, xPixel]);
                        }
                        else
                        {
                            CommonDeprecated.PSF.SetPSFInWindow(psfTmp, xImage, psf, yPixel, xPixel);
                            tmp  = FFT.Forward(psfTmp, 1.0);
                            tmp2 = Common.Fourier2D.Multiply(tmp, PsfCorr);
                            var bUpdateMasked = FFT.Backward(tmp2, tmp2.GetLength(0) * tmp2.GetLength(1));
                            UpdateB(bMap, Common.ToFloatImage(bUpdateMasked), imageSection, yPixel, xPixel, -xDiff[yPixel, xPixel]);
                        }

                        xImage[yPixel, xPixel] += xDiff[yPixel, xPixel];
                        xDiff[yPixel, xPixel]   = 0;
                        Console.WriteLine("iter " + iter + " y " + yPixel + " x " + xPixel + " val " + bla);
                    }

                    Console.WriteLine("iter " + iter);
                }

                iter++;
            }

            FitsIO.Write(pixelAcces, "pixelAccess.fits");
            return(converged);
        }