【WPF C#】PorphyStruct类卟啉和类咕啉的结构分析

news2025/1/11 16:00:51

前言

    首先,热烈祝贺家姐申请到了国家自然科学基金(8月底),找一些化学领域的程序和软件,助我姐一臂之力,顺便自己研究一下源码。

卟啉类化合物的结构分析

PorphyStruct,一种用于分析不同卟啉类非平面畸变模式的新型数字工具 - 该程序利用法向坐标结构分解技术 (NSD),并采用与为卟啉建立的等效的法向模式组来描述定量地计算来自corroles、norcorroles、porphycenes 和其他卟啉类化合物的周边原子的面外位错模式,并与已建立的术语进行类比。

87b7152b931473843204d0ede3433065.png

e6c0ad85d78b8dabe0181d6e0db9f174.png

79735d3d7cc1e6d04bce2dfcaeb35758.png

2460b270b5c8af8a5ad654076ff0f140.png

结语

      业余时间对于机器学习及其在化学领域的应用研究也该提上日程了。对机器学习的研究也为将来将其应用到工业领域各个方面做好准备。

f0fbf25125c0e6e2de8db3f4346056bb.png

87c96f81839bccd3a7ffd20dd73b046a.png

5a20377060201de4c4ffd46069c2d55e.png

附-程序主界面交互逻辑:

using System.Diagnostics;
using System.Reflection;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Navigation;
using ChemSharp.Mathematics;
using ChemSharp.Molecules.HelixToolkit;
using HelixToolkit.Wpf;
using Microsoft.Win32;
using PorphyStruct.Core;
using PorphyStruct.ViewModel;
using PorphyStruct.ViewModel.IO;
using ThemeCommons.Controls;
using MacrocycleViewModel = PorphyStruct.ViewModel.Windows.MacrocycleViewModel;


namespace PorphyStruct.WPF;


