コード例 #1
0
ファイル: MainWindow.xaml.cs プロジェクト: dtegunov/warp
        private void ButtonStartProcessing_OnClick(object sender, RoutedEventArgs e)
        {
            if (!IsProcessing)
            {
                foreach (var item in DisableWhenRunning)
                    item.IsEnabled = false;

                ButtonStartProcessing.Content = "STOP PROCESSING";
                IsProcessing = true;

                Thread ProcessThread = new Thread(() =>
                {
                    int MaxDevices = 999;
                    int UsedDevices = Math.Min(MaxDevices, GPU.GetDeviceCount());

                    Image[] ImageGain = new Image[UsedDevices];
                    if (!string.IsNullOrEmpty(Options.GainPath) && Options.CorrectGain && File.Exists(Options.GainPath))
                        for (int d = 0; d < UsedDevices; d++)
                            try
                            {
                                GPU.SetDevice(d);
                                ImageGain[d] = StageDataLoad.LoadMap(Options.GainPath,
                                                                     new int2(MainWindow.Options.InputDatWidth, MainWindow.Options.InputDatHeight),
                                                                     MainWindow.Options.InputDatOffset,
                                                                     ImageFormatsHelper.StringToType(MainWindow.Options.InputDatType));
                            }
                            catch
                            {
                                return;
                            }

                    Image[] VolRefFT = new Image[UsedDevices], VolMaskFT = new Image[UsedDevices];
                    if ((Options.ProcessCTF && Options.ProcessParticleCTF) || (Options.ProcessMovement && Options.ProcessParticleShift))
                        if (File.Exists(Options.ReferencePath) && File.Exists(Options.MaskPath))
                        {
                            for (int d = 0; d < UsedDevices; d++)
                            {
                                GPU.SetDevice(d);
                                {
                                    Image Volume = StageDataLoad.LoadMap(Options.ReferencePath, new int2(1, 1), 0, typeof (float));
                                    Image VolumePadded = Volume.AsPadded(Volume.Dims * Options.ProjectionOversample);
                                    Volume.Dispose();
                                    VolumePadded.RemapToFT(true);
                                    VolRefFT[d] = VolumePadded.AsFFT(true);
                                    VolumePadded.Dispose();
                                }
                                {
                                    Image Volume = StageDataLoad.LoadMap(Options.MaskPath, new int2(1, 1), 0, typeof (float));
                                    Image VolumePadded = Volume.AsPadded(Volume.Dims * Options.ProjectionOversample);
                                    Volume.Dispose();
                                    VolumePadded.RemapToFT(true);
                                    VolMaskFT[d] = VolumePadded.AsFFT(true);
                                    VolumePadded.Dispose();
                                }
                            }
                        }

                    Star ParticlesStar = null;
                    if (File.Exists(Options.DataStarPath))
                        ParticlesStar = new Star(Options.DataStarPath);

                    Queue<DeviceToken> Devices = new Queue<DeviceToken>();
                    for (int d = 0; d < UsedDevices; d++)
                        Devices.Enqueue(new DeviceToken(d));
                    //for (int d = 0; d < UsedDevices; d++)
                    //    Devices.Enqueue(new DeviceToken(d));
                    int NTokens = Devices.Count;

                    DeviceToken[] IOSync = new DeviceToken[UsedDevices];
                    for (int d = 0; d < UsedDevices; d++)
                        IOSync[d] = new DeviceToken(d);

                    foreach (var Movie in Options.Movies)
                    {
                        if (!IsProcessing)
                            break;

                        if (Movie.Status != ProcessingStatus.Skip && Movie.Status != ProcessingStatus.Processed)
                        {
                            while (Devices.Count <= 0)
                                Thread.Sleep(20);

                            if (!IsProcessing)
                                break;

                            DeviceToken CurrentDevice;
                            lock (Devices)
                                CurrentDevice = Devices.Dequeue();

                            Thread DeviceThread = new Thread(() =>
                            {
                                GPU.SetDevice(CurrentDevice.ID);

                                MapHeader OriginalHeader = null;
                                Image OriginalStack = null;
                                decimal ScaleFactor = 1M / (decimal)Math.Pow(2, (double)Options.PostBinTimes);

                                lock (IOSync[CurrentDevice.ID])
                                    PrepareHeaderAndMap(Movie.Path, ImageGain[CurrentDevice.ID], ScaleFactor, out OriginalHeader, out OriginalStack);
                                /*OriginalHeader = MapHeader.ReadFromFile(Movie.Path,
                                                                    new int2(Options.InputDatWidth, Options.InputDatHeight),
                                                                    Options.InputDatOffset,
                                                                    ImageFormatsHelper.StringToType(Options.InputDatType));*/

                                //try
                                {
                                    if (Options.ProcessMovement)
                                    {
                                        if (!Options.ProcessParticleShift)
                                            Movie.ProcessShift(OriginalHeader, OriginalStack, ScaleFactor);
                                        else
                                            Movie.ProcessParticleShift(OriginalHeader,
                                                                       OriginalStack,
                                                                       ParticlesStar,
                                                                       VolRefFT[CurrentDevice.ID],
                                                                       VolMaskFT[CurrentDevice.ID],
                                                                       VolRefFT[CurrentDevice.ID].Dims.X / Options.ProjectionOversample,
                                                                       ScaleFactor);
                                    }
                                    if (Options.ProcessCTF)
                                    {
                                        if (!Options.ProcessParticleCTF)
                                            Movie.ProcessCTF(OriginalHeader, OriginalStack, true, ScaleFactor);
                                        else
                                            Movie.ProcessParticleCTF(OriginalHeader,
                                                                     OriginalStack,
                                                                     ParticlesStar,
                                                                     VolRefFT[CurrentDevice.ID],
                                                                     VolMaskFT[CurrentDevice.ID],
                                                                     VolRefFT[CurrentDevice.ID].Dims.X / Options.ProjectionOversample,
                                                                     ScaleFactor);
                                    }

                                    if (Options.PostAverage || Options.PostStack)
                                        Movie.CreateCorrected(OriginalHeader, OriginalStack);

                                    //Movie.PerformComparison(OriginalHeader, ParticlesStar, VolRefFT, VolMaskFT, ScaleFactor);

                                    //((TiltSeries)Movie).Reconstruct(OriginalStack, 128, 3.42f * 4 * 2, new int3(3712, 3712, 1400));

                                    //Image Reference = StageDataLoad.LoadMap("F:\\badaben\\ref.mrc", new int2(1, 1), 0, typeof(float));
                                    //((TiltSeries)Movie).Correlate(OriginalStack, Reference, 128, 80, 400, new int3(3712, 3712, 1400), 2, "C1");
                                    //Reference.Dispose();

                                    Movie.Status = ProcessingStatus.Processed;
                                }
                                /*catch
                                {
                                    Movie.Status = ProcessingStatus.Unprocessed;
                                }*/

                                OriginalStack?.Dispose();

                                lock (Devices)
                                    Devices.Enqueue(CurrentDevice);
                            });

                            DeviceThread.Start();
                        }
                    }

                    while (Devices.Count != NTokens)
                        Thread.Sleep(20);

                    //ParticlesStar.Save("F:\\rado27\\20S_defocused_dataset_part1\\warpmaps2\\run1_it017_data_everything.star");
                    //MoviesStar.Save("D:\\rado27\\Refine3D\\run1_ct5_data_movies.star");

                    for (int d = 0; d < UsedDevices; d++)
                    {
                        ImageGain[d]?.Dispose();
                        VolRefFT[d]?.Dispose();
                        VolMaskFT[d]?.Dispose();
                    }
                });
                ProcessThread.Start();
            }
            else
            {
                foreach (var item in DisableWhenRunning)
                    item.IsEnabled = true;

                ButtonStartProcessing.Content = "START PROCESSING";
                IsProcessing = false;
            }
        }
