Ejemplo n.º 1
0
Archivo: FSC.cs Proyecto: smart111/warp
        public static float[] GetAmps1D(Image volume)
        {
            Image VolumeFT  = volume.IsComplex ? volume : volume.AsFFT(true);
            Image VolumeAbs = VolumeFT.AsAmplitudes();

            if (VolumeFT != volume)
            {
                VolumeFT.Dispose();
            }

            int NShells = volume.Dims.X / 2;

            float[] PS1D    = new float[NShells];
            float[] Samples = new float[NShells];

            float[] VolumeAbsData = VolumeAbs.GetHostContinuousCopy();

            int3 DimsFT = VolumeAbs.DimsFT;

            Parallel.For(0, 20, p =>
            {
                float[] ThreadPS1D    = new float[NShells];
                float[] ThreadSamples = new float[NShells];

                for (int z = p; z < DimsFT.Z; z += 20)
                {
                    int zz = z < DimsFT.Z / 2 + 1 ? z : z - DimsFT.Z;
                    zz    *= zz;

                    for (int y = 0; y < DimsFT.Y; y++)
                    {
                        int yy = y < DimsFT.Y / 2 + 1 ? y : y - DimsFT.Y;
                        yy    *= yy;

                        for (int x = 0; x < DimsFT.X; x++)
                        {
                            int xx = x;
                            xx    *= x;

                            float R = (float)Math.Sqrt(zz + yy + xx);
                            if (R >= NShells)
                            {
                                continue;
                            }

                            int ID   = (int)R;
                            float W1 = R - ID;
                            float W0 = 1f - W1;

                            int i = (z * DimsFT.Y + y) * DimsFT.X + x;

                            float Amp = VolumeAbsData[i];

                            ThreadPS1D[ID]    += W0 * Amp;
                            ThreadSamples[ID] += W0;

                            if (ID < NShells - 1)
                            {
                                ThreadPS1D[ID + 1]    += W1 * Amp;
                                ThreadSamples[ID + 1] += W1;
                            }
                        }
                    }
                }

                lock (PS1D)
                    for (int i = 0; i < PS1D.Length; i++)
                    {
                        PS1D[i]    += ThreadPS1D[i];
                        Samples[i] += ThreadSamples[i];
                    }
            });

            float[] Result = new float[NShells];

            for (int i = 0; i < Result.Length; i++)
            {
                Result[i] = PS1D[i] / Math.Max(1e-6f, Samples[i]);
            }

            return(Result);
        }