/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : DefaultWindow//MainWindow` 类包含了主窗口的各种操作和事件处理方法,用于管理应用程序的主要功能,包括打开文件、分析数据、保存结果、查看统计信息等
{
    public MacrocycleViewModel ViewModel { get; private set; }


    /// <summary>
    /// Should not be null!
    /// </summary>
    public static string Version => Assembly.GetEntryAssembly()!.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!
        .InformationalVersion!;


    public MainWindow()
    {
        Settings.Instance.Load();// 加载应用程序设置
        Atom3D.SelectionColor = Brushes.Fuchsia;// 设置选中的原子颜色
        InitializeComponent();// 初始化主窗口
        CheckUpdate(); // 检查更新
    }


    /// <summary>
    /// Checks for new Versions on Startup在启动时检查新版本
    /// </summary>
    private async void CheckUpdate(bool force = false)
    {
        if (!Settings.Instance.AutoUpdate && !force) return;// 如果禁用自动更新或不强制更新,直接返回
        (Updater u, bool current) = await Updater.CreateAsync(); // 创建 Updater 实例来检查更新
        if (!current) UpdateMsg.Visibility = Visibility.Visible;// 如果不是最新版本,显示更新消息
        else if (force) MessageBox.Show($"You already have the latest Version of PorphyStruct ({u.Latest})");// 如果是强制更新,显示已经是最新版本的消息
        if (!current && force)
        {// 如果不是最新版本且需要强制更新,打开浏览器到最新版本的下载页面
            Process.Start(new ProcessStartInfo("http://github.com/jenskrumsieck/porphystruct/releases/latest") { UseShellExecute = true });
            UpdateMsg.Visibility = Visibility.Collapsed;
        }
    }


    /// <summary>
    /// Handles Atom selection// 处理鼠标左键点击 3D 视图中的原子选择
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Viewport3D_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var hits = Viewport3D.Viewport.FindHits(e.GetPosition(Viewport3D));
        foreach (var hit in hits.OrderBy(s => s.Distance))
        {
            if (hit.Visual.GetType() != typeof(Atom3D)) continue;
            var av3d = hit.Visual as Atom3D;
            if (av3d != null) ViewModel.SelectedAtom = av3d.Atom;
        }
    }


    /// <summary>
    /// Drag and Drop Handler// 处理拖放文件到窗口的操作
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    /// <exception cref="InvalidOperationException"></exception>
    private void OnFileDrop(object sender, DragEventArgs e)
    {
        if (!e.Data.GetDataPresent(DataFormats.FileDrop)) return;
        var files = (string[])e.Data.GetData(DataFormats.FileDrop, false);
        OpenFile((files ?? throw new InvalidOperationException()).First());
    }


    /// <summary>
    /// Handles open File Dialog/ 处理打开文件对话框的操作
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Open_OnClick(object sender, RoutedEventArgs e)
    {
        var path = string.IsNullOrEmpty(Settings.Instance.DefaultImportPath)
            ? Environment.GetFolderPath(Environment.SpecialFolder.Desktop)//Environment.SpecialFolder.Desktop
            : Settings.Instance.DefaultImportPath;
        var ofd = new OpenFileDialog
        {
            InitialDirectory = "V:\\learn\\chem\\tests-data-master\\data",//path
            Filter = Constants.OpenFileFilter,
            Multiselect = false
        };
        if (ofd.ShowDialog(this) != true) return;
        OpenFile(ofd.FileName);
    }


    /// <summary>
    /// Handles actual file opening// 处理实际的文件打开操作
    /// </summary>
    /// <param name="path"></param>
    internal void OpenFile(string path)
    {
        DataContext = ViewModel = new MacrocycleViewModel(path);
        ViewModel.SelectedIndexChanged += ViewModelOnSelectedIndexChanged;
        Viewport3D.CameraController.CameraTarget =
            MathV.Centroid(ViewModel.Macrocycle.Atoms.Select(s => s.Location).ToList()).ToPoint3D();
        Activate();
    }
    // 处理选中索引更改事件
    private void ViewModelOnSelectedIndexChanged(object? sender, EventArgs e)
    {
        if (ViewModel?.SelectedItem != null)
            Viewport3D.CameraController.CameraTarget =
                MathV.Centroid(ViewModel.SelectedItem.Analysis.Atoms.Select(s => s.Location)).ToPoint3D();// 设置相机目标到选中的分析对象
        MainTabMenu.Focus();// 焦点切换到主选项卡菜单
    }
    // 准备分析操作
    private async Task PrepareAnalysis()
    {
        //Block UI interaction during this// 阻止在此期间的用户界面交互
        MainGrid.IsEnabled = false;
        TitleGrid.IsEnabled = false;
        AnalyzePopup.IsOpen = false;
        await ViewModel.Analyze();// 调用分析操作
        MainGrid.IsEnabled = true;
        TitleGrid.IsEnabled = true;
    }
    // 处理分析按钮的点击事件
    private async void Analyze_OnClick(object sender, RoutedEventArgs e)
    {
        Settings.Instance.UseExtendedBasis = false;
        await PrepareAnalysis();
    }
    // 处理扩展分析按钮的点击事件
    private async void AnalyzeExt_OnClick(object sender, RoutedEventArgs e)
    {
        Settings.Instance.UseExtendedBasis = true;
        await PrepareAnalysis();
    }
    // 处理旋转按钮的点击事件   对当前选定的项目或数据执行旋转操作。具体的旋转操作可能包括旋转、缩放或平移等,这取决于项目或数据的类型和应用的功能
    private void Rotate_OnClick(object sender, RoutedEventArgs e) => ViewModel.SelectedItem.Rotate();
    // 处理保存按钮的点击事件   在用户点击保存按钮时,打开一个保存窗口,允许用户选择保存选定的项目或数据的位置和文件名
    private void Save_OnClick(object sender, RoutedEventArgs e)
    {
        var sw = new SaveWindow(ViewModel.SelectedItem);
        sw.ShowDialog();
    }
    // 处理 URL 链接点击事件   允许用户点击一个URL链接后,在默认的Web浏览器中打开该链接,以便用户可以访问相关的在线资源或链接
    private void URL_OnClicked(object sender, RequestNavigateEventArgs e) =>
        Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true });
    // 处理信息按钮的点击事件  在用户点击信息按钮时,显示或隐藏一个信息弹出窗口,以便用户可以查看额外的信息或说明
    private void Info_OnClick(object sender, RoutedEventArgs e) => TogglePopup(InfoPopup);
    // 处理追加按钮的点击事件
    /*这段代码的作用是允许用户添加新的比较数据。它首先从 `AppendedData` 中获取用户选择的数据,
     * 然后将不再需要的比较数据从列表中移除,接着将用户选择的本地数据添加到比较数据中,
     * 最后准备新的比较数据并切换比较弹出窗口的可见性,以便用户查看比较结果*/
    private void Append_OnClick(object sender, RoutedEventArgs e)
    {
        var path = string.IsNullOrEmpty(Settings.Instance.DefaultImportPath)
            ? Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
            : Settings.Instance.DefaultImportPath;
        var ofd = new OpenFileDialog
        {
            InitialDirectory = path,
            Filter = Constants.CompareFileFilter,
            Multiselect = false
        };
        if (ofd.ShowDialog(this) != true) return;
        var data = new CompareData(ofd.FileName);
        ViewModel.SelectedItem.CompareData.Add(data);
        AppendedData.SelectedItems.Add(data);
    }
    // 处理比较追加按钮的点击事件
    private void CompareAdd_OnClick(object sender, RoutedEventArgs e)
    {
        var appendedData = AppendedData.SelectedItems.Cast<CompareData>().ToList();
        var remove = ViewModel.SelectedItem.CompareData.Except(appendedData);
        foreach (var item in remove) ViewModel.SelectedItem.CompareData.Remove(item);//将不包含在 `appendedData` 中的项添加到 `remove` 列表中。
        var localData = LocalData.SelectedItems.Cast<AnalysisViewModel>();//一个 `AnalysisViewModel` 类型的列表,它表示用户从本地数据中选择的项。
        foreach (var item in localData)// 对于每个 `localData` 中的项,创建一个新的 `CompareData`,并将其添加到 `ViewModel.SelectedItem.CompareData` 中
            ViewModel.SelectedItem.CompareData.Add(new CompareData(item.Title, item.Analysis.DataPoints.ToList()));
        ViewModel.SelectedItem.PrepareCompare();//准备比较数据,可能会重新计算一些比较数据。
        TogglePopup(ComparePopUp);//切换比较弹出窗口的可见性
    }
    // 处理比较按钮的点击事件  在用户点击比较按钮时,清除之前的比较数据并重新准备新的比较数据,然后切换比较弹出窗口的可见性,以便用户查看比较结果。
    private void Compare_OnClick(object sender, RoutedEventArgs e)
    {
        ViewModel.SelectedItem.CompareData.Clear();//清除已存储的比较数据
        ViewModel.SelectedItem.PrepareCompare();//准备比较数据,可能会重新计算一些比较数据。
        TogglePopup(ComparePopUp);//切换比较弹出窗口的可见性,如果当前是可见的,则隐藏它;如果当前是隐藏的,则显示它。
    }
    // 切换弹出窗口的可见性
    private static void TogglePopup(UIElement sender) => sender.Visibility =
        sender.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
    // 处理设置按钮的点击事件
    private void Settings_OnClick(object sender, RoutedEventArgs e) => new SettingsWindow().ShowDialog();
    // 处理统计信息按钮的点击事件
    private void Stats_OnClick(object sender, RoutedEventArgs e) => new StatisticsWindow().Show();
    // 处理批处理按钮的点击事件
    private void Batch_OnClick(object sender, RoutedEventArgs e) => new BatchWindow().Show();
    // 处理隔离按钮的点击事件
    private void Isolation_OnClick(object sender, RoutedEventArgs e) => new IsolationWindow(this).ShowDialog();


    /// <summary>
    /// Shows Analyze Popup显示分析弹出窗口
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void AnalyzeBtn_Click(object sender, RoutedEventArgs e) => AnalyzePopup.IsOpen = true;
    // 处理更新按钮的点击事件
    private void Update_Click(object sender, RoutedEventArgs e) => CheckUpdate(true);
}

