private void FittingRangeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { Plot1DAxisXSectionConsider.Visibility = Visibility.Hidden; if (Movie == null) { return; } TiltSeries Series = Movie as TiltSeries; if (Movie.GetType() == typeof(Movie) && (Movie.PS1D == null || Movie.Simulated1D == null)) { return; } if (Series != null && (Series.TiltPS1D.Count <= TiltID || Series.TiltPS1D[TiltID] == null)) { return; } Plot1DAxisXSectionConsider.Visibility = Visibility.Visible; float2[] ExperimentalData = Series == null ? Movie.PS1D : Series.TiltPS1D[TiltID]; int N = ExperimentalData.Length; Plot1DAxisXSectionConsider.Value = N * (double)FittingRangeMin; Plot1DAxisXSectionConsider.SectionWidth = N * (double)(FittingRangeMax - FittingRangeMin); }
private void TiltDial_MouseWheel(object sender, MouseWheelEventArgs e) { TiltSeries Series = Movie as TiltSeries; if (Series != null) { List <int> SortedAngle = Series.IndicesSortedAngle.ToList(); int CurrentPos = SortedAngle.IndexOf(TiltID); int Delta = -Math.Sign(e.Delta); TiltID = SortedAngle[Math.Max(0, Math.Min(SortedAngle.Count - 1, CurrentPos + Delta))]; } }
private void ComposeTomoDial() { CanvasDial.Children.Clear(); TiltKnobs.Clear(); if (Movie == null || Movie.GetType() != typeof(TiltSeries)) { return; } TiltSeries Series = (TiltSeries)Movie; for (int i = 0; i < Series.NTilts; i++) { TiltDialItem Knob = new TiltDialItem(); Knob.TiltID = i; Knob.Angle = Series.Angles[i]; Knob.Dose = Series.Dose[i]; Knob.DoProcess = Series.UseTilt[i]; Knob.Width = 160; Knob.Height = 20; TransformGroup TGroup = new TransformGroup(); TGroup.Children.Add(new TranslateTransform(-80, -10)); TGroup.Children.Add(new RotateTransform(-Knob.Angle)); Knob.RenderTransform = TGroup; TiltKnobs.Add(Knob); CanvasDial.Children.Add(Knob); double Radius = ActualWidth / 2; Canvas.SetLeft(Knob, Math.Cos((Knob.Angle + 180) * Helper.ToRad) * (Radius + 85) + Radius); Canvas.SetTop(Knob, -Math.Sin((Knob.Angle + 180) * Helper.ToRad) * (Radius + 85) + Radius); Knob.SelectionChanged += (o, args) => TiltID = ((TiltDialItem)o).TiltID; Knob.DoProcessChanged += (o, args) => { Series.UseTilt[Knob.TiltID] = (bool)args.NewValue; Series.SaveMeta(); UpdateTiltDial(); }; Knob.MouseWheel += TiltDial_MouseWheel; } UpdateTiltDial(); }
private void UpdateTiltInfo() { if (Movie != null && Movie.GetType() == typeof(TiltSeries)) { TiltSeries Series = Movie as TiltSeries; TextTiltDefocus.Value = Series.GetTiltDefocus(TiltID).ToString("F3", CultureInfo.InvariantCulture); TextTiltDefocusDelta.Value = Series.GetTiltDefocusDelta(TiltID).ToString("F3", CultureInfo.InvariantCulture); TextTiltDefocusAngle.Value = Series.GetTiltDefocusAngle(TiltID).ToString("F1", CultureInfo.InvariantCulture); TextTiltPhase.Value = Series.GetTiltPhase(TiltID).ToString("F2", CultureInfo.InvariantCulture); TextTiltResEstimate.Value = Series.CTFResolutionEstimate.ToString("F2", CultureInfo.InvariantCulture); float NormalAngle1 = (float)Math.Atan2(Series.PlaneNormal.Y, Series.PlaneNormal.X) * Helper.ToDeg; float NormalAngle2 = (float)Math.Asin(new float2(Series.PlaneNormal.X, Series.PlaneNormal.Y).Length()) * Helper.ToDeg; TransformPlaneInclination.Angle = -NormalAngle1; TextPlaneInclination.Value = NormalAngle2.ToString("F1", CultureInfo.InvariantCulture); TextAngleMismatch.Visibility = Series.AreAnglesInverted ? Visibility.Visible : Visibility.Hidden; } }
private void AdjustYAxis() { if (Movie == null) { return; } TiltSeries Series = Movie as TiltSeries; if ((Movie.GetType() == typeof(Movie) || ShowSeriesAverage) && (Movie.PS1D == null || Movie.Simulated1D == null)) { return; } if (Series != null && (Series.TiltPS1D.Count <= TiltID || Series.TiltPS1D[TiltID] == null)) { return; } float2[] ExperimentalData = (Series == null || _ShowSeriesAverage) ? Movie.PS1D : Series.TiltPS1D[TiltID]; float2[] SimulatedData = (Series == null || _ShowSeriesAverage) ? Movie.Simulated1D : Series.GetTiltSimulated1D(TiltID); int MinN = (int)(ExperimentalData.Length * FittingRangeMin); int N = (int)(ExperimentalData.Length * (FittingRangeMax - FittingRangeMin)); IEnumerable <float> RelevantExperimental = ExperimentalData.Select(p => p.Y).Skip(MinN).Take(N); IEnumerable <float> RelevantSimulated = SimulatedData.Select(p => p.Y).Skip(MinN).Take(N); float MinExperimental = MathHelper.Min(RelevantExperimental); float MaxExperimental = MathHelper.Max(RelevantExperimental); float MinSimulated = MathHelper.Min(RelevantSimulated); float MaxSimulated = MathHelper.Max(RelevantSimulated); Plot1DAxisY.MinValue = Math.Min(MinExperimental, MinSimulated); Plot1DAxisY.MaxValue = Math.Max(MaxExperimental, MaxSimulated) * 1.25f; Plot1DAxisY.LabelFormatter = val => val.ToString("F3", CultureInfo.InvariantCulture); Plot1DAxisYQuality.LabelFormatter = val => val.ToString("F3", CultureInfo.InvariantCulture); Plot1DAxisX.LabelFormatter = val => (Movie.OptionsCTF.Window / val * (double)Movie.OptionsCTF.BinnedPixelSizeMean).ToString("F2") + " Å"; }
private void UpdateTiltDial() { TiltSeries Series = Movie as TiltSeries; foreach (var Knob in TiltKnobs) { Knob.IsSelected = Knob.TiltID == TiltID; Brush KnobBrush; if (!Knob.DoProcess) { KnobBrush = Brushes.DarkGray; } else if (Series != null && Series.TiltPS1D.Count > Knob.TiltID && Series.TiltPS1D[Knob.TiltID] != null) { KnobBrush = Brushes.Green; } else { KnobBrush = Brushes.Red; } Knob.KnobBrush = KnobBrush; } }
static void Main(string[] args) { CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture; //if (!Debugger.IsAttached) // Debugger.Launch(); if (args.Length < 3) { return; } DeviceID = int.Parse(args[0]) % GPU.GetDeviceCount(); PipeName = args[1]; bool DebugMode = bool.Parse(args[2]); GPU.SetDevice(DeviceID); Console.WriteLine($"Running on GPU #{DeviceID} ({GPU.GetFreeMemory(DeviceID)} MB free) through {PipeName}\n"); Formatter = new BinaryFormatter(); Heartbeat = new Thread(new ThreadStart(() => { if (!DebugMode) { while (true) { try { NamedPipeClientStream PipeHeartbeat = new NamedPipeClientStream(".", PipeName + "_heartbeat", PipeDirection.In); PipeHeartbeat.Connect(5000); PipeHeartbeat.Dispose(); } catch { if (!Terminating) { Process.GetCurrentProcess().Kill(); } } } } })); Heartbeat.Start(); while (true) { PipeReceive = new NamedPipeClientStream(".", PipeName + "_out", PipeDirection.In); PipeReceive.Connect(); NamedSerializableObject Command = (NamedSerializableObject)Formatter.Deserialize(PipeReceive); PipeReceive.Dispose(); Console.WriteLine($"Received \"{Command.Name}\", with {Command.Content.Length} arguments, for GPU #{GPU.GetDevice()}, {GPU.GetFreeMemory(DeviceID)} MB free"); try { Stopwatch Watch = new Stopwatch(); Watch.Start(); if (Command.Name == "Exit") { Movie.WriteAverageAsync?.Wait(); SendSuccessStatus(true); Process.GetCurrentProcess().Kill(); return; } else if (Command.Name == "Ping") { Console.WriteLine("Ping!"); } else if (Command.Name == "SetHeaderlessParams") { HeaderlessDims = (int2)Command.Content[0]; HeaderlessOffset = (long)Command.Content[1]; HeaderlessType = (string)Command.Content[2]; Console.WriteLine($"Set headerless parameters to {HeaderlessDims}, {HeaderlessOffset}, {HeaderlessType}"); } else if (Command.Name == "LoadGainRef") { GainRef?.Dispose(); DefectMap?.Dispose(); string GainPath = (string)Command.Content[0]; bool FlipX = (bool)Command.Content[1]; bool FlipY = (bool)Command.Content[2]; bool Transpose = (bool)Command.Content[3]; string DefectsPath = (string)Command.Content[4]; if (!string.IsNullOrEmpty(GainPath)) { GainRef = LoadAndPrepareGainReference(GainPath, FlipX, FlipY, Transpose); } if (!string.IsNullOrEmpty(DefectsPath)) { DefectMap = LoadAndPrepareDefectMap(DefectsPath, FlipX, FlipY, Transpose); } Console.WriteLine($"Loaded gain reference and defect map: {GainRef}, {FlipX}, {FlipY}, {Transpose}, {DefectsPath}"); } else if (Command.Name == "LoadStack") { OriginalStack?.Dispose(); string Path = (string)Command.Content[0]; decimal ScaleFactor = (decimal)Command.Content[1]; int EERGroupFrames = (int)Command.Content[2]; HeaderEER.GroupNFrames = EERGroupFrames; OriginalStack = LoadAndPrepareStack(Path, ScaleFactor); OriginalStackOwner = Helper.PathToNameWithExtension(Path); Console.WriteLine($"Loaded stack: {OriginalStack}, {ScaleFactor}"); } else if (Command.Name == "MovieProcessCTF") { string Path = (string)Command.Content[0]; ProcessingOptionsMovieCTF Options = (ProcessingOptionsMovieCTF)Command.Content[1]; if (Helper.PathToNameWithExtension(Path) != OriginalStackOwner) { throw new Exception("Currently loaded stack doesn't match the movie requested for processing!"); } Movie M = new Movie(Path); M.ProcessCTF(OriginalStack, Options); M.SaveMeta(); Console.WriteLine($"Processed CTF for {Path}"); } else if (Command.Name == "MovieProcessMovement") { string Path = (string)Command.Content[0]; ProcessingOptionsMovieMovement Options = (ProcessingOptionsMovieMovement)Command.Content[1]; if (Helper.PathToNameWithExtension(Path) != OriginalStackOwner) { throw new Exception("Currently loaded stack doesn't match the movie requested for processing!"); } Movie M = new Movie(Path); M.ProcessShift(OriginalStack, Options); M.SaveMeta(); Console.WriteLine($"Processed movement for {Path}"); } else if (Command.Name == "MovieExportMovie") { string Path = (string)Command.Content[0]; ProcessingOptionsMovieExport Options = (ProcessingOptionsMovieExport)Command.Content[1]; if (Helper.PathToNameWithExtension(Path) != OriginalStackOwner) { throw new Exception("Currently loaded stack doesn't match the movie requested for processing!"); } Movie M = new Movie(Path); M.ExportMovie(OriginalStack, Options); M.SaveMeta(); Console.WriteLine($"Exported movie for {Path}"); } else if (Command.Name == "MovieExportParticles") { string Path = (string)Command.Content[0]; ProcessingOptionsParticlesExport Options = (ProcessingOptionsParticlesExport)Command.Content[1]; float2[] Coordinates = (float2[])Command.Content[2]; if (Helper.PathToNameWithExtension(Path) != OriginalStackOwner) { throw new Exception("Currently loaded stack doesn't match the movie requested for processing!"); } Movie M = new Movie(Path); M.ExportParticles(OriginalStack, Coordinates, Options); M.SaveMeta(); Console.WriteLine($"Exported {Coordinates.Length} particles for {Path}"); } else if (Command.Name == "TomoProcessCTF") { string Path = (string)Command.Content[0]; ProcessingOptionsMovieCTF Options = (ProcessingOptionsMovieCTF)Command.Content[1]; TiltSeries T = new TiltSeries(Path); T.ProcessCTFSimultaneous(Options); T.SaveMeta(); Console.WriteLine($"Processed CTF for {Path}"); } else if (Command.Name == "TomoExportParticles") { string Path = (string)Command.Content[0]; ProcessingOptionsTomoSubReconstruction Options = (ProcessingOptionsTomoSubReconstruction)Command.Content[1]; float3[] Coordinates = (float3[])Command.Content[2]; float3[] Angles = Command.Content[3] != null ? (float3[])Command.Content[3] : null; TiltSeries T = new TiltSeries(Path); T.ReconstructSubtomos(Options, Coordinates, Angles); T.SaveMeta(); Console.WriteLine($"Exported {Coordinates.Length} particles for {Path}"); } else if (Command.Name == "MPAPreparePopulation") { string Path = (string)Command.Content[0]; MPAPopulation = new Population(Path); foreach (var species in MPAPopulation.Species) { Console.Write($"Preparing {species.Name} for refinement... "); species.PrepareRefinementRequisites(true, DeviceID); Console.WriteLine("Done."); } } else if (Command.Name == "MPARefine") { string Path = (string)Command.Content[0]; string WorkingDirectory = (string)Command.Content[1]; string LogPath = (string)Command.Content[2]; ProcessingOptionsMPARefine Options = (ProcessingOptionsMPARefine)Command.Content[3]; DataSource Source = (DataSource)Command.Content[4]; Movie Item = null; if (Helper.PathToExtension(Path).ToLower() == ".tomostar") { Item = new TiltSeries(Path); } else { Item = new Movie(Path); } GPU.SetDevice(DeviceID); Item.PerformMultiParticleRefinement(WorkingDirectory, Options, MPAPopulation.Species.ToArray(), Source, GainRef, DefectMap, (message) => { Console.WriteLine(message); bool Success = false; int Tries = 0; while (!Success && Tries < 10) { try { using (TextWriter Writer = File.AppendText(LogPath)) Writer.WriteLine(message); Success = true; } catch { Thread.Sleep(100); Tries++; } } }); Item.SaveMeta(); GPU.CheckGPUExceptions(); Console.WriteLine($"Finished refining {Item.Name}"); } else if (Command.Name == "MPASaveProgress") { string Path = (string)Command.Content[0]; MPAPopulation.SaveRefinementProgress(Path); } else if (Command.Name == "TryAllocatePinnedMemory") { long[] ChunkSizes = (long[])Command.Content[0]; IntPtr[] Chunks = new IntPtr[ChunkSizes.Length]; for (int i = 0; i < ChunkSizes.Length; i++) { Chunks[i] = GPU.MallocHostPinned(ChunkSizes[i] / sizeof(float)); //Dummies.Add(Helper.ArrayOfSequence(0, (int)(ChunkSizes[i] / sizeof(float) / 2), 1)); } GPU.CheckGPUExceptions(); //for (int i = 0; i < ChunkSizes.Length; i++) // GPU.FreeHostPinned(Chunks[i]); Console.WriteLine($"Successfully allocated {ChunkSizes.Sum()} bytes of pinned memory"); } Watch.Stop(); Console.WriteLine((Watch.ElapsedMilliseconds / 1000f).ToString("F3")); Console.WriteLine(""); SendSuccessStatus(true); } catch (Exception e) { Console.WriteLine(e.ToString()); File.WriteAllText($"worker_{DeviceID}_crash.txt", e.ToString()); //Console.Read(); SendSuccessStatus(false); } } }
static void Main(string[] args) { CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture; Options Options = new Options(); string WorkingDirectory; Dictionary <int, string> MaskOverrideNames = new Dictionary <int, string>(); if (!Debugger.IsAttached) { Parser.Default.ParseArguments <Options>(args).WithParsed <Options>(opts => Options = opts); WorkingDirectory = Environment.CurrentDirectory + "/"; } else { Options.PopulationPath = "population_combined/70SRibos.population"; Options.MinResolution = 15; Options.DoTiltFrames = false; Options.FitAnisotropy = true; Options.ResolveLocation = false; Options.ResolveFrames = true; Options.ResolveItems = true; Options.GridWidth = 5; Options.GridHeight = 5; WorkingDirectory = @"H:\20181109CmMp\"; } Options.PopulationPath = Path.Combine(WorkingDirectory, Options.PopulationPath); string RefinementDirectory = Path.Combine(Helper.PathToFolder(Options.PopulationPath), "refinement_temp"); if (!Options.ResolveFrames && !Options.ResolveItems && !Options.ResolveLocation) { throw new Exception("No dimension chosen to resolve over."); } if (Options.ResolveLocation && (Options.ResolveFrames || Options.ResolveItems)) { throw new Exception("Spatial resolution cannot be combined with other dimensions in the same run. Please execute separately with different dimensions."); } Population P = new Population(Options.PopulationPath); DataSource[] Sources = P.Sources.ToArray(); float PixelSize = (float)P.Species[0].PixelSize; foreach (var source in Sources) { List <Movie> ItemsWithData = new List <Movie>(); Console.Write("Discovering items with data..."); int NItemsDiscovered = 0; foreach (var item in source.Files.Values) { if (Options.DoTiltFrames) { bool SomethingMissing = false; string ItemPath = Path.Combine(source.FolderPath, item); TiltSeries Series = new TiltSeries(ItemPath); for (int t = 0; t < Series.NTilts; t++) { if (!File.Exists(Path.Combine(RefinementDirectory, $"{Helper.PathToName(item)}_tilt{t:D3}_fsc.mrc"))) { SomethingMissing = true; break; } } if (SomethingMissing) { continue; } ItemsWithData.Add(Series); } else { if (Options.ResolveFrames || Options.ResolveItems) { if (!File.Exists(Path.Combine(RefinementDirectory, Helper.PathToName(item) + "_fsc.mrc"))) { continue; } } else if (Options.ResolveLocation) { if (!File.Exists(Path.Combine(RefinementDirectory, Helper.PathToName(item) + "_fscparticles.mrc"))) { continue; } if (!File.Exists(Path.Combine(RefinementDirectory, Helper.PathToName(item) + "_fscparticles.star"))) { continue; } } string ItemPath = Path.Combine(source.FolderPath, item); if (item.Contains(".tomostar")) { ItemsWithData.Add(new TiltSeries(ItemPath)); } else { ItemsWithData.Add(new Movie(ItemPath)); } } NItemsDiscovered++; ClearCurrentConsoleLine(); Console.Write($"Discovering items with data... {NItemsDiscovered}/{source.Files.Count}"); } Console.WriteLine("\n"); if (ItemsWithData.Count == 0) { Console.WriteLine($"No items with FSC data found for source {source.Name}!"); } if (Options.DoTiltFrames) { for (int t = 0; t < ((TiltSeries)ItemsWithData[0]).NTilts; t++) { int2 Dims; int MaxFrames = 1; { string FSCPath = Path.Combine(RefinementDirectory, $"{ItemsWithData[0].RootName}_tilt{t:D3}_fsc.mrc"); Image FSC = Image.FromFile(FSCPath); Dims = new int2(FSC.Dims.Y); MaxFrames = FSC.Dims.Z / 3; FSC.Dispose(); } List <float[]> AllAB = new List <float[]>(); List <float[]> AllA2 = new List <float[]>(); List <float[]> AllB2 = new List <float[]>(); foreach (var parentItem in ItemsWithData.Select(v => (TiltSeries)v)) { string MoviePath = Path.Combine(parentItem.DirectoryName, parentItem.TiltMoviePaths[t]); Movie item = new Movie(MoviePath); { string FSCPath = Path.Combine(RefinementDirectory, $"{parentItem.RootName}_tilt{t:D3}_fsc.mrc"); Image FSC = Image.FromFile(FSCPath); float[][] FSCData = FSC.GetHost(Intent.Read); for (int z = 0; z < FSCData.Length / 3; z++) { if (AllAB.Count <= z) { AllAB.Add(FSCData[z * 3 + 0]); AllA2.Add(FSCData[z * 3 + 1]); AllB2.Add(FSCData[z * 3 + 2]); } else { for (int i = 0; i < FSCData[0].Length; i++) { AllAB[z][i] += FSCData[z * 3 + 0][i]; AllA2[z][i] += FSCData[z * 3 + 1][i]; AllB2[z][i] += FSCData[z * 3 + 2][i]; } } } FSC.Dispose(); } } int NItems = AllAB.Count; Image CorrAB = new Image(AllAB.ToArray(), new int3(Dims.X, Dims.Y, NItems), true); Image CorrA2 = new Image(AllA2.ToArray(), new int3(Dims.X, Dims.Y, NItems), true); Image CorrB2 = new Image(AllB2.ToArray(), new int3(Dims.X, Dims.Y, NItems), true); Image CTFWeights = CorrAB.GetCopyGPU(); CTFWeights.Fill(1f); (float[] ResultScales, float3[] ResultBfactors) = FSC.FitBFactors2D(CorrAB, CorrA2, CorrB2, CTFWeights, PixelSize, Options.MinResolution, Options.FitAnisotropy, 512, null); CorrAB.Dispose(); CorrA2.Dispose(); CorrB2.Dispose(); CTFWeights.Dispose(); float MaxScale = MathHelper.Max(ResultScales); ResultScales = ResultScales.Select(v => v / MaxScale).ToArray(); List <float> BfacsSorted = new List <float>(ResultBfactors.Select(v => v.X)); float MaxBfac = MathHelper.Max(BfacsSorted); //float MaxBfac = MathHelper.Max(ResultBfactors.Select(v => v.X)); ResultBfactors = ResultBfactors.Select(v => new float3(Math.Min(0, v.X - MaxBfac), v.Y, v.Z)).ToArray(); List <float3> TableRows = new List <float3>(); foreach (var parentItem in ItemsWithData.Select(v => (TiltSeries)v)) { string MoviePath = Path.Combine(parentItem.DirectoryName, parentItem.TiltMoviePaths[t]); Movie item = new Movie(MoviePath); int InThisItem = MaxFrames; float[] Weights = ResultScales; float[] Bfacs = ResultBfactors.Select(v => v.X).ToArray(); float[] BfacsDelta = ResultBfactors.Select(v => v.Y).ToArray(); float[] BfacsAngle = ResultBfactors.Select(v => v.Z).ToArray(); (int MaxIndex, float MaxB) = MathHelper.MaxElement(Bfacs); TableRows.Add(new float3((float)item.CTF.Defocus, Weights[MaxIndex], MaxB)); item.GridDoseWeights = new CubicGrid(new int3(1, 1, InThisItem), Weights); item.GridDoseBfacs = new CubicGrid(new int3(1, 1, InThisItem), Bfacs); item.GridDoseBfacsDelta = new CubicGrid(new int3(1, 1, InThisItem), BfacsDelta); item.GridDoseBfacsAngle = new CubicGrid(new int3(1, 1, InThisItem), BfacsAngle); item.SaveMeta(); } } } else if (Options.ResolveFrames || Options.ResolveItems) { int2 Dims; int MaxFrames = 1; { string FSCPath = Path.Combine(RefinementDirectory, ItemsWithData[0].RootName + "_fsc.mrc"); Image FSC = Image.FromFile(FSCPath); Dims = new int2(FSC.Dims.Y); MaxFrames = FSC.Dims.Z / 3; FSC.Dispose(); } List <float[]> AllAB = new List <float[]>(); List <float[]> AllA2 = new List <float[]>(); List <float[]> AllB2 = new List <float[]>(); if (!Options.ResolveItems) { AllAB = new List <float[]>(Helper.ArrayOfFunction(i => new float[Dims.ElementsFFT()], MaxFrames)); AllA2 = new List <float[]>(Helper.ArrayOfFunction(i => new float[Dims.ElementsFFT()], MaxFrames)); AllB2 = new List <float[]>(Helper.ArrayOfFunction(i => new float[Dims.ElementsFFT()], MaxFrames)); } else if (!Options.ResolveFrames) { AllAB = new List <float[]>(Helper.ArrayOfFunction(i => new float[Dims.ElementsFFT()], ItemsWithData.Count)); AllA2 = new List <float[]>(Helper.ArrayOfFunction(i => new float[Dims.ElementsFFT()], ItemsWithData.Count)); AllB2 = new List <float[]>(Helper.ArrayOfFunction(i => new float[Dims.ElementsFFT()], ItemsWithData.Count)); } Console.Write("Loading correlation data..."); int NDone = 0; foreach (var item in ItemsWithData) { //if (NDone >= 30) // break; string FSCPath = Path.Combine(RefinementDirectory, item.RootName + "_fsc.mrc"); Image FSC = Image.FromFile(FSCPath); float[][] FSCData = FSC.GetHost(Intent.Read); for (int z = 0; z < FSCData.Length / 3; z++) { if (Options.ResolveItems && Options.ResolveFrames) { AllAB.Add(FSCData[z * 3 + 0]); AllA2.Add(FSCData[z * 3 + 1]); AllB2.Add(FSCData[z * 3 + 2]); } else { int s = 0; if (!Options.ResolveItems) { s = z; } else if (!Options.ResolveFrames) { s = NDone; } else { throw new Exception("Shouldn't be here"); } for (int i = 0; i < FSCData[0].Length; i++) { AllAB[s][i] += FSCData[z * 3 + 0][i]; AllA2[s][i] += FSCData[z * 3 + 1][i]; AllB2[s][i] += FSCData[z * 3 + 2][i]; } } } FSC.Dispose(); NDone++; ClearCurrentConsoleLine(); Console.Write($"Loading correlation data... {NDone}/{ItemsWithData.Count}"); } Console.WriteLine("\n"); int NItems = AllAB.Count; Image CorrAB = new Image(AllAB.ToArray(), new int3(Dims.X, Dims.Y, NItems), true); Image CorrA2 = new Image(AllA2.ToArray(), new int3(Dims.X, Dims.Y, NItems), true); Image CorrB2 = new Image(AllB2.ToArray(), new int3(Dims.X, Dims.Y, NItems), true); //Image CTFWeights = CorrAB.GetCopyGPU(); //CTFWeights.Fill(1f); (float[] ResultScales, float3[] ResultBfactors) = FSC.FitBFactors2D(CorrAB, CorrA2, CorrB2, null, PixelSize, Options.MinResolution, Options.FitAnisotropy, 512, (progress) => { ClearCurrentConsoleLine(); Console.Write($"Fitting... {(progress * 100).ToString("F4")} %"); }); Console.WriteLine("\n"); List <float> ScalesSorted = ResultScales.Where((v, i) => ResultBfactors[i].X > -30).ToList(); ScalesSorted.Sort(); float MaxScale = Options.ResolveItems ? ScalesSorted[(int)(ScalesSorted.Count * 0.997f)] : ScalesSorted.Last(); ResultScales = ResultScales.Select(v => Math.Min(1, v / MaxScale)).ToArray(); List <float> BfacsSorted = Helper.ArrayOfSequence(0, ResultBfactors.Length, 1).Where(i => ResultScales[i] > 0.7).Select(i => ResultBfactors[i].X + Math.Abs(ResultBfactors[i].Y)).ToList(); BfacsSorted.Sort(); float MaxBfac = Options.ResolveItems ? BfacsSorted[(int)(BfacsSorted.Count * 0.997f)] : BfacsSorted.Last(); //float MaxBfac = MathHelper.Max(ResultBfactors.Select(v => v.X)); ResultBfactors = ResultBfactors.Select(v => new float3(Math.Min(0, v.X - MaxBfac), v.Y, v.Z)).ToArray(); NDone = 0; int NFramesDone = 0; foreach (var item in ItemsWithData) { int InThisItem = MaxFrames; if (item.GetType() == typeof(TiltSeries)) { InThisItem = ((TiltSeries)item).NTilts; } if (Options.ResolveFrames) { float[] Weights = ResultScales.Skip(NFramesDone).Take(InThisItem).ToArray(); float[] Bfacs = ResultBfactors.Skip(NFramesDone).Take(InThisItem).Select(v => v.X).ToArray(); float[] BfacsDelta = ResultBfactors.Skip(NFramesDone).Take(InThisItem).Select(v => v.Y).ToArray(); float[] BfacsAngle = ResultBfactors.Skip(NFramesDone).Take(InThisItem).Select(v => v.Z).ToArray(); item.GridDoseWeights = new CubicGrid(new int3(1, 1, InThisItem), Weights); item.GridDoseBfacs = new CubicGrid(new int3(1, 1, InThisItem), Bfacs); item.GridDoseBfacsDelta = new CubicGrid(new int3(1, 1, InThisItem), BfacsDelta); item.GridDoseBfacsAngle = new CubicGrid(new int3(1, 1, InThisItem), BfacsAngle); if (Options.ResolveItems) { NFramesDone += InThisItem; } } else if (Options.ResolveItems) { item.GlobalBfactor = ResultBfactors[NFramesDone].X; item.GlobalWeight = ResultScales[NFramesDone]; NFramesDone++; } item.SaveMeta(); NDone++; ClearCurrentConsoleLine(); Console.Write($"Saving metadata... {NDone}/{ItemsWithData.Count}"); } } else if (Options.ResolveLocation) { List <List <Movie> > ItemGroups = new List <List <Movie> >(); foreach (var item in ItemsWithData) { ItemGroups.Add(new List <Movie>() { item }); } int FSCLength = 0; { string FSCPath = Path.Combine(RefinementDirectory, ItemsWithData[0].RootName + "_fscparticles.mrc"); Image FSC = Image.FromFile(FSCPath); FSCLength = FSC.Dims.X; FSC.Dispose(); } int NGroupsDone = 0; foreach (var itemGroup in ItemGroups) { int2 DimsGrid = new int2(Options.GridWidth, Options.GridHeight); float2 GridMultiplier = new float2(DimsGrid - 1); float3[][] AllFSCs = Helper.ArrayOfFunction(i => new float3[FSCLength], (int)DimsGrid.Elements()); float[][] AllCTFs = Helper.ArrayOfFunction(i => Helper.ArrayOfConstant(1f, FSCLength), (int)DimsGrid.Elements()); foreach (var item in itemGroup) { string FSCPath = Path.Combine(RefinementDirectory, item.RootName + "_fscparticles.mrc"); string StarPath = Path.Combine(RefinementDirectory, item.RootName + "_fscparticles.star"); Image FSC = Image.FromFile(FSCPath); float[] FSCData = FSC.GetHost(Intent.Read)[0]; Star TableIn = new Star(StarPath); float2[] Coords = TableIn.GetFloat2("wrpNormCoordinateX", "wrpNormCoordinateY"); if (Coords.Length * 3 != FSC.Dims.Y) { throw new Exception($"Number of particles does not match number of FSC lines"); } for (int p = 0; p < Coords.Length; p++) { int2 CoordsRounded = new int2((int)Math.Round(Coords[p].X * GridMultiplier.X), (int)Math.Round(Coords[p].Y * GridMultiplier.Y)); int FSCID = CoordsRounded.Y * DimsGrid.X + CoordsRounded.X; float3[] LocalFSC = AllFSCs[FSCID]; for (int i = 0; i < FSCLength; i++) { LocalFSC[i] += new float3(FSCData[(p * 3 + 0) * FSCLength + i], FSCData[(p * 3 + 1) * FSCLength + i], FSCData[(p * 3 + 2) * FSCLength + i]); } } FSC.Dispose(); } try { float2[] PositionFits = FSC.FitBFactors(AllFSCs, AllCTFs, PixelSize, Options.MinResolution); float MaxWeight = MathHelper.Max(PositionFits.Select(v => v.X)); float MaxBfactor = MathHelper.Max(PositionFits.Select(v => v.Y)); PositionFits = PositionFits.Select(v => new float2(v.X / MaxWeight, v.Y - MaxBfactor)).ToArray(); Image Fitted = new Image(new[] { PositionFits.Select(v => v.X).ToArray(), PositionFits.Select(v => v.Y).ToArray() }, new int3(DimsGrid.X, DimsGrid.Y, 2)); Fitted.WriteMRC($"d_fitted_{NGroupsDone}.mrc", true); foreach (var item in itemGroup) { item.GridLocationWeights = new CubicGrid(new int3(DimsGrid.X, DimsGrid.Y, 1), PositionFits.Select(v => v.X).ToArray()); item.GridLocationBfacs = new CubicGrid(new int3(DimsGrid.X, DimsGrid.Y, 1), PositionFits.Select(v => v.Y).ToArray()); item.SaveMeta(); } } catch { } NGroupsDone++; } } } }
void WorkLoop(object sender, EventArgs e) { string[] ParticleFileNames = null; if (Directory.Exists(Path.Combine(FolderPath, "matching"))) { ParticleFileNames = Directory.EnumerateFiles(Path.Combine(FolderPath, "matching"), "*.star", SearchOption.TopDirectoryOnly).Select(p => Helper.PathToNameWithExtension(p)).ToArray(); } while (true) { if (ShouldAbort) { return; } Stopwatch Watch = new Stopwatch(); bool EventNeedsFiring = false; FileWatcherRaised = false; try { foreach (var fileName in Directory.EnumerateFiles(FolderPath, FileExtension, SearchOption.TopDirectoryOnly).ToArray()) { if (ShouldAbort) { return; } if (GetMovie(fileName) != null) { continue; } string NameXML = fileName.Substring(0, fileName.LastIndexOf(".")) + ".xml"; if (!File.Exists(NameXML)) { FileInfo Info = new FileInfo(fileName); Tuple <string, Stopwatch, long> CurrentState = GetIncubating(fileName); if (CurrentState == null) { Stopwatch Timer = new Stopwatch(); Timer.Start(); lock (Incubator) { Incubator.Add(new Tuple <string, Stopwatch, long>(fileName, Timer, Info.Length)); if (Incubator.Count == 1) { IncubationStarted?.Invoke(); } } } else { // Check if bool CanRead = false; try { File.OpenRead(fileName).Close(); CanRead = true; } catch { } if (Info.Length != CurrentState.Item3 || !CanRead) { lock (Incubator) Incubator.Remove(CurrentState); Stopwatch Timer = new Stopwatch(); Timer.Start(); lock (Incubator) Incubator.Add(new Tuple <string, Stopwatch, long>(fileName, Timer, Info.Length)); } else if (CurrentState.Item2.ElapsedMilliseconds > 1000) { //lock (Ripe) { if (!Ripe.Exists(m => m.Path == fileName)) { while (CreationTasks.Count > 15) { Thread.Sleep(1); } Task CreationTask = new Task(() => { Movie Created = null; if (!fileName.Substring(fileName.Length - 8).ToLower().Contains("tomostar")) { Created = new Movie(fileName, ParticleFileNames); } else { Created = new TiltSeries(fileName); } lock (Ripe) { // Make sure the list is sorted int InsertAt = 0; while (InsertAt < Ripe.Count && Ripe[InsertAt].Path.CompareTo(fileName) < 0) { InsertAt++; } Ripe.Insert(InsertAt, Created); } lock (CreationTasks) CreationTasks.Remove(fileName); }); lock (CreationTasks) CreationTasks.Add(fileName, CreationTask); CreationTask.Start(); } } EventNeedsFiring = true; if (!Watch.IsRunning) { Watch.Start(); } lock (Incubator) { Incubator.Remove(CurrentState); if (Incubator.Count == 0) { IncubationEnded?.Invoke(); } } } } if (EventNeedsFiring && Watch.ElapsedMilliseconds > 500) { //Task.WaitAll(CreationTasks.ToArray()); //CreationTasks.Clear(); Watch.Stop(); Watch.Reset(); EventNeedsFiring = false; FilesChanged?.Invoke(); } } else { //lock (Ripe) { if (!Ripe.Exists(m => m.Path == fileName)) { while (CreationTasks.Count > 15) { Thread.Sleep(1); } Task CreationTask = new Task(() => { Movie Created = null; if (!fileName.Substring(fileName.Length - 8).ToLower().Contains("tomostar")) { Created = new Movie(fileName, ParticleFileNames); } else { Created = new TiltSeries(fileName); } lock (Ripe) { // Make sure the list is sorted int InsertAt = 0; while (InsertAt < Ripe.Count && Ripe[InsertAt].Path.CompareTo(fileName) < 0) { InsertAt++; } Ripe.Insert(InsertAt, Created); } lock (CreationTasks) CreationTasks.Remove(fileName); }); lock (CreationTasks) CreationTasks.Add(fileName, CreationTask); CreationTask.Start(); } } EventNeedsFiring = true; if (!Watch.IsRunning) { Watch.Start(); } if (EventNeedsFiring && Watch.ElapsedMilliseconds > 500) { //Task.WaitAll(CreationTasks.ToArray()); //CreationTasks.Clear(); Watch.Stop(); Watch.Reset(); EventNeedsFiring = false; FilesChanged?.Invoke(); } } } } catch (Exception exc) { Debug.WriteLine("FileDiscoverer crashed:"); Debug.WriteLine(exc); if (ExceptionsLogged < 100) { using (TextWriter Writer = File.AppendText("d_filediscoverer.txt")) { Writer.WriteLine(DateTime.Now + ":"); Writer.WriteLine(exc.ToString()); Writer.WriteLine(""); ExceptionsLogged++; } } } while (CreationTasks.Count > 0) { Thread.Sleep(1); } if (EventNeedsFiring) { FilesChanged?.Invoke(); } while (!IsIncubating() && !FileWatcherRaised) { if (ShouldAbort) { return; } Thread.Sleep(50); } } }
private async void PerformRefinementIteration(ProcessingOptionsMPARefine options) { bool DoMultiProcess = true; #region Create worker processes int NDevices = GPU.GetDeviceCount(); List <int> UsedDevices = Options.MainWindow.GetDeviceList(); WorkerWrapper[] Workers = new WorkerWrapper[GPU.GetDeviceCount()]; string[] WorkerFolders = new string[Workers.Length]; string[] WorkerLogs = new string[Workers.Length]; foreach (var gpuID in UsedDevices) { WorkerFolders[gpuID] = System.IO.Path.Combine(ActivePopulation.FolderPath, "refinement_temp", $"worker{gpuID}"); Directory.CreateDirectory(WorkerFolders[gpuID]); } if (DoMultiProcess) { foreach (var gpuID in UsedDevices) { Workers[gpuID] = new WorkerWrapper(gpuID); Workers[gpuID].SetHeaderlessParams(new int2(2), 0, "float"); WorkerLogs[gpuID] = System.IO.Path.Combine(ActivePopulation.FolderPath, "refinement_temp", $"worker{gpuID}", "run.out"); } } #endregion var Progress = await this.ShowProgressAsync("Preparing for refinement – this will take a few minutes per species", ""); Progress.SetIndeterminate(); int ItemsCompleted = 0; int ItemsToDo = ActivePopulation.Sources.Select(s => s.Files.Count).Sum(); string[] CurrentlyRefinedItems = new string[GPU.GetDeviceCount()]; System.Timers.Timer StatusUpdater = null; if (DoMultiProcess) { StatusUpdater = new System.Timers.Timer(1001); StatusUpdater.Elapsed += (s, e) => { lock (CurrentlyRefinedItems) { StringBuilder StatusMessage = new StringBuilder(); foreach (var gpuID in UsedDevices) { if (CurrentlyRefinedItems[gpuID] == null) { continue; } try { string ItemMessage = File.ReadLines(WorkerLogs[gpuID]).Last(); StatusMessage.Append(CurrentlyRefinedItems[gpuID] + ": " + ItemMessage + "\n"); } catch { } } Dispatcher.Invoke(() => Progress.SetMessage(StatusMessage.ToString())); } }; } try { await Task.Run(() => { if (DoMultiProcess) { Helper.ForEachGPUOnce(gpuID => { Workers[gpuID].MPAPreparePopulation(ActivePopulation.Path); }, UsedDevices); foreach (var species in ActivePopulation.Species) { species.PrepareRefinementRequisites(false, 0); } } else { foreach (var species in ActivePopulation.Species) { Dispatcher.InvokeAsync(() => Progress.SetMessage($"Preprocessing {species.Name}...")); species.PrepareRefinementRequisites(); } } GPU.CheckGPUExceptions(); Dispatcher.InvokeAsync(() => Progress.SetTitle("Performing refinement")); Image.PrintObjectIDs(); //if (false) foreach (var source in ActivePopulation.Sources) { //break; Dispatcher.InvokeAsync(() => Progress.SetMessage($"Loading gain reference for {source.Name}...")); Image[] GainRefs = new Image[GPU.GetDeviceCount()]; try { if (DoMultiProcess) { Helper.ForEachGPUOnce(gpuID => { if (!string.IsNullOrEmpty(source.GainPath)) { Workers[gpuID].LoadGainRef(source.GainPath, source.GainFlipX, source.GainFlipY, source.GainTranspose); } else { Workers[gpuID].LoadGainRef("", false, false, false); } }, UsedDevices); } else { Image GainRef = source.LoadAndPrepareGainReference(); if (GainRef != null) { GainRefs = Helper.ArrayOfFunction(i => GainRef.GetCopy(), GPU.GetDeviceCount()); } } } catch { throw new Exception($"Could not load gain reference for {source.Name}."); } if (DoMultiProcess) { StatusUpdater.Start(); } Helper.ForEachGPU(source.Files, (pair, GPUID) => { if (DoMultiProcess) { lock (CurrentlyRefinedItems) CurrentlyRefinedItems[GPUID] = pair.Value; Workers[GPUID].MPARefine(source.FolderPath + pair.Value, WorkerFolders[GPUID], WorkerLogs[GPUID], options, source); lock (CurrentlyRefinedItems) CurrentlyRefinedItems[GPUID] = null; } else { Movie Item = null; if (source.IsTiltSeries) { Item = new TiltSeries(source.FolderPath + pair.Value); } else { Item = new Movie(source.FolderPath + pair.Value); } Dispatcher.InvokeAsync(() => Progress.SetTitle($"Refining {Item.Name}...")); Item.PerformMultiParticleRefinement(WorkerFolders[GPUID], options, ActivePopulation.Species.ToArray(), source, GainRefs[GPUID], (s) => { Dispatcher.InvokeAsync(() => { Progress.SetMessage(s); }); }); Item.SaveMeta(); GPU.CheckGPUExceptions(); } Dispatcher.Invoke(() => { ItemsCompleted++; Progress.Maximum = ItemsToDo; Progress.SetProgress(ItemsCompleted); }); return(false); }, 1, UsedDevices); if (DoMultiProcess) { StatusUpdater.Stop(); } source.Commit(); } Image.PrintObjectIDs(); Dispatcher.InvokeAsync(() => Progress.SetTitle("Finishing refinement")); if (DoMultiProcess) { Dispatcher.InvokeAsync(() => Progress.SetMessage("Saving intermediate results")); Helper.ForEachGPUOnce(gpuID => { Workers[gpuID].MPASaveProgress(WorkerFolders[gpuID]); Workers[gpuID].Dispose(); }, UsedDevices); Dispatcher.InvokeAsync(() => Progress.SetMessage("Gathering intermediate results")); ActivePopulation.GatherRefinementProgress(UsedDevices.Select(gpuID => WorkerFolders[gpuID]).ToArray()); foreach (var folder in WorkerFolders) { try { Directory.Delete(folder, true); } catch { } } } foreach (var species in ActivePopulation.Species) { Dispatcher.InvokeAsync(() => Progress.SetMessage($"Reconstructing and filtering {species.Name}...")); species.FinishRefinement(); species.Commit(); } }); } catch (Exception exc) { await Progress.CloseAsync(); await this.ShowMessageAsync("Oopsie", "Something went wrong during refinement. Sorry! Here are the details:\n\n" + exc.ToString()); } await Progress.CloseAsync(); }
private async void Movie_CTF1DChanged(object sender, EventArgs e) { try { AdjustGridVisibility(); if (Movie == null) { return; } TiltSeries Series = Movie as TiltSeries; bool NoDataAvailable = false; if ((Movie.GetType() == typeof(Movie) || ShowSeriesAverage) && (Movie.PS1D == null || Movie.Simulated1D == null)) { NoDataAvailable = true; } else if (Series != null && (Series.TiltPS1D.Count <= TiltID || Series.TiltPS1D[TiltID] == null)) { NoDataAvailable = true; } if (NoDataAvailable) { Plot1DSeriesExperimental.Values = null; Plot1DSeriesSimulated.Values = null; Plot1DSeriesQuality.Values = null; return; } //ProgressCTF1D.Visibility = Visibility.Visible; Movie movie = Movie; decimal fittingRangeMin = FittingRangeMin; //await Task.Delay(1000); await Task.Run(() => { float2[] ExperimentalData = (Series == null || _ShowSeriesAverage) ? movie.PS1D : Series.TiltPS1D[TiltID]; float2[] SimulatedData = (Series == null || _ShowSeriesAverage) ? movie.Simulated1D : Series.GetTiltSimulated1D(TiltID); Cubic1D ScaleData = (Series == null || _ShowSeriesAverage) ? movie.SimulatedScale : Series.TiltSimulatedScale[TiltID]; int N = ExperimentalData.Length * 2; ChartValues <ObservablePoint> ExperimentalValues = new ChartValues <ObservablePoint>(ExperimentalData.Select(p => new ObservablePoint(p.X *N, p.Y))); ChartValues <ObservablePoint> SimulatedValues = new ChartValues <ObservablePoint>(SimulatedData.Select(p => new ObservablePoint(p.X *N, p.Y))); CTF CTF = (Series == null || _ShowSeriesAverage) ? movie.CTF : Series.GetTiltCTF(TiltID); float[] Quality = CTF.EstimateQuality(ExperimentalData.Select(p => p.Y).ToArray(), ScaleData.Interp(ExperimentalData.Select(p => p.X).ToArray()), (float)fittingRangeMin, 16, true); Dispatcher.Invoke(() => { Plot1DSeriesExperimental.Values = ExperimentalValues; Plot1DSeriesSimulated.Values = SimulatedValues; Plot1DSeriesQuality.Values = new ChartValues <double>(Quality.Select(v => (double)Math.Max(0, v))); }); }); AdjustYAxis(); FittingRangeChanged(null, new DependencyPropertyChangedEventArgs()); //ProgressCTF1D.Visibility = Visibility.Hidden; } catch { } }