public static int3 GetMapDimensions(string path) { int3 Dims = new int3(1, 1, 1); FileInfo Info = new FileInfo(path); using (BinaryReader Reader = new BinaryReader(OpenWithBigBuffer(path))) { if (Info.Extension.ToLower() == ".mrc" || Info.Extension.ToLower() == ".mrcs") { HeaderMRC Header = new HeaderMRC(Reader); Dims = Header.Dimensions; } else if (Info.Extension.ToLower() == ".em") { HeaderEM Header = new HeaderEM(Reader); Dims = Header.Dimensions; } else { throw new Exception("Format not supported."); } } return(Dims); }
public static ImageTexture FromMRC(string path) { ImageTexture NewTexture = new ImageTexture(); HeaderMRC Header = HeaderMRC.ReadFromFile(path) as HeaderMRC; NewTexture.Size = Header.Dimensions; NewTexture.Scale = new Vector2(Header.Pixelsize.X, Header.Pixelsize.Y); NewTexture.Offset = new Vector2(Header.Origin.X, Header.Origin.Y); float[] Data = IOHelper.ReadSmallMapFloat(path, new int2(1, 1), 0, typeof(float)); float DataMin = float.MaxValue, DataMax = -float.MaxValue; for (int i = 0; i < Data.Length; i++) { DataMin = Math.Min(DataMin, Data[i]); DataMax = Math.Max(DataMax, Data[i]); } float Range = 255f / (DataMax - DataMin); byte[] DataByte = new byte[Data.Length]; for (int i = 0; i < Data.Length; i++) { DataByte[i] = (byte)((Data[i] - DataMin) * Range); } NewTexture.Data = DataByte; return(NewTexture); }
public void WriteMRC(string path, HeaderMRC header = null) { if (header == null) { header = new HeaderMRC(); } header.Dimensions = IsFT ? DimsFT : Dims; header.Dimensions.X *= IsComplex ? 2 : 1; float[][] Data = GetHost(Intent.Read); float Min = float.MaxValue, Max = -float.MaxValue; Parallel.For(0, Data.Length, z => { float LocalMin = MathHelper.Min(Data[z]); float LocalMax = MathHelper.Max(Data[z]); lock (Data) { Min = Math.Min(LocalMin, Min); Max = Math.Max(LocalMax, Max); } }); header.MinValue = Min; header.MaxValue = Max; IOHelper.WriteMapFloat(path, header, GetHost(Intent.Read)); }
public static VolumeTexture FromMRC(string path) { VolumeTexture NewTexture = new VolumeTexture(); HeaderMRC Header = HeaderMRC.ReadFromFile(path) as HeaderMRC; NewTexture.Size = Header.Dimensions; NewTexture.Scale = new Vector3(Header.Pixelsize.X, Header.Pixelsize.Y, Header.Pixelsize.Z); NewTexture.Offset = new Vector3(Header.Origin.X, Header.Origin.Y, Header.Origin.Z); unsafe { float[] OriginalData = IOHelper.ReadSmallMapFloat(path, new int2(1, 1), 0, typeof(float)); float DataMin = float.MaxValue, DataMax = float.MinValue; fixed(float *DataPtr = OriginalData) { float *DataP = DataPtr; for (int i = 0; i < OriginalData.Length; i++) { DataMin = Math.Min(DataMin, *DataP); DataMax = Math.Max(DataMax, *DataP++); } float Range = (DataMax - DataMin) / 255f; byte[] DataByte = new byte[OriginalData.Length]; fixed(byte *DataBytePtr = DataByte) { byte *DataByteP = DataBytePtr; DataP = DataPtr; for (int i = 0; i < OriginalData.Length; i++) { *DataByteP++ = (byte)((*DataP++ - DataMin) / Range); } } NewTexture.Data = DataByte; } NewTexture.OriginalData = OriginalData; } return(NewTexture); }
public void UpdateDepiction() { if (DepictionMesh != null) { DepictionMesh.Dispose(); DepictionMesh = null; } foreach (var point in Points) { point.DropDepictionMesh(); } //if (Points.Count == 0) //return; if (Depiction == PointDepiction.Mesh && File.Exists(DepictionMeshPath)) { FileInfo Info = new FileInfo(DepictionMeshPath); if (Info.Extension.ToLower().Contains("mrc")) { HeaderMRC VolumeHeader = (HeaderMRC)MapHeader.ReadFromFile(DepictionMeshPath); float[] VolumeData = IOHelper.ReadSmallMapFloat(DepictionMeshPath, new int2(1, 1), 0, typeof(float)); Mesh NewMesh = Mesh.FromVolume(VolumeData, VolumeHeader.Dimensions, VolumeHeader.Pixelsize.X, (float)DepictionMeshLevel); NewMesh.UsedComponents = MeshVertexComponents.Position | MeshVertexComponents.Normal; NewMesh.GLContext = MainWindow.Options.Viewport.GetControl(); NewMesh.UpdateBuffers(); _DepictionMesh = NewMesh; } else if (Info.Extension.ToLower().Contains("obj")) { Mesh NewMesh = Mesh.FromOBJ(DepictionMeshPath, true); NewMesh.UsedComponents = MeshVertexComponents.Position | MeshVertexComponents.Normal; NewMesh.GLContext = MainWindow.Options.Viewport.GetControl(); NewMesh.UpdateBuffers(); _DepictionMesh = NewMesh; } } else if (Depiction == PointDepiction.LocalSurface && MainWindow.Options.Membrane.TomogramTexture != null) { int3 DimsExtract = new int3((int)Size + 2, (int)Size + 2, (int)Size + 2); Parallel.ForEach(Points, point => { Vector3 TomoPos = (point.Position - MainWindow.Options.Membrane.TomogramTexture.Offset) / MainWindow.Options.PixelScale.X; int3 TomoPosInt = new int3((int)Math.Round(TomoPos.X), (int)Math.Round(TomoPos.Y), (int)Math.Round(TomoPos.Z)); float[] LocalVol = Helper.Extract(MainWindow.Options.Membrane.TomogramTexture.OriginalData, MainWindow.Options.Membrane.TomogramTexture.Size, TomoPosInt, DimsExtract); if (DepictionLocalSurfaceInvert) { for (int i = 0; i < LocalVol.Length; i++) { LocalVol[i] = -LocalVol[i]; } } for (int z = 0; z < DimsExtract.Z; z++) { for (int y = 0; y < DimsExtract.Y; y++) { for (int x = 0; x < DimsExtract.X; x++) { if (z == 0 || y == 0 || x == 0 || z == DimsExtract.Z - 1 || y == DimsExtract.Y - 1 || x == DimsExtract.X - 1) { LocalVol[(z * DimsExtract.Y + y) * DimsExtract.X + x] = -99999; } } } } bool[] Mask = new bool[LocalVol.Length]; float Threshold = (float)DepictionLocalSurfaceLevel; if (DepictionLocalSurfaceOnlyCenter) { int MostCentralID = -1; float MostCentralDist = DimsExtract.X * DimsExtract.X; // Find most central valid pixel in the local window to start mask expansion from there. for (int z = 1; z < DimsExtract.Z - 1; z++) { int zz = z - DimsExtract.Z / 2; zz *= zz; for (int y = 1; y < DimsExtract.Y - 1; y++) { int yy = y - DimsExtract.Y / 2; yy *= yy; for (int x = 1; x < DimsExtract.X - 1; x++) { if (LocalVol[(z * DimsExtract.Y + y) * DimsExtract.X + x] >= Threshold) { int xx = x - DimsExtract.X / 2; xx *= xx; float r = xx + yy + zz; if (r < MostCentralDist) { MostCentralDist = r; MostCentralID = (z * DimsExtract.Y + y) * DimsExtract.X + x; } } } } } if (MostCentralID < 0) // Volume doesn't contain voxels above threshold { return; } Mask[MostCentralID] = true; for (int mi = 0; mi < Size / 2; mi++) { bool[] NextMask = new bool[Mask.Length]; for (int z = 1; z < DimsExtract.Z - 1; z++) { for (int y = 1; y < DimsExtract.Y - 1; y++) { for (int x = 1; x < DimsExtract.X - 1; x++) { int ID = (z * DimsExtract.Y + y) * DimsExtract.X + x; if (LocalVol[ID] >= Threshold) { if (Mask[ID] || Mask[ID + 1] || Mask[ID - 1] || Mask[ID + DimsExtract.X] || Mask[ID - DimsExtract.X] || Mask[ID + DimsExtract.Y * DimsExtract.X] || Mask[ID - DimsExtract.Y * DimsExtract.X]) { NextMask[ID] = true; } } } } } Mask = NextMask; } } else { for (int i = 0; i < Mask.Length; i++) { Mask[i] = true; } } // Apply spherical mask int Size2 = (int)(Size * Size / 4); for (int z = 1; z < DimsExtract.Z - 1; z++) { int zz = z - DimsExtract.Z / 2; zz *= zz; for (int y = 1; y < DimsExtract.Y - 1; y++) { int yy = y - DimsExtract.Y / 2; yy *= yy; for (int x = 1; x < DimsExtract.X - 1; x++) { int xx = x - DimsExtract.X / 2; xx *= xx; int r2 = xx + yy + zz; Mask[(z * DimsExtract.Y + y) * DimsExtract.X + x] &= r2 < Size2; } } } for (int i = 0; i < Mask.Length; i++) { if (!Mask[i]) { LocalVol[i] = Math.Min(LocalVol[i], Threshold - 1e-5f); } } //IOHelper.WriteMapFloat("d_extract.mrc", HeaderMRC.ReadFromFile("test_extract.mrc"), LocalVol); //IOHelper.WriteMapFloat("d_original.mrc", HeaderMRC.ReadFromFile("Tomo1L1_bin4.mrc"), MainWindow.Options.Membrane.TomogramTexture.OriginalData); point.DepictionMesh = Mesh.FromVolume(LocalVol, DimsExtract, MainWindow.Options.PixelScale.X, (float)DepictionLocalSurfaceLevel); point.DepictionMesh.UsedComponents = MeshVertexComponents.Position | MeshVertexComponents.Normal; }); foreach (var point in Points) { if (point.DepictionMesh == null) { continue; } point.DepictionMesh.GLContext = MainWindow.Options.Viewport.GetControl(); point.DepictionMesh.UpdateBuffers(); } } MainWindow.Options.Viewport.Redraw(); }
public void GrabScreenshot(string path) { MakeCurrent(); bool IsMRC = path.ToLower().Substring(path.Length - 3) == "mrc"; Color ScreenshotBackground = IsMRC ? Colors.Black : Colors.White; Color OldBackground = BackgroundColor; if (IsMRC) { BackgroundColor = ScreenshotBackground; Redraw(); } Bitmap bmp = new Bitmap(GLControl.ClientSize.Width, GLControl.ClientSize.Height); System.Drawing.Imaging.BitmapData data = bmp.LockBits(GLControl.ClientRectangle, System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); GL.ReadPixels(0, 0, GLControl.ClientSize.Width, GLControl.ClientSize.Height, PixelFormat.Bgr, PixelType.UnsignedByte, data.Scan0); bmp.UnlockBits(data); if (!IsMRC) { bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); using (Stream ImageStream = File.Create(path)) { bmp.Save(ImageStream, System.Drawing.Imaging.ImageFormat.Png); } } else { using (BinaryWriter Writer = new BinaryWriter(File.Create(path))) { HeaderMRC Header = new HeaderMRC { Dimensions = new int3(bmp.Width, bmp.Height, 1), Mode = MRCDataType.Byte }; Header.Write(Writer); int Elements = bmp.Width * bmp.Height; byte[] Data = new byte[Elements]; System.Drawing.Imaging.BitmapData BitmapData = bmp.LockBits(GLControl.ClientRectangle, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); unsafe { fixed(byte *DataPtr = Data) { byte *BitmapDataP = (byte *)BitmapData.Scan0; for (int i = 0; i < Elements; i++) { DataPtr[i] = BitmapDataP[i * 4 + 1]; } } } bmp.UnlockBits(BitmapData); Writer.Write(Data); } BackgroundColor = OldBackground; } }