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
YiHui Liu 05dce90378 fix: cumbo box select;
add: combo box for simulation source
2022-06-03 13:30:39 +08:00

710 lines
21 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// MainFrm.cpp: CMainFrame 类的实现
//
#include <math.h>
#include <chrono>
#include <fstream>
#include <sstream>
#include <iostream>
#include "pch.h"
#include "framework.h"
#include "MCA.h"
#include "Matrix.h"
#include "MainFrm.h"
#include "TotalView.h"
#include "DetailView.h"
#include "ControlView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CREATE()
ON_WM_TIMER()
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)
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)
END_MESSAGE_MAP()
static UINT indicators[] = {
ID_SEPARATOR, // 状态行指示器
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
// CMainFrame 构造/析构
CMainFrame::CMainFrame() noexcept {
// TODO: 在此添加成员初始化代码
}
CMainFrame::~CMainFrame() {
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
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();
OnLoadToolBarIcon();
return 0;
}
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,
CCreateContext* pContext) {
// 左右拆分窗口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));
// 右侧窗口上下拆分2行1列
VERIFY(m_wndSplitter2.CreateStatic(&m_wndSplitter, 2, 1,
WS_CHILD | WS_VISIBLE, m_wndSplitter.IdFromRowCol(0, 1)));
// 右上窗口创建视图第0行第0列
VERIFY(m_wndSplitter2.CreateView(0, 0,
RUNTIME_CLASS(CTotalView), CSize(2086, 400), pContext));
// 右下窗口创建视图第1行第0列
VERIFY(m_wndSplitter2.CreateView(1, 0,
RUNTIME_CLASS(CDetailView), CSize(2086, 0), pContext));
return TRUE;
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) {
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
cs.style &= ~WS_THICKFRAME;
cs.style &= ~WS_MAXIMIZEBOX;
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))
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();
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
{
// 获取时间
std::getline(ifs, line);
pView->m_nTime = 0;
pView->m_nT0 = GetMilliTime() - std::stof(line);
// 获取源
std::getline(ifs, line);
pView->m_sSource = line.c_str();
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];
// 其他设置
m_bClearFlag = TRUE;
pView->m_sRangeMode = "Auto";
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);
std::string str = CStringA(pView->m_sSource);
ofs << pView->m_nTime << std::endl;
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() {
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) {
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;
}
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";
pView->m_sRangeMode = "Auto";
pView->m_ComboAxis.SetCurSel(1);
m_bAutoFlag = FALSE;
m_bLinearFlag = TRUE;
m_bLogFlag = FALSE;
}
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);
}
void CMainFrame::OnDataPeak() {
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;
if (pView->m_nWidth > 256) {
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;
}
if (amplitude < 0 || mean < 0 || sigma < 0) {
AfxMessageBox((CString)"拟合失败");
return ;
}
CString strText;
strText.Format(_T("幅值%.3f\n均值%.3f\n标准差%.3f"), amplitude, mean, sigma);
AfxMessageBox(strText);
}