参考源码:

https://github.com/JensKrumsieck/PorphyStruct 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/981598.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tlog实现链路追踪

tlog实现链路追踪 TLog通过对日志打标签完成企业级微服务的日志追踪。它不收集日志&#xff0c;使用简单&#xff0c; 产生全局唯一追踪码。除了追踪码&#xff0c;TLog还支持SpanId和上下游服务信息 标签的追加。你还可以自定义方法级别的标签&#xff0c;让日志的定位轻而易…

春秋云镜 CVE-2017-5638

春秋云镜 CVE-2017-5638 S2-045/S2-046 靶标介绍 2.3.32 之前的 Apache Struts 2 2.3.x 和 2.5.10.1 之前的 2.5.x 中的 Jakarta Multipart 解析器在文件上传尝试期间具有不正确的异常处理和错误消息生成&#xff0c;这允许远程攻击者通过精心制作的内容执行任意命令-Type、C…

Mysql 流程控制

简介 我们可以在存储过程和函数中实现比较复杂的业务逻辑&#xff0c;但是需要对应的流程控制语句来控制&#xff0c;就像Java中分支和循环语句一样&#xff0c;在MySQL中也提供了对应的语句&#xff0c;接下来就详细的介绍下。 1.分支结构 1.1 IF语句 IF 表达式1 THEN 操作1…