コード例 #2
0
ファイル: MainWindow.xaml.cs プロジェクト: dtegunov/warp
        private void ButtonExportParticles_OnClick(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.OpenFileDialog Dialog = new System.Windows.Forms.OpenFileDialog
            {
                Filter = "STAR Files|*.star",
                Multiselect = false
            };
            System.Windows.Forms.DialogResult Result = Dialog.ShowDialog();
            if (Result == System.Windows.Forms.DialogResult.OK)
            {
                System.Windows.Forms.SaveFileDialog SaveDialog = new System.Windows.Forms.SaveFileDialog
                {
                    Filter = "STAR Files|*.star"
                };
                System.Windows.Forms.DialogResult SaveResult = SaveDialog.ShowDialog();
                if (SaveResult == System.Windows.Forms.DialogResult.OK)
                {
                    Thread ProcessThread = new Thread(() =>
                    {
                        Star TableIn = new Star(Dialog.FileName);
                        //if (TableIn.GetColumn("rlnCtfImage") == null)
                        //    TableIn.AddColumn("rlnCtfImage");

                        string[] ColumnNames = TableIn.GetColumn("rlnMicrographName");

                        string[] Excluded = Options.Movies.Where(m => m.Status == ProcessingStatus.Skip).Select(m => m.RootName).ToArray();
                        List<int> ForDelete = new List<int>();
                        for (int r = 0; r < TableIn.RowCount; r++)
                            for (int ex = 0; ex < Excluded.Length; ex++)
                                if (ColumnNames[r].Contains(Excluded[ex]))
                                    ForDelete.Add(r);
                        TableIn.RemoveRows(ForDelete.ToArray());

                        ColumnNames = TableIn.GetColumn("rlnMicrographName");
                        string[] ColumnCoordsX = TableIn.GetColumn("rlnCoordinateX");
                        string[] ColumnCoordsY = TableIn.GetColumn("rlnCoordinateY");

                        Star TableOut = new Star(TableIn.GetColumnNames());

                        int MaxDevices = 999;
                        int UsedDevices = Math.Min(MaxDevices, GPU.GetDeviceCount());

                        Queue<DeviceToken> Devices = new Queue<DeviceToken>();
                        for (int d = 0; d < UsedDevices; d++)
                            Devices.Enqueue(new DeviceToken(d));
                        //for (int d = 0; d < UsedDevices; d++)
                        //    Devices.Enqueue(new DeviceToken(d));
                        int NTokens = Devices.Count;

                        DeviceToken[] IOSync = new DeviceToken[UsedDevices];
                        for (int d = 0; d < UsedDevices; d++)
                            IOSync[d] = new DeviceToken(d);

                        Image[] ImageGain = new Image[UsedDevices];
                        if (!string.IsNullOrEmpty(Options.GainPath) && Options.CorrectGain && File.Exists(Options.GainPath))
                            for (int d = 0; d < UsedDevices; d++)
                                try
                                {
                                    GPU.SetDevice(d);
                                    ImageGain[d] = StageDataLoad.LoadMap(Options.GainPath,
                                                                         new int2(MainWindow.Options.InputDatWidth, MainWindow.Options.InputDatHeight),
                                                                         MainWindow.Options.InputDatOffset,
                                                                         ImageFormatsHelper.StringToType(MainWindow.Options.InputDatType));
                                }
                                catch
                                {
                                    return;
                                }

                        //Dictionary<int, Projector>[] DeviceReferences = new Dictionary<int, Projector>[GPU.GetDeviceCount()];
                        //Dictionary<int, Projector>[] DeviceReconstructions = new Dictionary<int, Projector>[GPU.GetDeviceCount()];
                        //Dictionary<int, Projector>[] DeviceCTFReconstructions = new Dictionary<int, Projector>[GPU.GetDeviceCount()];
                        //for (int d = 0; d < GPU.GetDeviceCount(); d++)
                        //{
                        //    GPU.SetDevice(d);

                        //    Dictionary<int, Projector> References = new Dictionary<int, Projector>();
                        //    {
                        //        Image Ref1 = StageDataLoad.LoadMap("F:\\badaben\\vlion123\\warp_ref1.mrc", new int2(1, 1), 0, typeof(float));
                        //        Image Ref2 = StageDataLoad.LoadMap("F:\\badaben\\vlion123\\warp_ref2.mrc", new int2(1, 1), 0, typeof(float));
                        //        Image Ref3 = StageDataLoad.LoadMap("F:\\badaben\\vlion123\\warp_ref3.mrc", new int2(1, 1), 0, typeof(float));
                        //        Image Ref4 = StageDataLoad.LoadMap("F:\\badaben\\vlion123\\warp_ref4.mrc", new int2(1, 1), 0, typeof(float));
                        //        //Image Ref5 = StageDataLoad.LoadMap("F:\\badaben\\vlion12\\warp_ref5.mrc", new int2(1, 1), 0, typeof(float));
                        //        //Image Ref6 = StageDataLoad.LoadMap("F:\\badaben\\vlion12\\warp_ref6.mrc", new int2(1, 1), 0, typeof(float));
                        //        //Image Ref1 = StageDataLoad.LoadMap("F:\\badaben\\chloro\\warp_ref1.mrc", new int2(1, 1), 0, typeof(float));
                        //        //Image Ref2 = StageDataLoad.LoadMap("F:\\badaben\\chloro\\warp_ref2.mrc", new int2(1, 1), 0, typeof(float));
                        //        //Image Ref3 = StageDataLoad.LoadMap("F:\\stefanribo\\vlion\\mini_warp_ref3.mrc", new int2(1, 1), 0, typeof(float));
                        //        //Image Ref4 = StageDataLoad.LoadMap("F:\\stefanribo\\vlion\\mini_warp_ref4.mrc", new int2(1, 1), 0, typeof(float));
                        //        References.Add(1, new Projector(Ref1, 2));
                        //        References.Add(2, new Projector(Ref2, 2));
                        //        References.Add(3, new Projector(Ref3, 2));
                        //        References.Add(4, new Projector(Ref4, 2));
                        //        //References.Add(5, new Projector(Ref5, 2));
                        //        //References.Add(6, new Projector(Ref6, 2));

                        //        //References.Add(3, new Projector(Ref3, 2));
                        //        Ref1.Dispose();
                        //        Ref2.Dispose();
                        //        Ref3.Dispose();
                        //        Ref4.Dispose();
                        //        //Ref5.Dispose();
                        //        //Ref6.Dispose();
                        //    }
                        //    DeviceReferences[d] = References;

                        //    Dictionary<int, Projector> Reconstructions = new Dictionary<int, Projector>();
                        //    foreach (var reference in References)
                        //    {
                        //        Reconstructions.Add(reference.Key, new Projector(reference.Value.Dims, reference.Value.Oversampling));
                        //        Reconstructions[reference.Key].FreeDevice();
                        //    }
                        //    DeviceReconstructions[d] = Reconstructions;

                        //    Dictionary<int, Projector> CTFReconstructions = new Dictionary<int, Projector>();
                        //    foreach (var reference in References)
                        //    {
                        //        CTFReconstructions.Add(reference.Key, new Projector(reference.Value.Dims, reference.Value.Oversampling));
                        //        CTFReconstructions[reference.Key].FreeDevice();
                        //    }
                        //    DeviceCTFReconstructions[d] = CTFReconstructions;
                        //}

                        int NTilts = (int)MathHelper.Max(Options.Movies.Select(m => (float)((TiltSeries)m).NTilts));
                        Dictionary<int, Projector[]> PerAngleReconstructions = new Dictionary<int, Projector[]>();
                        Dictionary<int, Projector[]> PerAngleWeightReconstructions = new Dictionary<int, Projector[]>();
                        //{
                        //    int[] ColumnSubset = TableIn.GetColumn("rlnRandomSubset").Select(s => int.Parse(s)).ToArray();
                        //    List<int> SubsetIDs = new List<int>();
                        //    foreach (var subset in ColumnSubset)
                        //        if (!SubsetIDs.Contains(subset))
                        //            SubsetIDs.Add(subset);
                        //    SubsetIDs.Sort();
                        //    SubsetIDs.Remove(1);
                        //    SubsetIDs.Remove(2);

                        //    int Size = Options.ExportParticleSize;

                        //    //foreach (var subsetID in SubsetIDs)
                        //    //{
                        //    //    PerAngleReconstructions.Add(subsetID, new Projector[NTilts]);
                        //    //    PerAngleWeightReconstructions.Add(subsetID, new Projector[NTilts]);

                        //    //    for (int t = 0; t < NTilts; t++)
                        //    //    {
                        //    //        PerAngleReconstructions[subsetID][t] = new Projector(new int3(Size, Size, Size), 2);
                        //    //        PerAngleReconstructions[subsetID][t].FreeDevice();
                        //    //        PerAngleWeightReconstructions[subsetID][t] = new Projector(new int3(Size, Size, Size), 2);
                        //    //        PerAngleWeightReconstructions[subsetID][t].FreeDevice();
                        //    //    }
                        //    //}
                        //}

                        foreach (var movie in Options.Movies)
                            if (movie.DoProcess)
                            {
                                //if (((TiltSeries)movie).GlobalBfactor < -200)
                                //    continue;

                                while (Devices.Count <= 0)
                                    Thread.Sleep(20);

                                DeviceToken CurrentDevice;
                                lock (Devices)
                                    CurrentDevice = Devices.Dequeue();

                                Thread DeviceThread = new Thread(() =>
                                {
                                    GPU.SetDevice(CurrentDevice.ID);

                                    MapHeader OriginalHeader = null;
                                    Image OriginalStack = null;
                                    decimal ScaleFactor = 1M / (decimal)Math.Pow(2, (double)Options.PostBinTimes);

                                    lock (IOSync[CurrentDevice.ID])
                                        PrepareHeaderAndMap(movie.Path, ImageGain[CurrentDevice.ID], ScaleFactor, out OriginalHeader, out OriginalStack);

                                    if (movie.GetType() == typeof (Movie))
                                    {
                                        movie.UpdateStarDefocus(TableIn, ColumnNames, ColumnCoordsX, ColumnCoordsY);
                                        //movie.ExportParticles(TableIn, TableOut, OriginalHeader, OriginalStack, Options.ExportParticleSize, Options.ExportParticleRadius, ScaleFactor);
                                    }
                                    else if (movie.GetType() == typeof (TiltSeries))
                                    {
                                        //((TiltSeries)movie).ExportSubtomos(TableIn, OriginalStack, Options.ExportParticleSize, new int3(928, 928, 300));
                                        //((TiltSeries)movie).ExportSubtomos(TableIn, OriginalStack, Options.ExportParticleSize, new int3(3712, 3712, 1400));

                                        //((TiltSeries)movie).Reconstruct(OriginalStack, 128, 3.42f * 4 * 2, new int3(3712, 3712, 1400));

                                        /*for (int refinement = 0; refinement < 20; refinement++)
                                        {*/
                                            //OriginalStack.FreeDevice();
                                            //((TiltSeries)movie).PerformOptimizationStep(TableIn, OriginalStack, Options.ExportParticleSize, new int3(3712, 3712, 1400), DeviceReferences[CurrentDevice.ID], 22f, DeviceReconstructions[0], DeviceCTFReconstructions[0]);
                                            //((TiltSeries)movie).RealspaceRefineGlobal(TableIn, OriginalStack, Options.ExportParticleSize, new int3(3838, 3710, 1200), References, 30, 2, "D4", Reconstructions);

                                            //Image Simulated = ((TiltSeries)movie).SimulateTiltSeries(TableIn, OriginalStack.Dims, Options.ExportParticleSize, new int3(3712, 3712, 1200), References, 15);
                                            //Simulated.WriteMRC("d_simulatedseries.mrc");

                                            //((TiltSeries)movie).AlignTiltMovies(TableIn, OriginalStack.Dims, Options.ExportParticleSize, new int3(3712, 3712, 1200), References, 100);

                                            /*TableIn.Save(SaveDialog.FileName + $".it{refinement:D2}.star");
                                        }*/

                                        //((TiltSeries)movie).ExportSubtomos(TableIn, OriginalStack, Options.ExportParticleSize, new int3(3712, 3712, 1400));

                                        //Image Reference = StageDataLoad.LoadMap("F:\\chloroplastribo\\vlion\\warp_ref3.mrc", new int2(1, 1), 0, typeof (float));
                                        //((TiltSeries)movie).Correlate(OriginalStack, Reference, 128, 40, 400, new int3(3712, 3712, 1400), 2, "C1");
                                        //Reference.Dispose();

                                        //GPU.SetDevice(0);
                                        //((TiltSeries)movie).MakePerTomogramReconstructions(TableIn, OriginalStack, Options.ExportParticleSize, new int3(3712, 3712, 1400));
                                        //((TiltSeries)movie).AddToPerAngleReconstructions(TableIn, OriginalStack, Options.ExportParticleSize, new int3(3710, 3710, 1400), PerAngleReconstructions, PerAngleWeightReconstructions);
                                    }

                                    OriginalStack?.Dispose();
                                    //Debug.WriteLine(movie.Path);
                                    //TableIn.Save(SaveDialog.FileName);

                                    lock (Devices)
                                        Devices.Enqueue(CurrentDevice);

                                    Debug.WriteLine("Done: " + movie.RootName);
                                });

                                DeviceThread.Start();
                            }

                        while (Devices.Count != NTokens)
                            Thread.Sleep(20);

                        for (int d = 0; d < UsedDevices; d++)
                        {
                            ImageGain[d]?.Dispose();
                        }

                        //for (int d = 0; d < DeviceReferences.Length; d++)
                        //{
                        //    GPU.SetDevice(d);
                        //    foreach (var reconstruction in DeviceReconstructions[d])
                        //    {
                        //        if (d == 0)
                        //        {
                        //            Image ReconstructedMap = reconstruction.Value.Reconstruct(false);
                        //            //ReconstructedMap.WriteMRC($"F:\\chloroplastribo\\vlion\\warped_{reconstruction.Key}_nodeconv.mrc");

                        //            Image ReconstructedCTF = DeviceCTFReconstructions[d][reconstruction.Key].Reconstruct(true);

                        //            Image ReconstructedMapFT = ReconstructedMap.AsFFT(true);
                        //            ReconstructedMap.Dispose();

                        //            int Dim = ReconstructedMap.Dims.Y;
                        //            int DimFT = Dim / 2 + 1;
                        //            int R2 = Dim / 2 - 2;
                        //            R2 *= R2;
                        //            foreach (var slice in ReconstructedCTF.GetHost(Intent.ReadWrite))
                        //            {
                        //                for (int y = 0; y < Dim; y++)
                        //                {
                        //                    int yy = y < Dim / 2 + 1 ? y : y - Dim;
                        //                    yy *= yy;

                        //                    for (int x = 0; x < DimFT; x++)
                        //                    {
                        //                        int xx = x * x;

                        //                        slice[y * DimFT + x] = xx + yy < R2 ? Math.Max(1e-2f, slice[y * DimFT + x]) : 1f;
                        //                    }
                        //                }
                        //            }

                        //            ReconstructedMapFT.Divide(ReconstructedCTF);
                        //            ReconstructedMap = ReconstructedMapFT.AsIFFT(true);
                        //            ReconstructedMapFT.Dispose();

                        //            //GPU.SphereMask(ReconstructedMap.GetDevice(Intent.Read),
                        //            //               ReconstructedMap.GetDevice(Intent.Write),
                        //            //               ReconstructedMap.Dims,
                        //            //               (float)(ReconstructedMap.Dims.X / 2 - 8),
                        //            //               8,
                        //            //               1);

                        //            ReconstructedMap.WriteMRC($"F:\\badaben\\vlion123\\warped_{reconstruction.Key}.mrc");
                        //            ReconstructedMap.Dispose();
                        //        }

                        //        reconstruction.Value.Dispose();
                        //        DeviceReferences[d][reconstruction.Key].Dispose();
                        //        DeviceCTFReconstructions[d][reconstruction.Key].Dispose();
                        //    }
                        //}

                        //string WeightOptimizationDir = ((TiltSeries)Options.Movies[0]).WeightOptimizationDir;
                        //foreach (var subset in PerAngleReconstructions)
                        //{
                        //    for (int t = 0; t < NTilts; t++)
                        //    {
                        //        Image Reconstruction = PerAngleReconstructions[subset.Key][t].Reconstruct(false);
                        //        PerAngleReconstructions[subset.Key][t].Dispose();
                        //        Reconstruction.WriteMRC(WeightOptimizationDir + $"subset{subset.Key}_tilt{t.ToString("D3")}.mrc");
                        //        Reconstruction.Dispose();

                        //        foreach (var slice in PerAngleWeightReconstructions[subset.Key][t].Weights.GetHost(Intent.ReadWrite))
                        //            for (int i = 0; i < slice.Length; i++)
                        //                slice[i] = Math.Min(1, slice[i]);
                        //        Image WeightReconstruction = PerAngleWeightReconstructions[subset.Key][t].Reconstruct(true);
                        //        PerAngleWeightReconstructions[subset.Key][t].Dispose();
                        //        WeightReconstruction.WriteMRC(WeightOptimizationDir + $"subset{subset.Key}_tilt{t.ToString("D3")}.weight.mrc");
                        //        WeightReconstruction.Dispose();
                        //    }
                        //}

                        TableIn.Save(SaveDialog.FileName);
                    });
                    ProcessThread.Start();
                }
            }
        }