710 lines
21 KiB
C++
710 lines
21 KiB
C++
|
||
// 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);
|
||
}
|