Beispiel #1
0
        /// <summary>
        /// Worker method.
        /// </summary>
        protected override void WorkerMethod()
        {
            string[] vtkFiles = Directory.GetFiles(m_inputDir, "*.vtk");
            if ((vtkFiles == null) || (vtkFiles.Length == 0))
            {
                return;
            }

            // Write the color parameters to a file
            string outputDir       = CreateOutputDir(m_inputDir);
            string colorParamsFile = Path.Combine(outputDir, "ColorParams.txt");

            File.WriteAllText(colorParamsFile, m_colorBuilder.GetLastSavedCode().Replace("\n", "\r\n"));

            string paramsFile = Path.Combine(m_inputDir, "Params.txt");

            if (File.Exists(paramsFile))
            {
                File.Copy(paramsFile, Path.Combine(outputDir, Path.GetFileName(paramsFile)));
            }

            WaveFunction.ColorDelegate colorFunc = (re, im, maxAmpl) => { return(m_colorBuilder.CalcColor(re, im, maxAmpl)); };
            if (colorFunc(1, 1, 1) == Color.Empty)
            {
                colorFunc = null;
            }

            m_numFilesToProcess = vtkFiles.Length;
            int chunkSize = Environment.ProcessorCount;

            for (int iStart = 0; iStart < m_numFilesToProcess; iStart += chunkSize)
            {
                int iEnd = Math.Min(iStart + chunkSize, m_numFilesToProcess);
                Parallel.For(iStart, iEnd, i =>
                {
                    // Re-color one file
                    string inputFile = vtkFiles[i];
                    WaveFunction wf  = WaveFunction.ReadFromVtkFile(inputFile);

                    string outFile = Path.Combine(outputDir, Path.GetFileName(inputFile));
                    wf.SaveToVtkFile(outFile, WaveFunction.WfSaveFormat.AMPLITUDE_AND_COLOR, colorFunc);
                });

                // Report progress to the caller
                m_currentFileIndex = iEnd - 1;
                ReportProgress();
                if (IsCancelled)
                {
                    return;
                }
            }
        }
Beispiel #2
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);
                                }
                            }
                        }
                    }
                }
            }
        }