This repository has been archived on 2022-07-04. You can view files and clone it, but cannot push or open issues or pull requests.
Multichannel-Analyzer/MCA/MainFrm.cpp

712 lines
21 KiB
C++
Raw Normal View History

2022-03-19 20:43:29 +08:00

// MainFrm.cpp: CMainFrame 类的实现
//
2022-06-03 01:26:26 +08:00
#include <math.h>
#include <chrono>
#include <fstream>
#include <sstream>
#include <iostream>
2022-03-19 20:43:29 +08:00
#include "pch.h"
#include "framework.h"
2022-03-20 15:14:44 +08:00
#include "MCA.h"
2022-06-03 01:26:26 +08:00
#include "Matrix.h"
2022-03-19 20:43:29 +08:00
#include "MainFrm.h"
2022-03-20 15:14:44 +08:00
#include "TotalView.h"
#include "DetailView.h"
#include "ControlView.h"
2022-03-20 15:14:44 +08:00
2022-03-19 20:43:29 +08:00
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CREATE()
ON_WM_TIMER()
2022-06-02 14:57:51 +08:00
ON_WM_CLOSE()
ON_COMMAND(ID_OPT_OPEN, &CMainFrame::OnOptOpen)
ON_COMMAND(ID_OPT_SAVE, &CMainFrame::OnOptSave)
ON_COMMAND(ID_STA_START, &CMainFrame::OnStaStart)
ON_COMMAND(ID_STA_STOP, &CMainFrame::OnStaStop)
ON_COMMAND(ID_STA_CLEAR, &CMainFrame::OnStaClear)
ON_COMMAND(ID_SIMU_CO, &CMainFrame::OnSimuCo)
ON_COMMAND(ID_SIMU_CS, &CMainFrame::OnSimuCs)
ON_COMMAND(ID_SIMU_NA, &CMainFrame::OnSimuNa)
ON_COMMAND(ID_AXIS_LINEAR, &CMainFrame::OnAxisLinear)
ON_COMMAND(ID_AXIS_LOG, &CMainFrame::OnAxisLog)
ON_COMMAND(ID_RANGE_AUTO, &CMainFrame::OnRangeAuto)
ON_COMMAND(ID_RANGE_D4, &CMainFrame::OnRangeD4)
ON_COMMAND(ID_RANGE_D2, &CMainFrame::OnRangeD2)
ON_COMMAND(ID_RANGE_M2, &CMainFrame::OnRangeM2)
ON_COMMAND(ID_RANGE_M4, &CMainFrame::OnRangeM4)
ON_COMMAND(ID_DATA_ORIGIN, &CMainFrame::OnDataOrigin)
ON_COMMAND(ID_DATA_3, &CMainFrame::OnData3)
ON_COMMAND(ID_DATA_5, &CMainFrame::OnData5)
2022-06-03 01:26:26 +08:00
ON_COMMAND(ID_DATA_PEAK, &CMainFrame::OnDataPeak)
ON_UPDATE_COMMAND_UI(ID_STA_START, &CMainFrame::OnUpdateStaStart)
ON_UPDATE_COMMAND_UI(ID_STA_STOP, &CMainFrame::OnUpdateStaStop)
ON_UPDATE_COMMAND_UI(ID_STA_CLEAR, &CMainFrame::OnUpdateStaClear)
ON_UPDATE_COMMAND_UI(ID_SIMU_CO, &CMainFrame::OnUpdateSimuCo)
ON_UPDATE_COMMAND_UI(ID_SIMU_CS, &CMainFrame::OnUpdateSimuCs)
ON_UPDATE_COMMAND_UI(ID_SIMU_NA, &CMainFrame::OnUpdateSimuNa)
ON_UPDATE_COMMAND_UI(ID_AXIS_LINEAR, &CMainFrame::OnUpdateAxisLinear)
ON_UPDATE_COMMAND_UI(ID_AXIS_LOG, &CMainFrame::OnUpdateAxisLog)
ON_UPDATE_COMMAND_UI(ID_RANGE_AUTO, &CMainFrame::OnUpdateRangeAuto)
ON_UPDATE_COMMAND_UI(ID_DATA_ORIGIN, &CMainFrame::OnUpdateDataOrigin)
ON_UPDATE_COMMAND_UI(ID_DATA_3, &CMainFrame::OnUpdateData3)
ON_UPDATE_COMMAND_UI(ID_DATA_5, &CMainFrame::OnUpdateData5)
2022-03-19 20:43:29 +08:00
END_MESSAGE_MAP()
static UINT indicators[] = {
2022-03-19 20:43:29 +08:00
ID_SEPARATOR, // 状态行指示器
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
// CMainFrame 构造/析构
CMainFrame::CMainFrame() noexcept {
2022-03-19 20:43:29 +08:00
// TODO: 在此添加成员初始化代码
}
CMainFrame::~CMainFrame() {
2022-03-19 20:43:29 +08:00
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
2022-03-19 20:43:29 +08:00
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("未能创建工具栏\n");
return -1; // 未能创建
}
if (!m_wndStatusBar.Create(this))
{
TRACE0("未能创建状态栏\n");
return -1; // 未能创建
}
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
// TODO: 如果不需要可停靠工具栏,则删除这三行
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
MoveWindow(0, 0, 2386, 1200);
CenterWindow();
2022-03-19 20:43:29 +08:00
OnLoadToolBarIcon();
2022-03-19 20:43:29 +08:00
return 0;
}
2022-06-02 14:57:51 +08:00
2022-03-19 20:43:29 +08:00
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,
CCreateContext* pContext) {
2022-03-20 15:14:44 +08:00
// 左右拆分窗口1行2列
VERIFY(m_wndSplitter.CreateStatic(this, 1, 2,
WS_CHILD | WS_VISIBLE, AFX_IDW_PANE_FIRST));
// 左侧窗口创建视图第0行第0列
VERIFY(m_wndSplitter.CreateView(0, 0,
RUNTIME_CLASS(CControlView), CSize(300, 0), pContext));
2022-03-20 15:14:44 +08:00
// 右侧窗口上下拆分2行1列
VERIFY(m_wndSplitter2.CreateStatic(&m_wndSplitter, 2, 1,
2022-03-20 15:14:44 +08:00
WS_CHILD | WS_VISIBLE, m_wndSplitter.IdFromRowCol(0, 1)));
// 右上窗口创建视图第0行第0列
VERIFY(m_wndSplitter2.CreateView(0, 0,
RUNTIME_CLASS(CTotalView), CSize(2086, 400), pContext));
2022-03-20 15:14:44 +08:00
// 右下窗口创建视图第1行第0列
VERIFY(m_wndSplitter2.CreateView(1, 0,
RUNTIME_CLASS(CDetailView), CSize(2086, 0), pContext));
2022-03-20 15:14:44 +08:00
return TRUE;
2022-03-19 20:43:29 +08:00
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) {
2022-03-19 20:43:29 +08:00
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
cs.style &= ~WS_THICKFRAME;
cs.style &= ~WS_MAXIMIZEBOX;
2022-03-19 20:43:29 +08:00
return TRUE;
}
void CMainFrame::OnLoadToolBarIcon() {
HICON icon;
m_imgList.Create(50, 50, TRUE | ILC_COLOR32, 10, 0);
icon = AfxGetApp()->LoadIconW(IDI_START);
m_imgList.Add(icon);
icon = AfxGetApp()->LoadIconW(IDI_STOP);
m_imgList.Add(icon);
icon = AfxGetApp()->LoadIconW(IDI_CLEAR);
m_imgList.Add(icon);
icon = AfxGetApp()->LoadIconW(IDI_FOLDER);
m_imgList.Add(icon);
icon = AfxGetApp()->LoadIconW(IDI_SAVE);
m_imgList.Add(icon);
icon = AfxGetApp()->LoadIconW(IDI_UP);
m_imgList.Add(icon);
icon = AfxGetApp()->LoadIconW(IDI_DOWN);
m_imgList.Add(icon);
icon = AfxGetApp()->LoadIconW(IDI_AUTO);
m_imgList.Add(icon);
icon = AfxGetApp()->LoadIconW(IDI_CLOSE);
m_imgList.Add(icon);
m_wndToolBar.GetToolBarCtrl().SetImageList(&m_imgList);
}
// CMainFrame 诊断
#ifdef _DEBUG
void CMainFrame::AssertValid() const {
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const {
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
int RoundupPowerof2(int val) {
if ((val & (val - 1)) == 0) return val;
int andv = 1 << 30;
while ((andv & val) == 0) andv = andv >> 1;
return andv << 1;
}
double GetMilliTime() {
std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()
);
return ms.count() / 1000.;
}
void CMainFrame::UpdateValue() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
// 更新显示曲线
for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = pDoc->m_nChannelCount[i];
if (pView->m_sSmoothType == "S3") SmoothThree();
else if (pView->m_sSmoothType == "S5") SmoothFive();
// 更新信息
pView->m_nTotalCount = pDoc->GetTotal(0, 1023);
pView->m_nMaxCount = pDoc->GetMax(0, 1023);
pView->m_nPartCount = pDoc->GetTotal(pView->m_nCursor1, pView->m_nCursor2);
pView->m_nCursorROICount = pDoc->m_nChannelCount[pView->m_nCursorROI];
pView->m_nTime += GetMilliTime() - pView->m_nT0;
pView->m_nTimeStr.Format(_T("%.1f"), pView->m_nTime);
pView->m_nT0 = GetMilliTime();
// 更新量程
if (pView->m_sRangeMode == "Auto") pView->m_nLC = RoundupPowerof2(pView->m_nMaxCount);
// 更新屏幕信息
pView->UpdateData(FALSE);
}
void CMainFrame::SaveFirst() {
int res = MessageBox(TEXT("打开前是否保存?"), TEXT("保存文件"), MB_YESNO | MB_ICONQUESTION);
if (res == IDYES) OnOptSave();
}
void CMainFrame::SmoothThree() {
pDoc->m_nChannelSmooth[0] = (5 * pDoc->m_nChannelCount[0] + 2 * pDoc->m_nChannelCount[1] - pDoc->m_nChannelCount[2]) / 6;
for (int i = 1; i < 1023; i++)
pDoc->m_nChannelSmooth[i] = (pDoc->m_nChannelCount[i - 1] + pDoc->m_nChannelCount[i] + pDoc->m_nChannelCount[i + 1]) / 3;
pDoc->m_nChannelSmooth[1023] = (5 * pDoc->m_nChannelCount[1023] + 2 * pDoc->m_nChannelCount[1022] - pDoc->m_nChannelCount[1021]) / 6;
for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = max(0, pDoc->m_nChannelSmooth[i]);
}
void CMainFrame::SmoothFive() {
pDoc->m_nChannelSmooth[0] = (3 * pDoc->m_nChannelCount[0] + 2 * pDoc->m_nChannelCount[1] + pDoc->m_nChannelCount[2] - pDoc->m_nChannelCount[4]) / 5;
pDoc->m_nChannelSmooth[1] = (4 * pDoc->m_nChannelCount[0] + 3 * pDoc->m_nChannelCount[1] + 2 * pDoc->m_nChannelCount[2] + pDoc->m_nChannelCount[3]) / 10;
for (int i = 2; i < 1022; i++)
pDoc->m_nChannelSmooth[i] = (pDoc->m_nChannelCount[i - 2] + pDoc->m_nChannelCount[i - 1] + pDoc->m_nChannelCount[i] + pDoc->m_nChannelCount[i + 1] + pDoc->m_nChannelCount[i + 2]) / 5;
pDoc->m_nChannelSmooth[1022] = (4 * pDoc->m_nChannelCount[1023] + 3 * pDoc->m_nChannelCount[1022] + 2 * pDoc->m_nChannelCount[1021] + pDoc->m_nChannelCount[1020]) / 10;
pDoc->m_nChannelSmooth[1023] = (3 * pDoc->m_nChannelCount[1023] + 2 * pDoc->m_nChannelCount[1022] + pDoc->m_nChannelCount[1021] - pDoc->m_nChannelCount[1019]) / 5;
for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = max(0, pDoc->m_nChannelSmooth[i]);
}
void CMainFrame::OnSimuCoOpt() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sSource = (CString)"Co60";
pView->m_ComboSource.SetCurSel(0);
m_bCoFlag = FALSE;
m_bCsFlag = TRUE;
m_bNaFlag = TRUE;
}
void CMainFrame::OnSimuCsOpt() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sSource = (CString)"Cs137";
pView->m_ComboSource.SetCurSel(1);
m_bCoFlag = TRUE;
m_bCsFlag = FALSE;
m_bNaFlag = TRUE;
}
void CMainFrame::OnSimuNaOpt() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sSource = (CString)"Na22";
pView->m_ComboSource.SetCurSel(2);
m_bCoFlag = TRUE;
m_bCsFlag = TRUE;
m_bNaFlag = FALSE;
}
// CMainFrame 消息处理程序
void CMainFrame::OnTimer(UINT_PTR nIDEvent) {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pDoc->SetModifiedFlag(TRUE);
// 判断终止
if ((pView->m_sMode == "Time" && pView->m_nTime >= pView->m_nCond) || (pView->m_sMode == "Count" && pView->m_nTotalCount >= pView->m_nCond))
2022-06-03 12:14:48 +08:00
OnStaStop();
else {
// 生成随机信号
int n = rand() % 10 + 5;
pDoc->RandomPeak(pView->m_sSource, n);
// 更新
UpdateValue();
}
pDoc->UpdateAllViews(NULL);
CFrameWnd::OnTimer(nIDEvent);
}
void CMainFrame::OnClose() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pDoc->IsModified()) {
int res = MessageBox(TEXT("退出前是否保存?"), TEXT("保存文件"), MB_YESNO | MB_ICONQUESTION);
if (res == IDYES) OnOptSave();
pDoc->SetModifiedFlag(FALSE);
}
CFrameWnd::OnClose();
}
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
if (pMsg->message == WM_KEYDOWN && pMsg->wParam >= 0x25 && pMsg->wParam <= 0x28) {
if (pMsg->wParam == VK_LEFT) pView->m_nCursorROI = max(pView->m_nCursor1, pView->m_nCursorROI - 1);
if (pMsg->wParam == VK_RIGHT) pView->m_nCursorROI = min(pView->m_nCursor2, pView->m_nCursorROI + 1);
if (pMsg->wParam == VK_UP) OnRangeM2();
if (pMsg->wParam == VK_DOWN) OnRangeD2();
2022-06-03 01:47:52 +08:00
pView->m_nWidth = pView->m_nCursor2 - pView->m_nCursor1 + 1;
pView->m_nCursorROICount = pDoc->m_nChannelCount[pView->m_nCursorROI];
pView->UpdateData(FALSE);
pDoc->UpdateAllViews(NULL);
return TRUE;
}
return CFrameWnd::PreTranslateMessage(pMsg);
}
void CMainFrame::OnOptOpen() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
if (pDoc->IsModified()) SaveFirst();
CString szFilter = (CString)"文本文件(*.txt)|*.txt|";
CFileDialog fileDlg(TRUE, (CString)"*.txt", NULL, OFN_OVERWRITEPROMPT, szFilter);
if (IDCANCEL == fileDlg.DoModal())
return;
CString szfile = fileDlg.GetPathName();
int k, cnt = 0;
int count[1024] = { 0 };
std::string line, tmp;
std::ifstream ifs(szfile);
try
{
2022-06-03 12:14:48 +08:00
// 获取时间
std::getline(ifs, line);
pView->m_nTime = 0;
pView->m_nT0 = GetMilliTime() - std::stof(line);
2022-06-03 12:14:48 +08:00
// 获取源
std::getline(ifs, line);
pView->m_sSource = line.c_str();
2022-06-03 12:14:48 +08:00
if (pView->m_sSource == "Cs137") OnSimuCs();
else if (pView->m_sSource == "Co60") OnSimuCo();
else OnSimuNa();
// 获取计数
while (std::getline(ifs, line))
{
std::stringstream ss(line);
std::getline(ss, tmp, ',');
k = std::stoi(tmp);
std::getline(ss, tmp, ',');
count[k] = std::stoi(tmp);
cnt += 1;
}
for (int i = 1; i < 1024; i++) pDoc->m_nChannelCount[i] = count[i];
2022-06-03 12:14:48 +08:00
// 其他设置
m_bClearFlag = TRUE;
pView->m_sRangeMode = "Auto";
2022-06-03 12:14:48 +08:00
pView->m_sSmoothType = "Origin";
UpdateValue();
pDoc->UpdateAllViews(NULL);
}
catch (const std::exception&)
{
AfxMessageBox((CString)"文件格式错误");
}
}
void CMainFrame::OnOptSave() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
CString szFilter = (CString)"文本文件(*.txt)|*.txt|";
CFileDialog fileDlg(FALSE, (CString)"*.txt", NULL, OFN_OVERWRITEPROMPT, szFilter);
if (IDCANCEL == fileDlg.DoModal())
return;
CString szfile = fileDlg.GetPathName();
std::ofstream ofs(szfile);
2022-06-03 12:20:35 +08:00
std::string str = CStringA(pView->m_sSource);
ofs << pView->m_nTime << std::endl;
2022-06-03 12:20:35 +08:00
ofs << str.c_str() << std::endl;
for (int i = 0; i < 1024; i++)
ofs << i << ", " << pDoc->m_nChannelCount[i] << std::endl;
AfxMessageBox((CString)"保存成功");
pDoc->SetModifiedFlag(FALSE);
}
void CMainFrame::OnStaStart() {
2022-06-03 12:14:48 +08:00
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
// 重置结束条件
pView->m_nT0 = GetMilliTime();
// 设置状态
m_bStartFlag = FALSE;
m_bStopFlag = TRUE;
m_bClearFlag = FALSE;
pView->SetCond(FALSE);
// 获取屏幕值至变量
pView->UpdateData(TRUE);
// 设置更新
SetTimer(1, 20, NULL);
}
void CMainFrame::OnUpdateStaStart(CCmdUI* pCmdUI) {
2022-06-03 12:14:48 +08:00
pCmdUI->Enable(m_bStartFlag);
}
void CMainFrame::OnStaStop() {
// 设置状态
m_bStartFlag = TRUE;
m_bStopFlag = FALSE;
m_bClearFlag = TRUE;
pView->SetCond(TRUE);
// 停止更新
KillTimer(1);
}
void CMainFrame::OnUpdateStaStop(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_bStopFlag);
}
void CMainFrame::OnStaClear() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
// 重置
pView->m_nLC = 4;
pView->m_nTime = 0;
pView->m_nMaxCount = 0;
pView->m_nPartCount = 0;
pView->m_nTotalCount = 0;
pView->m_nCursorROICount = 0;
pView->m_nTimeStr = (CString)"0.0";
// 更新屏幕信息
pView->UpdateData(FALSE);
// 设置曲线
for (int i = 0; i < 1024; i++) pDoc->m_nChannelCount[i] = 0;
for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = 0;
pDoc->UpdateAllViews(NULL);
pDoc->SetModifiedFlag(FALSE);
}
void CMainFrame::OnUpdateStaClear(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_bClearFlag);
}
void CMainFrame::OnSimuCo() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
OnSimuCoOpt();
OnStaStop();
OnStaClear();
}
void CMainFrame::OnUpdateSimuCo(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_bCoFlag);
}
void CMainFrame::OnSimuCs() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
OnSimuCoOpt();
OnStaStop();
OnStaClear();
}
void CMainFrame::OnUpdateSimuCs(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_bCsFlag);
}
void CMainFrame::OnSimuNa() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
OnSimuCoOpt();
OnStaStop();
OnStaClear();
}
void CMainFrame::OnUpdateSimuNa(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_bNaFlag);
}
void CMainFrame::OnAxisLinear() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sAxisMode = (CString)"Linear";
pView->m_ComboAxis.SetCurSel(0);
m_bLinearFlag = FALSE;
m_bLogFlag = TRUE;
2022-06-03 13:38:20 +08:00
pDoc->UpdateAllViews(NULL);
}
void CMainFrame::OnUpdateAxisLinear(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_bLinearFlag);
}
void CMainFrame::OnAxisLog() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sAxisMode = (CString)"Log";
2022-06-03 12:14:48 +08:00
pView->m_sRangeMode = "Auto";
pView->m_ComboAxis.SetCurSel(1);
2022-06-03 12:14:48 +08:00
m_bAutoFlag = FALSE;
m_bLinearFlag = TRUE;
m_bLogFlag = FALSE;
2022-06-03 13:38:20 +08:00
pDoc->UpdateAllViews(NULL);
}
void CMainFrame::OnUpdateAxisLog(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_bLogFlag);
}
void CMainFrame::OnRangeAuto() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sRangeMode = (CString)"Auto";
m_bAutoFlag = FALSE;
pView->m_nLC = max(1, RoundupPowerof2(pView->m_nMaxCount));
pDoc->UpdateAllViews(NULL);
}
void CMainFrame::OnUpdateRangeAuto(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_bAutoFlag);
}
void CMainFrame::OnRangeD4() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sRangeMode = (CString)"Manual";
pView->m_nLC /= 4;
m_bAutoFlag = TRUE;
pView->UpdateData(FALSE);
pDoc->UpdateAllViews(NULL);
}
void CMainFrame::OnRangeD2() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sRangeMode = (CString)"Manual";
pView->m_nLC /= 2;
m_bAutoFlag = TRUE;
pView->UpdateData(FALSE);
pDoc->UpdateAllViews(NULL);
}
void CMainFrame::OnRangeM2() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sRangeMode = (CString)"Manual";
pView->m_nLC *= 2;
m_bAutoFlag = TRUE;
pView->UpdateData(FALSE);
pDoc->UpdateAllViews(NULL);
}
void CMainFrame::OnRangeM4() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sRangeMode = (CString)"Manual";
pView->m_nLC *= 4;
m_bAutoFlag = TRUE;
pView->UpdateData(FALSE);
pDoc->UpdateAllViews(NULL);
}
void CMainFrame::OnDataOrigin() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sSmoothType = (CString)"Origin";
m_bOriginFlag = FALSE;
m_bTSmoothFlag = TRUE;
m_bFSmoothFlag = TRUE;
for (int i = 0; i < 1024; i++) pDoc->m_nChannelSmooth[i] = pDoc->m_nChannelCount[i];
pDoc->UpdateAllViews(NULL);
}
void CMainFrame::OnUpdateDataOrigin(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_bOriginFlag);
}
void CMainFrame::OnData3() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sSmoothType = (CString)"S3";
m_bOriginFlag = TRUE;
m_bTSmoothFlag = FALSE;
m_bFSmoothFlag = TRUE;
SmoothThree();
pDoc->UpdateAllViews(NULL);
}
void CMainFrame::OnUpdateData3(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_bTSmoothFlag);
}
void CMainFrame::OnData5() {
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
pView->m_sSmoothType = (CString)"S5";
m_bOriginFlag = TRUE;
m_bTSmoothFlag = TRUE;
m_bFSmoothFlag = FALSE;
SmoothFive();
pDoc->UpdateAllViews(NULL);
}
void CMainFrame::OnUpdateData5(CCmdUI* pCmdUI) {
pCmdUI->Enable(m_bFSmoothFlag);
}
2022-06-03 01:26:26 +08:00
void CMainFrame::OnDataPeak() {
2022-06-03 01:26:26 +08:00
if (pDoc == nullptr) pDoc = (CMCADoc*)GetActiveDocument();
if (pView == nullptr) pView = (CControlView*)pDoc->GetView(RUNTIME_CLASS(CControlView));
int L = pView->m_nCursor1;
int R = pView->m_nCursor2;
2022-06-03 01:47:52 +08:00
if (pView->m_nWidth > 256) {
2022-06-03 01:26:26 +08:00
AfxMessageBox((CString)"ROI区域太大需≤256");
return ;
}
int cnt = 0;
double amplitude, mean, sigma, b0, b1, b2;
for (int i = L; i <= R; i++)
if (pDoc->m_nChannelSmooth[i] != 0) cnt++;
matrix mZ(cnt, 1);
matrix mX(cnt, 3);
matrix mB(3, 1);
cnt = 0;
for (int i = L; i <= R; i++) {
if (pDoc->m_nChannelSmooth[i] == 0) continue;
vX[cnt] = i, vY[cnt] = pDoc->m_nChannelSmooth[i];
mZ(cnt, 0) = log(pDoc->m_nChannelSmooth[i]);
mX(cnt, 0) = 1, mX(cnt, 1) = i, mX(cnt, 2) = i * i;
cnt++;
}
mB = (mX.T() * mX).I() * mX.T() * mZ;
b0 = mB(0, 0), b1 = mB(1, 0), b2 = mB(2, 0);
sigma = -1 / b2;
mean = b1 * sigma / 2;
amplitude = exp(b0 + mean * mean / sigma);
sigma = sqrt(sigma);
matrix mJ(cnt, 3);
matrix mH(3, 3);
matrix mF(cnt, 1);
matrix mG(3, 1);
matrix mS(3, 1);
matrix mL(3, 3);
matrix mU(3, 3);
double maxV;
int* P = new int[3]();
double* b = new double[3]();
for (int i = 0; i < 10; i++) {
mJ = Jacobian(cnt, &vX[0], amplitude, mean, sigma);
mH = mJ.T() * mJ;
for (int j = 0; j < cnt; j++) mF(j, 0) = vY[j] - Gaussian(vX[j], amplitude, mean, sigma);
mG = mJ.T() * mF;
for (int j = 0; j < 3; j++) b[j] = -mG(j, 0);
if (!LUPDescomposition(mH, mL, mU, P)) return;
mS = LUPSolve(mL, mU, P, b);
amplitude += mS(0, 0), mean += mS(1, 0), sigma += mS(2, 0);
maxV = 0;
for (int j = 0; j < 3; j++) maxV = max(maxV, abs(mS(j, 0)));
if (maxV < 1e-5) break;
}
2022-06-03 01:47:52 +08:00
if (amplitude < 0 || mean < 0 || sigma < 0) {
AfxMessageBox((CString)"拟合失败");
return ;
}
2022-06-03 01:26:26 +08:00
CString strText;
strText.Format(_T("幅值%.3f\n均值%.3f\n标准差%.3f"), amplitude, mean, sigma);
AfxMessageBox(strText);
}