亚信科技AntDB数据库携“U8C+AntDB联合产品”亮相“2023全球商业创新大会”,开启生态合作新篇章

8月18-19日&#xff0c;近万人齐聚上海国家会展中心&#xff0c;带着对数字化、数智化趋势和热点的关注&#xff0c;以满腹热情投身到以“数据驱动 智能运营”为主题的“2023全球商业创新大会”&#xff0c;共商新技术条件下企业信息化出现的新课题、新挑战&#xff0c;共享数智…

【MQTT接收数据写入数据库】

MQTT接收数据写入数据库 1.搭建MQTT服务器 参考上一篇文章 2.安装数据库mysql sudo apt update sudo apt install mysql-server创建一个数据库和数据表存储mqtt消息 首先&#xff0c;登录到MySQL服务器&#xff1a; mysql -u root -p输入你的root用户密码。默认root 3.创…

Json字符串内容比较-超实用版

背景 之前有类似接口diff对比&#xff0c;数据对比的测试需求&#xff0c;涉及到json格式的数据对比&#xff0c;调研了几个大神们分享的代码&#xff0c;选了一个最符合自己需求的研究了下。 说明 这个对比方法&#xff0c;支持JsonObject和JsonArray类型的数据对比&#x…

攻防世界-crypto-工业协议分析2

打开附件得到 尝试直接搜索flag关键字&#xff0c;未果 发现存在关于ARP、UDP、SNA协议的流量包&#xff0c;仔细分析后发现大量的UDP包大小都一样&#xff0c;只有少量的是不同的&#xff0c;一个一个找下去&#xff0c;发现如下包有异常字符&#xff1a; 提取字符串&#xff…

MyBatis: 向oracle表中插入null字段的处理

一、可以在SQL中指定类型&#xff1a; Insert("insert into student values(#{name},#{age})")二、可以进行全局配置&#xff08;单独使用MyBatis时可如下配置&#xff09; 如果不进行配置&#xff0c;将报错

移动安全测试框架-MobSF WINDOWS 环境搭建

安装python python-3.11.5-amd64.exe 安装Win64OpenSSL-3_1_2.exe 安装VisualStudioSetup.exe github下载安装包 https://github.com/MobSF/Mobile-Security-Framework-MobSF/archive/refs/heads/master.zip GitHub - MobSF/Mobile-Security-Framework-MobSF: Mobile Secur…

【Apollo】自动驾驶技术的介绍

阿波罗是百度发布的名为“Apollo&#xff08;阿波罗&#xff09;”的向汽车行业及自动驾驶领域的合作伙伴提供的软件平台。 帮助汽车行业及自动驾驶领域的合作伙伴结合车辆和硬件系统&#xff0c;快速搭建一套属于自己的自动驾驶系统。 百度开放此项计划旨在建立一个以合作为中…

