예제 #1
0
        /// <summary>
        /// Processes a single input file.
        /// </summary>
        private void ProcessFile(string inFile, string outFile, WaveFunction.ColorDelegate colorFunc)
        {
            unsafe
            {
                int    sx             = -1;
                int    sy             = -1;
                int    sz             = -1;
                string inFormat       = "";
                float  latticeSpacing = 0.0f;
                long   inDataStartPos = 0;
                string nl             = Environment.NewLine;

                float fa = 0.0f, fb = 0.0f;
                byte *fa0 = (byte *)(&fa);
                byte *fa1 = fa0 + 1;
                byte *fa2 = fa0 + 2;
                byte *fa3 = fa0 + 3;
                byte *fb0 = (byte *)(&fb);
                byte *fb1 = fb0 + 1;
                byte *fb2 = fb0 + 2;
                byte *fb3 = fb0 + 3;


                using (BinaryReader br = new BinaryReader(File.Open(inFile, FileMode.Open)))
                {
                    // Parse the header of the input file
                    while (br.BaseStream.Position < br.BaseStream.Length)
                    {
                        string textLine = WaveFunction.ReadTextLine(br);

                        if (textLine.StartsWith("Wavefunction3D"))
                        {
                            string[] comps = textLine.Split(null);
                            inFormat       = comps[1];
                            latticeSpacing = Single.Parse(comps[3]);
                        }
                        else if (textLine.StartsWith("DIMENSIONS"))
                        {
                            string[] comps = textLine.Split(null);
                            sx = Int32.Parse(comps[1]);
                            sy = Int32.Parse(comps[2]);
                            sz = Int32.Parse(comps[3]);
                        }
                        else if (textLine.StartsWith("LOOKUP_TABLE default"))
                        {
                            break;
                        }
                    }
                    // Bail out if the header was not what we expected
                    if (string.IsNullOrEmpty(inFormat) || (sx < 0) || (sy < 0) || (sz < 0))
                    {
                        throw new ArgumentException("Invalid Wavefunction file, in Colorer.ProcessFile.");
                    }
                    if (inFormat != "REAL_AND_IMAG")
                    {
                        throw new ArgumentException("Unsupported Wavefunction format, in Colorer.ProcessFile. " + "(" + inFormat + ")");
                    }
                    inDataStartPos = br.BaseStream.Position;



                    // Create output file
                    using (FileStream fileStream = File.Create(outFile))
                    {
                        using (BinaryWriter bw = new BinaryWriter(fileStream))
                        {
                            // Write the output header
                            string outFormat = (colorFunc == null) ? "AMPLITUDE_ONLY" : "AMPLITUDE_AND_COLOR";
                            bw.Write(Encoding.ASCII.GetBytes("# vtk DataFile Version 3.0" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("Wavefunction3D " + outFormat.ToString() + " " + "spacing: " + latticeSpacing.ToString() + nl));
                            bw.Write(Encoding.ASCII.GetBytes("BINARY" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("DATASET STRUCTURED_POINTS" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("DIMENSIONS " + sx + " " + sy + " " + sz + nl));
                            bw.Write(Encoding.ASCII.GetBytes("ORIGIN 0 0 0" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("SPACING 1 1 1" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("POINT_DATA " + sx * sy * sz + nl));
                            bw.Write(Encoding.ASCII.GetBytes("SCALARS amplitude float" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("LOOKUP_TABLE default" + nl));


                            // Read {re,im} pairs from the input file, and write the corresponding ampl values to the output file
                            // (Avoid reading-in the whole input file up-front, as it may be extremely large.)
                            byte[] outPlane = new byte[sx * sy * 4];
                            float  maxAmpl  = 0.0f;
                            for (int z = 0; z < sz; z++)
                            {
                                byte[] inPlane = br.ReadBytes(sx * sy * 8);
                                int    ni = 0, no = 0;;
                                for (int y = 0; y < sy; y++)
                                {
                                    for (int x = 0; x < sx; x++)
                                    {
                                        *fa3 = inPlane[ni];   // Reverse the byte order
                                        *fa2 = inPlane[ni + 1];
                                        *fa1 = inPlane[ni + 2];
                                        *fa0 = inPlane[ni + 3];

                                        *fb3 = inPlane[ni + 4];
                                        *fb2 = inPlane[ni + 5];
                                        *fb1 = inPlane[ni + 6];
                                        *fb0 = inPlane[ni + 7];
                                        ni  += 8;

                                        fa = (float)Math.Sqrt(fa * fa + fb * fb);
                                        if (fa > maxAmpl)
                                        {
                                            maxAmpl = fa;
                                        }
                                        outPlane[no]     = *fa3;
                                        outPlane[no + 1] = *fa2;
                                        outPlane[no + 2] = *fa1;
                                        outPlane[no + 3] = *fa0;
                                        no += 4;
                                    }
                                }
                                bw.Write(outPlane);
                            }


                            // Now write the colors
                            if (colorFunc != null)
                            {
                                bw.Write(Encoding.ASCII.GetBytes("SCALARS colors unsigned_char 3" + nl));
                                bw.Write(Encoding.ASCII.GetBytes("LOOKUP_TABLE default" + nl));
                                br.BaseStream.Seek(inDataStartPos, SeekOrigin.Begin);
                                byte[] colorPlane = new byte[sx * sy * 3];
                                for (int z = 0; z < sz; z++)
                                {
                                    byte[] inPlane = br.ReadBytes(sx * sy * 8);
                                    int    ni = 0, no = 0;;
                                    for (int y = 0; y < sy; y++)
                                    {
                                        for (int x = 0; x < sx; x++)
                                        {
                                            *fa3 = inPlane[ni];    // Real part
                                            *fa2 = inPlane[ni + 1];
                                            *fa1 = inPlane[ni + 2];
                                            *fa0 = inPlane[ni + 3];

                                            *fb3 = inPlane[ni + 4];  // Imaginary part
                                            *fb2 = inPlane[ni + 5];
                                            *fb1 = inPlane[ni + 6];
                                            *fb0 = inPlane[ni + 7];
                                            ni  += 8;

                                            Color color = (colorFunc == null) ? Color.Blue : colorFunc(fb, fa, maxAmpl);
                                            colorPlane[no]     = color.R;
                                            colorPlane[no + 1] = color.G;
                                            colorPlane[no + 2] = color.B;
                                            no += 3;
                                        }
                                    }
                                    bw.Write(colorPlane);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Processes a single input file.
        /// </summary>
        private void ProcessFile(string inFile, string outFile)
        {
            unsafe
            {
                int    sx = -1, sy = -1, sz = -1;
                string format         = "";
                float  latticeSpacing = 0.0f;
                string nl             = Environment.NewLine;

                float[] kernel = CreateGaussianKernel(m_smoothingFactor);
                int     sk     = kernel.Length;
                int     hsk    = (sk - 1) / 2;

                using (BinaryReader br = new BinaryReader(File.Open(inFile, FileMode.Open)))
                {
                    // Parse the header of the input file
                    while (br.BaseStream.Position < br.BaseStream.Length)
                    {
                        string textLine = WaveFunction.ReadTextLine(br);

                        if (textLine.StartsWith("Wavefunction3D"))
                        {
                            string[] comps = textLine.Split(null);
                            format         = comps[1];
                            latticeSpacing = Single.Parse(comps[3]);
                        }
                        else if (textLine.StartsWith("DIMENSIONS"))
                        {
                            string[] comps = textLine.Split(null);
                            sx = Int32.Parse(comps[1]);
                            sy = Int32.Parse(comps[2]);
                            sz = Int32.Parse(comps[3]);
                        }
                        else if (textLine.StartsWith("LOOKUP_TABLE default"))
                        {
                            break;
                        }
                    }
                    // Bail out if the header was not what we expected
                    if (string.IsNullOrEmpty(format) || (sx < 0) || (sy < 0) || (sz < 0))
                    {
                        throw new ArgumentException("Invalid Wavefunction file, in Colorer.ProcessFile.");
                    }
                    if (format != "REAL_AND_IMAG")
                    {
                        throw new ArgumentException("Unsupported Wavefunction format, in Smoother.ProcessFile. " + "(" + format + ")");
                    }

                    // Allocate some storage
                    float[][][] slab      = TdseUtils.Misc.Allocate3DArray(sk, sy, 2 * sx);
                    float[][]   outPlane  = TdseUtils.Misc.Allocate2DArray(sy, 2 * sx);
                    float[][]   workSpace = TdseUtils.Misc.Allocate2DArray(sy, 2 * sx);


                    // Create and open the output file
                    using (FileStream fileStream = File.Create(outFile))
                    {
                        using (BinaryWriter bw = new BinaryWriter(fileStream))
                        {
                            // Write the output header
                            bw.Write(Encoding.ASCII.GetBytes("# vtk DataFile Version 3.0" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("Wavefunction3D " + "REAL_AND_IMAG" + " " + "spacing: " + latticeSpacing.ToString() + nl));
                            bw.Write(Encoding.ASCII.GetBytes("BINARY" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("DATASET STRUCTURED_POINTS" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("DIMENSIONS " + sx + " " + sy + " " + sz + nl));
                            bw.Write(Encoding.ASCII.GetBytes("ORIGIN 0 0 0" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("SPACING 1 1 1" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("POINT_DATA " + sx * sy * sz + nl));
                            bw.Write(Encoding.ASCII.GetBytes("SCALARS wf float 2" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("LOOKUP_TABLE default" + nl));

                            // Read the initial few planes
                            for (int i = hsk; i < sk; i++)
                            {
                                GetNextXYPlane(br, kernel, workSpace, slab[i]);
                            }
                            for (int i = 0; i < hsk; i++)
                            {
                                TdseUtils.Misc.Copy2DArray(slab[sk - 1 - i], slab[i]); // Mirror boundary conditions on z
                            }
                            // Smooth along z, and write-out the result
                            SmoothAlongZ(slab, kernel, outPlane);
                            WriteXYPlane(bw, outPlane);


                            // Loop over remaining planes
                            for (int z = 1; z < sz; z++)
                            {
                                // Cycle the z-planes, and read-in a new one
                                float[][] temp = slab[0];
                                for (int i = 0; i < sk - 1; i++)
                                {
                                    slab[i] = slab[i + 1];
                                }
                                slab[sk - 1] = temp;
                                if (z < sz - hsk)
                                {
                                    GetNextXYPlane(br, kernel, workSpace, slab[sk - 1]);
                                }
                                else
                                {
                                    TdseUtils.Misc.Copy2DArray(slab[2 * (sz - 1 - z)], slab[sk - 1]); // Mirror boundary conditions on z
                                }

                                // Smooth along z, and write-out the result
                                SmoothAlongZ(slab, kernel, outPlane);
                                WriteXYPlane(bw, outPlane);
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Processes a single input file.
        /// </summary>
        private void ProcessFile(string inFile, string outFile)
        {
            unsafe
            {
                int    sx = -1, sy = -1, sz = -1;
                string format         = "";
                float  latticeSpacing = 0.0f;
                string nl             = Environment.NewLine;

                using (BinaryReader br = new BinaryReader(File.Open(inFile, FileMode.Open)))
                {
                    // Parse the header of the input file
                    while (br.BaseStream.Position < br.BaseStream.Length)
                    {
                        string textLine = WaveFunction.ReadTextLine(br);

                        if (textLine.StartsWith("Wavefunction3D"))
                        {
                            string[] comps = textLine.Split(null);
                            format         = comps[1];
                            latticeSpacing = (float)(Single.Parse(comps[3]) / m_upsampFactor);
                        }
                        else if (textLine.StartsWith("DIMENSIONS"))
                        {
                            string[] comps = textLine.Split(null);
                            sx = Int32.Parse(comps[1]);
                            sy = Int32.Parse(comps[2]);
                            sz = Int32.Parse(comps[3]);
                        }
                        else if (textLine.StartsWith("LOOKUP_TABLE default"))
                        {
                            break;
                        }
                    }
                    // Bail out if the header was not what we expected
                    if (string.IsNullOrEmpty(format) || (sx < 0) || (sy < 0) || (sz < 0))
                    {
                        throw new ArgumentException("Invalid Wavefunction file, in Colorer.ProcessFile.");
                    }
                    if (format != "REAL_AND_IMAG")
                    {
                        throw new ArgumentException("Unsupported Wavefunction format, in Smoother.ProcessFile. " + "(" + format + ")");
                    }

                    // Allocate some storage
                    int       sxu       = (int)Math.Max(1, sx * m_upsampFactor);
                    int       syu       = (int)Math.Max(1, sy * m_upsampFactor);
                    int       szu       = (int)Math.Max(1, sz * m_upsampFactor);
                    int       sxu2      = 2 * sxu;
                    float[][] workSpace = TdseUtils.Misc.Allocate2DArray(sy, 2 * sx);
                    float[][] outPlane  = TdseUtils.Misc.Allocate2DArray(syu, sxu2);

                    // Read the initial few xy planes
                    float[][][] iXYPlanes = new float[sz][][];
                    for (int zIn = 0; zIn < 4; zIn++)
                    {
                        iXYPlanes[zIn] = TdseUtils.Misc.Allocate2DArray(syu, sxu2);
                        GetNextXYPlane(br, iXYPlanes[zIn], workSpace, m_upsampFactor);
                    }

                    // Precalculate the z-weights and indices
                    int[]   zInm2, zInm1, zInp1, zInp2;
                    float[] wzm2, wzm1, wzp1, wzp2;
                    GetUpsampleArrays(sz, m_upsampFactor, out zInm2, out zInm1, out zInp1, out zInp2, out wzm2, out wzm1, out wzp1, out wzp2);


                    // Create and open the output file
                    using (FileStream fileStream = File.Create(outFile))
                    {
                        using (BinaryWriter bw = new BinaryWriter(fileStream))
                        {
                            // Write the output header
                            bw.Write(Encoding.ASCII.GetBytes("# vtk DataFile Version 3.0" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("Wavefunction3D " + "REAL_AND_IMAG" + " " + "spacing: " + latticeSpacing.ToString() + nl));
                            bw.Write(Encoding.ASCII.GetBytes("BINARY" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("DATASET STRUCTURED_POINTS" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("DIMENSIONS " + sxu + " " + syu + " " + szu + nl));
                            bw.Write(Encoding.ASCII.GetBytes("ORIGIN 0 0 0" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("SPACING 1 1 1" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("POINT_DATA " + sxu * syu * szu + nl));
                            bw.Write(Encoding.ASCII.GetBytes("SCALARS wf float 2" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("LOOKUP_TABLE default" + nl));


                            // Loop over the output z-planes
                            for (int zOut = 0; zOut < szu; zOut++)
                            {
                                // Cache z-weights and offsets
                                float Wzm2 = wzm2[zOut];
                                float Wzm1 = wzm1[zOut];
                                float Wzp1 = wzp1[zOut];
                                float Wzp2 = wzp2[zOut];

                                float[][] pixValsZInm2 = iXYPlanes[zInm2[zOut]];
                                float[][] pixValsZInm1 = iXYPlanes[zInm1[zOut]];
                                float[][] pixValsZInp1 = iXYPlanes[zInp1[zOut]];
                                float[][] pixValsZInp2 = iXYPlanes[zInp2[zOut]];
                                if (pixValsZInp2 == null)
                                {
                                    // Load (and upsample) the next xy plane
                                    float[][] temp = iXYPlanes[zInp2[zOut] - 4];
                                    iXYPlanes[zInp2[zOut] - 4] = null;
                                    GetNextXYPlane(br, temp, workSpace, m_upsampFactor);
                                    pixValsZInp2 = iXYPlanes[zInp2[zOut]] = temp;
                                }

                                for (int yOut = 0; yOut < syu; yOut++)
                                {
                                    float[] pixValsZInm2Y = pixValsZInm2[yOut];
                                    float[] pixValsZInm1Y = pixValsZInm1[yOut];
                                    float[] pixValsZInp1Y = pixValsZInp1[yOut];
                                    float[] pixValsZInp2Y = pixValsZInp2[yOut];
                                    float[] outPlaneY     = outPlane[yOut];

                                    for (int xOut = 0; xOut < sxu2; xOut++)
                                    {
                                        outPlaneY[xOut] = Wzm2 * pixValsZInm2Y[xOut] + Wzm1 * pixValsZInm1Y[xOut] + Wzp1 * pixValsZInp1Y[xOut] + Wzp2 * pixValsZInp2Y[xOut];
                                    }
                                }
                                WriteXYPlane(bw, outPlane);
                            }
                        }
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Processes a single input file.
        /// </summary>
        private void ProcessFile(string inFile, string outFile)
        {
            unsafe
            {
                int    sxIn = -1, syIn = -1, szIn = -1;
                int    sxOut = -1, syOut = -1, szOut = -1;
                string format         = "";
                float  latticeSpacing = 0.0f;
                string nl             = Environment.NewLine;

                using (BinaryReader br = new BinaryReader(File.Open(inFile, FileMode.Open)))
                {
                    // Parse the header of the input file
                    while (br.BaseStream.Position < br.BaseStream.Length)
                    {
                        string textLine = WaveFunction.ReadTextLine(br);

                        if (textLine.StartsWith("Wavefunction3D"))
                        {
                            string[] comps = textLine.Split(null);
                            format         = comps[1];
                            latticeSpacing = Single.Parse(comps[3]);
                        }
                        else if (textLine.StartsWith("DIMENSIONS"))
                        {
                            string[] comps = textLine.Split(null);
                            sxIn = Int32.Parse(comps[1]);
                            syIn = Int32.Parse(comps[2]);
                            szIn = Int32.Parse(comps[3]);
                        }
                        else if (textLine.StartsWith("LOOKUP_TABLE default"))
                        {
                            break;
                        }
                    }
                    // Bail out if the header was not what we expected
                    if (string.IsNullOrEmpty(format) || (sxIn < 0) || (syIn < 0) || (szIn < 0))
                    {
                        throw new ArgumentException("Invalid Wavefunction file, in Cropper.ProcessFile.");
                    }



                    // Create output file
                    sxOut = sxIn - m_xCrop1 - m_xCrop2;
                    syOut = syIn - m_yCrop1 - m_yCrop2;
                    szOut = szIn - m_zCrop1 - m_zCrop2;

                    using (FileStream fileStream = File.Create(outFile))
                    {
                        using (BinaryWriter bw = new BinaryWriter(fileStream))
                        {
                            // Write the output header
                            bw.Write(Encoding.ASCII.GetBytes("# vtk DataFile Version 3.0" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("Wavefunction3D " + format.ToString() + " " + "spacing: " + latticeSpacing.ToString() + nl));
                            bw.Write(Encoding.ASCII.GetBytes("BINARY" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("DATASET STRUCTURED_POINTS" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("DIMENSIONS " + sxOut + " " + syOut + " " + szOut + nl));
                            bw.Write(Encoding.ASCII.GetBytes("ORIGIN 0 0 0" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("SPACING 1 1 1" + nl));
                            bw.Write(Encoding.ASCII.GetBytes("POINT_DATA " + sxOut * syOut * szOut + nl));


                            // Read values from the input file, and write (some of) them to the output file.
                            // (Avoid reading-in the whole input file up-front, as it may be extremely large.)
                            if (format == "REAL_AND_IMAG")
                            {
                                bw.Write(Encoding.ASCII.GetBytes("SCALARS wf float 2" + nl));
                                bw.Write(Encoding.ASCII.GetBytes("LOOKUP_TABLE default" + nl));

                                byte[] outPlane = new byte[sxOut * syOut * 8];
                                for (int z = 0; z < szIn - m_zCrop2; z++)
                                {
                                    byte[] inPlane = br.ReadBytes(sxIn * syIn * 8);

                                    if (z < m_zCrop1)
                                    {
                                        continue;
                                    }

                                    for (int y = m_yCrop1; y < syIn - m_yCrop2; y++)
                                    {
                                        Buffer.BlockCopy(inPlane, (y * sxIn + m_xCrop1) * 8, outPlane, (y - m_yCrop1) * sxOut * 8, sxOut * 8);
                                    }
                                    bw.Write(outPlane);
                                }
                            }
                            else if ((format == "AMPLITUDE_ONLY") || (format == "AMPLITUDE_AND_COLOR"))
                            {
                                bw.Write(Encoding.ASCII.GetBytes("SCALARS amplitude float" + nl));
                                bw.Write(Encoding.ASCII.GetBytes("LOOKUP_TABLE default" + nl));

                                byte[] outPlane = new byte[sxOut * syOut * 4];
                                for (int z = 0; z < szIn; z++)
                                {
                                    byte[] inPlane = br.ReadBytes(sxIn * syIn * 4);

                                    if ((z < m_zCrop1) || (z > szIn - m_zCrop2 - 1))
                                    {
                                        continue;
                                    }

                                    for (int y = m_yCrop1; y < syIn - m_yCrop2; y++)
                                    {
                                        Buffer.BlockCopy(inPlane, (y * sxIn + m_xCrop1) * 4, outPlane, (y - m_yCrop1) * sxOut * 4, sxOut * 4);
                                    }
                                    bw.Write(outPlane);
                                }

                                if (format == "AMPLITUDE_AND_COLOR")
                                {
                                    bw.Write(Encoding.ASCII.GetBytes("SCALARS colors unsigned_char 3" + nl));
                                    bw.Write(Encoding.ASCII.GetBytes("LOOKUP_TABLE default" + nl));

                                    outPlane = new byte[sxOut * syOut * 3];
                                    for (int z = 0; z < szIn - m_zCrop2; z++)
                                    {
                                        byte[] inPlane = br.ReadBytes(sxIn * syIn * 3);

                                        if (z < m_zCrop1)
                                        {
                                            continue;
                                        }

                                        for (int y = m_yCrop1; y < syIn - m_yCrop2; y++)
                                        {
                                            Buffer.BlockCopy(inPlane, (y * sxIn + m_xCrop1) * 3, outPlane, (y - m_yCrop1) * sxOut * 3, sxOut * 3);
                                        }
                                        bw.Write(outPlane);
                                    }
                                }
                            }
                            else
                            {
                                throw new ArgumentException("Unsupported Wavefunction format, in Cropper.ProcessFile. " + "(" + format + ")");
                            }
                        }
                    }
                }
            }
        }