コード例 #1
0
ファイル: FSC.cs プロジェクト: smart111/warp
        public static Image GetAnisotropicFSC(Image volume1,
                                              Image volume2,
                                              Image mask,
                                              float pixelsize,
                                              float threshold,
                                              int healpixOrder,
                                              float scaleToGlobalShell)
        {
            float MaskFraction = mask.GetHostContinuousCopy().Sum() / mask.ElementsReal;

            Image Masked1 = volume1.GetCopyGPU();

            volume1.FreeDevice();
            Masked1.Multiply(mask);
            Image Volume1FT = Masked1.AsFFT(true);

            Masked1.Dispose();

            Image Masked2 = volume2.GetCopyGPU();

            Masked2.Multiply(mask);
            volume2.FreeDevice();
            Image Volume2FT = Masked2.AsFFT(true);

            Masked2.Dispose();

            mask.FreeDevice();

            float2[] Angles     = Helper.GetHealpixRotTilt(healpixOrder, "C1", 91f);
            float3[] Directions = Angles.Select(a => Matrix3.Euler(a.X * Helper.ToRad, a.Y * Helper.ToRad, 0).Transposed() * float3.UnitZ).ToArray();

            float AngleSpacing = (float)(60.0 / Math.Pow(2, Math.Min(2, healpixOrder)));

            float[] ConeShells = new float[Directions.Length];

            CPU.ConicalFSC(Volume1FT.GetHostContinuousCopy(),
                           Volume2FT.GetHostContinuousCopy(),
                           volume1.Dims,
                           Helper.ToInterleaved(Directions),
                           Directions.Length,
                           AngleSpacing,
                           10,
                           threshold,
                           MaskFraction,
                           ConeShells);

            Volume1FT.Dispose();
            Volume2FT.Dispose();

            float MeanShell = MathHelper.MeanWeighted(ConeShells, MathHelper.Mult(ConeShells, ConeShells));

            ConeShells = ConeShells.Select(v => v / MeanShell * scaleToGlobalShell).ToArray();

            int   NRot     = (int)Math.Ceiling(360f / AngleSpacing * 2);
            float StepRot  = 360f / NRot;
            int   NTilt    = (int)Math.Ceiling(90f / AngleSpacing * 2);
            float StepTilt = 90f / NTilt;

            float[] PolarValues = new float[NRot * NTilt];

            for (int t = 0; t < NTilt; t++)
            {
                float Tilt = t * StepTilt;
                for (int r = 0; r < NRot; r++)
                {
                    float Rot = r * StepRot;

                    float3 Direction = Matrix3.Euler(Rot * Helper.ToRad, Tilt * Helper.ToRad, 0).Transposed() * float3.UnitZ;

                    float WeightedShell = 0;
                    float Weights       = 0;
                    for (int d = 0; d < Directions.Length; d++)
                    {
                        float AngleDiff = (float)Math.Acos(Math.Min(1, Math.Abs(float3.Dot(Directions[d], Direction)))) * Helper.ToDeg;
                        float Weight    = 1 - Math.Min(1, AngleDiff / AngleSpacing);
                        WeightedShell += ConeShells[d] * Weight;
                        Weights       += Weight;
                    }

                    PolarValues[t * NRot + r] = volume1.Dims.X * pixelsize / (WeightedShell / Weights);
                }
            }

            return(new Image(PolarValues, new int3(NRot, NTilt, 1)));
        }