2023年软件测试常见面试题

测试花费的成本&#xff0c;要深入在那个环节上&#xff0c;&#xff08;前提准备上&#xff0c;需求理解上&#xff0c;业务逻辑&#xff0c;排错上&#xff0c;业务名词上理解&#xff0c;通过什么样的方法&#xff0c;有谁能解决这样的问题&#xff09; 软性热身题 1.自我…

Matlab图像处理-高斯低通滤波器

高通滤波 图像的边缘、细节主要位于高频部分&#xff0c;而图像的模糊是由于高频成分比较弱产生的。高通滤波就是为了高消除模糊&#xff0c;突出边缘。因此采用高通滤波器让高频成分通过&#xff0c;消除低频噪声成分削弱&#xff0c;再经傅里叶逆变换得到边缘锐化的图像。 …

C语言基础(下)

结构体 结构体类型的声明 结构体是一些值得集合&#xff0c;这些值称为成员变量。结构体得每个成员可以是不同类型得变量。 语法&#xff1a;struct tag{member-list;}variable-list;创建方法一&#xff1a;&#xff08;普通创建&#xff09; struct Stu {char name[20];char…

在Windows配置PPPoE连接

PPPoE&#xff08;Point-to-Point Protocol over Ethernet&#xff09;是一种常用的网络接入方式&#xff0c;广泛应用于家庭宽带、企业互联网等场景。本文将为您提供详细步骤和示例来指导如何在Windows操作系统上进行PPPoE连接的设置与配置。 1. 打开网络和共享中心 首先&…

关于在ts中使用最新版redux的方法记录

1.首先在react-ts项目中引入redux&react-redux npm i --save redux react-redux 2.redux文件及目录建设 3.文件说明 Store.ts&#xff1a;为入口文件 reducers: 为多个reducer独立文件&#xff0c;并且每个reducer都设置自己的类型注解文件 代码展示如下&#xff1a;…

zemax简单非序列光学系统

切换到非序列模式&#xff1a; 建立一个标准面&#xff0c;设置为抛物面&#xff0c;反射 添加灯丝光源&#xff1a; 陈列光线条数是图中蓝色光线的数目&#xff0c;分析光线条数是后续计算用到的光线条数 匝数&#xff08;圈数&#xff09;和长度、曲率半径决定了灯丝光源的形…

【Git】删除本地分支;报错error: Cannot delete branch ‘wangyunuo-test‘ checked out at ‘XXX‘

目录 0.环境 1.问题描述 2.解决步骤 1&#xff09;使用命令切换到其他分支 2&#xff09;查看当前本地所有分支 3&#xff09;删除“wangyunuo-test”分支 0.环境 windows 11 64位 Git VScode跑代码 1.问题描述 在做项目过程中&#xff0c;想删除一个本地分支“wangyun…

下载JDK及配置环境变量

Oracle网址 Java Downloads | Oracle 环境变量的配置 1. 在系统变量中新建名 JAVA_HOME 的变量 值为你jdk按照的文件目录 2. 在系统变量里面新建一个CLASSPATH变量&#xff0c;其变量值如下图所示&#xff08;此处需要注意&#xff1a;最前面有一个英文状态下的小圆点&#x…

git branch 分支

分支的定义 一个分支是git一个可移动的指针&#xff0c;指向某次提交。每次提交后&#xff0c;当前分支指针就往前挪一个&#xff0c;挪到最新的提交上。 HEAD 指向当前活动的分支 master 默认分支名 &#xff08;git init命令 默认创建它&#xff09; 常见分支指令 创建一个…

电子元器件采购的数字化转型:智能采购工具的应用

电子元器件采购的数字化转型是采购领域的一项重要趋势&#xff0c;智能采购工具的应用在此过程中发挥了关键作用。以下是智能采购工具在电子元器件采购数字化转型中的应用方面的一些关键点&#xff1a; 供应链可见性&#xff1a; 智能采购工具可以提供对供应链的实时可见性。通…