📄 ecg_1dlg.cpp
字号:
//memmove does not work!!!
for(int i=0;i<lenght;i++)
{
AR_ECG[i] = double(*(ar0+i));
AR_REV[i] = double(*(ar1+i));
}
//Calculate the signal mean
//Normalize array
dsp_flf.SetArrToNormalize(&AR_ECG[0],lenght);
dsp_flf.SetArrToNormalize(&AR_REV[0],lenght);
//Low filtr
// dsp_flf.Filter_High(AR_ECG,AR_ECG,5000,1,500,0.000001);
//If noht filter was selected use it 2 times
s_filter_input = "";
if(m_b50hz==1)
{
dsp_flf.RFilter_Noht(&AR_ECG[0],lenght,500,50,0.005);
dsp_flf.RFilter_Noht(&AR_ECG[0],lenght,500,50,0.005);
s_filter_input = s_filter_input + " 2x50Hz Rnoht/";
}
//if noht filter was selected use it 2 times
if(m_b60hz==1)
{
dsp_flf.RFilter_Noht(&AR_ECG[0],lenght,500,60,0.01);
dsp_flf.RFilter_Noht(&AR_ECG[0],lenght,500,60,0.01);
s_filter_input = s_filter_input + " 2x60Hz Rnoht/";
}
//If lol filter was selected use it
if(m_b40hzlol==1)
{
dsp_flf.RFilter_Low(&AR_ECG[0],lenght,500,0.51);
s_filter_input = s_filter_input + " 1x40Hz Rlow/";
}
if(m_bw45low==1)
{
dsp_flf.WFilter_Low40Hz(AR_ECG,AR_ECG,lenght,500,40);
// dsp_flf.WFilter_Low40Hz(AR_ECG,AR_ECG,lenght,500,40);
s_filter_input = s_filter_input + " 1x40Hz Wlol/";
}
if(m_bw50noht==1)
{
dsp_flf.WFilter_Noht(AR_ECG,AR_ECG,lenght,500,50);
dsp_flf.WFilter_Noht(AR_ECG,AR_ECG,lenght,500,50);
s_filter_input = s_filter_input + " 2x50Hz Wnoht/";
}
if(m_bw067hz==1)
{
dsp_flf.WFilter_High(&AR_ECG[0],&AR_ECG[0],
5000,-1,500,0.0001);
s_filter_input = s_filter_input + " 1x>0.67Hz Whigh/";
}
if(s_filter_input=="")
s_filter_input = " NO FILTER";
//Resample signal from500Hz to 250Hz
int k = Resample(&AR_ECG[0],&AR_ECG[0],lenght,500,250);
//After this we can draw a bitmap with sampled arrays
OnBtest();
}
void CECG_1Dlg::OnOK()
{
// TODO: Add extra validation here
}
void CECG_1Dlg::OnBshowbmp()
{
// TODO: Add your control notification handler code here
// dsp_flf.Filter_Low(&AR_ECG[0],5000,500,0.05);
dsp_flf.SetArrToNormalize(&AR_ECG[0],5000);
dsp_flf.RFilter_Noht(&AR_ECG[0],5000,250,50,0.017);
OnBtest();
}
int CECG_1Dlg::Resample(double *dest, double *source, int lenght, int fold, int fnew)
{
int k;
k = fold/fnew;
for(int i=0;i<lenght/k;i++)
{
*(dest+i) = *(source+i*k);
}
//Zero end of the array
for(i=lenght/k;i<lenght;i++)
{
*(dest+i) = 0;
}
return k;
}
void CECG_1Dlg::SamplingProcess()
{
//Begins a new thread to visualize sampling process
AfxBeginThread(SmplProcess,this);
SetThreadPriority(SmplProcess,THREAD_PRIORITY_NORMAL);
}
void CECG_1Dlg::OnBtest()
{
//Pass curr record throught the ECG_DSP
dsp_ecg.SetECG(AR_ECG,2500,AR_REV,&i_QRS_count,&i_QRS_ms,
&i_PR_ms,&i_QT_QTc_ms,m_select_segment);
//Format the ECG record intervals info
s_ECG_Info.Format("%d:%d Pulse-rate %d/min, QRSint.%dms, PRint.%dms, QTint.%dms",
hh,mm,i_QRS_count,i_QRS_ms,i_PR_ms,i_QT_QTc_ms);
OnButton1();
}
void CECG_1Dlg::OnBinvertecg()
{
// TODO: Add your control notification handler code here
//Inverst the array ECG
dsp_flf.InvertArr(&AR_ECG[0],&AR_ECG[0],5000);
//Inverts the array REV
dsp_flf.InvertArr(&AR_REV[0],&AR_REV[0],5000);
OnBtest() ;
}
int CECG_1Dlg::CountQRS(double *ECG, int lenght)
{
int D = 0;
/* int Delta[5000];
int Deltamin[5000];
for(int i=0;i<lenght;i++)
{
*(AR_REV+i) = 0;
Deltamin[i]= 0;
}
for(i=0;i<lenght-1;i++)
{
D = int(*(ECG+i+1) - *(ECG+i));
Delta[i] = D;
if(D>16)
*(AR_REV+i) = 2;
if(D<-16)
*(AR_REV+i) = -2;
}
D = 0;
int d_count;
for(i=0;i<lenght-1;i++)
{
d_count=0;
if(*(AR_REV+i)==2)
{ //*(AR_REV+i-1)=400;//find the delta begining
do{ i++;d_count++;}
while(*(AR_REV+i)==2);
int max=i;
do{max++;}
while(*(AR_REV+max)==2);
*(AR_REV+max) = *(AR_ECG+max);//fing max after delta+
do{max++;}
while(*(AR_REV+max)<0);
*(AR_REV+max+1) = *(AR_ECG+max);//find min after max
max = i;
do{max--;}
while(Delta[max]>0);
*(AR_REV+max+2) = *(ECG+max+1);//find min after d-
if(d_count>2)
{D++;
//*(AR_REV+i) = 400;//end of the delta+
}
}
}
//D contains QRS/10s to convert it in QRS/min
//we must multiply it by 6, because 1 min contains 60 seconds
i_QRS_count = D*6;
//Format the QRS count in to text string
s_ECG_Info.Format("%d:%d QRS %d/min",hh,mm,i_QRS_count);
*/ return D;
}
void CECG_1Dlg::OnBlow()
{
// TODO: Add your control notification handler code here
dsp_flf.RFilter_Low(&AR_ECG[0],5000,250,0.62);
OnBtest();
}
void CECG_1Dlg::OnButton2()
{
// TODO: Add your control notification handler code here
dsp_flf.WFilter_High(&AR_ECG[0],&AR_ECG[0],
5000,-1,250,0.0001);//255Hz*0.001 = 0.225
OnBtest() ;
}
void CECG_1Dlg::OnBprint()
{
// TODO: Add your control notification handler code here
CPrintDialog dlgPrint(FALSE,PD_ALLPAGES ,this);
if(dlgPrint.DoModal()==IDOK)
{
CDC dcPrint;
dcPrint.Attach(dlgPrint.GetPrinterDC());
// dcPrint.SetMapMode(MM_LOMETRIC);
DOCINFO myPrintJob;
myPrintJob.cbSize = sizeof(myPrintJob);
myPrintJob.lpszDocName = "MyPrintJob";
myPrintJob.lpszOutput = NULL;
myPrintJob.lpszDatatype = NULL;
myPrintJob.fwType = NULL;
if(dcPrint.StartDoc(&myPrintJob)>=0)
{
dcPrint.StartPage();
CString str;
for(int i=1;i<10;i++)
{
str.Format("points %d lenght",100*i);
dcPrint.MoveTo(10,100*i);
dcPrint.TextOut(10,100*i,str);
dcPrint.LineTo(100*i,100*i);
}
dcPrint.MoveTo(100,100);
dcPrint.LineTo(1000,100);
dcPrint.EndPage();
dcPrint.EndDoc();
}
dcPrint.DeleteDC();
}
}
void CECG_1Dlg::OnButton1()
{
// TODO: Add your control notification handler code here
i_bmp = 0;
CRect rcClient;
GetClientRect(rcClient);
CClientDC dc(this);
int x,y;
y = 100;
x = 220;
rcClient.SetRect(x,y,x+500,y+500);
ecg_draw.SetArr(&AR_ECG[0],&AR_REV[0],5000);
ecg_draw.SetEcgInfo(s_ECG_Info);
ecg_draw.SetEcgDrawRect(&dc,rcClient,m_bmppos*500,m_bmppos*500+500);
//Set the redraw type to be bmp_ecg
if(i_bmp==1)
i_bmp = 0;
}
void CECG_1Dlg::OnBdelta()
{
// TODO: Add your control notification handler code here
dsp_flf.RFilter_Low(AR_ECG,5000,250,0.1);
dsp_flf.Delta1(AR_REV,AR_ECG,5000);
OnButton1();
}
void CECG_1Dlg::OnBdelta2()
{
// TODO: Add your control notification handler code here
dsp_flf.RFilter_Low(AR_ECG,5000,250,0.1);
dsp_flf.Delta2(AR_REV,AR_ECG,5000);
OnButton1();
}
void CECG_1Dlg::OnBdeltareverse()
{
// TODO: Add your control notification handler code here
dsp_flf.DeltaReverse1(AR_REV,AR_REV,5000);
OnButton1();
}
void CECG_1Dlg::StartSampling()
{
cur_index=0;
//Starts the sampling process
//before this format the date
SetTestdate();
m_ctlRecord.SetWindowText("End Record");
mcp3002.SetEndSampleNotification(this,EndSampleNotification);
//Loads filter kernels for 500Hz
dsp_flf.LoadFilterKernels(500);
mcp3002.MMT_Start(0x378);
//Visualize process with time bar
SamplingProcess();
b_start_stop = 1;
}
void CECG_1Dlg::StopSampling()
{
//End the sampling process
mcp3002.MMT_Stop();
m_ctlRecord.SetWindowText("Star Record");
//Loads filter kernels for 250Hz
dsp_flf.LoadFilterKernels(250);
b_start_stop = 0;
// GetDlgItem(IDC_BRECORD)->EnableWindow(false);
}
void CECG_1Dlg::OnButton3()
{
// TODO: Add your control notification handler code here
//Set the redraw type to be bmp_statistic
if(i_bmp==0)
i_bmp = 1;
//Count all qrs min
CountQRSmin();
// CountAllQRS();
// dsp_flf.Message(QRS_MIN_COUNT.GetSize());
CRect rcClient;
GetClientRect(rcClient);
CClientDC dc(this);
int x,y;
y = 100;
x = 220;
double Qrscount[2500];
double pwt[2500];
for(int i=0;i<2500;i++)
{
Qrscount[i]=1;
pwt[i]=10;
}
for(i=0;i<QRS_MIN_COUNT.GetSize();i++)
{
Qrscount[i] = QRS_MIN_COUNT.GetAt(i);
pwt[i] = Qrscount[i] * 2 + rand()%50 - rand()%50;
//pwt[i] = 100;//
}
dsp_flf.RFilter_Low(pwt,1000,100,0.45);
// dsp_flf.Message(i);//OK
rcClient.SetRect(x,y,x+500,y+200);
statistic_draw.SetArr(Qrscount,pwt,2500);
CString str;
str = " (Y=pulse & power rates, X=minutes)";
str = "Test date "+
ecg_data.ecg_info.velo_test_date.Format("%Y-%mm-%dd Start at %H:%M")+
str;
statistic_draw.SetInfo(str);
statistic_draw.SetEcgDrawRect(&dc,rcClient,m_bmppos*500,m_bmppos*500+500);
}
void CECG_1Dlg::OnBdeltareverse2()
{
// TODO: Add your control notification handler code here
dsp_flf.DeltaReverse2(AR_REV,AR_REV,5000);
OnButton1();
}
void CECG_1Dlg::SetData(double *source, int lenght)
{
//Adds new portion of sampled data to the ECG_DATA DATA
//word array
m_sComment = "Used filters:"+ s_filter_input;
ecg_data.SetDataNew(source,lenght,m_sComment,i_QRS_count,
i_QRS_ms,i_PR_ms,i_QT_QTc_ms,hh,mm);
}
void CECG_1Dlg::OnSelchangeLdata()
{
// TODO: Add your control notification handler code here
int index = m_ctldata.GetCurSel();
//If there are something in the list box
//enable corect button
if(index>=0)
{
GetDlgItem(IDC_BCORECT)->EnableWindow(TRUE);
i_old_ctldata_index = index;
m_srecord.Format("Record %d of %d",index,m_ctldata.GetCount()-1);
UpdateData(false);
GetDataFrom(AR_ECG,index,2500);
dsp_flf.SetArrToNormalize(AR_ECG,2500);
OnBtest();
}
}
void CECG_1Dlg::GetDataFrom(double *dest,int start, int lenght)
{
UpdateData(true);
ecg_data.GetFrom(dest,start*lenght,lenght);
//Gets the info about the recorded segment
//GetInfoFrom returns the CString comment about the segment
m_sComment = ecg_data.GetInfoFrom(start,&i_QRS_count,
&i_QRS_ms,&i_PR_ms,&i_QT_QTc_ms,&hh,&mm);
i_QRS_count = ecg_data.GetQRSCount(start);
s_ECG_Info.Format("%d:%d QRS %d /m",hh,mm,i_QRS_count);
UpdateData(false);
}
void CECG_1Dlg::SetDataAt(double* source,int start,int lenght)
{
UpdateData(true);
ecg_data.SetDataAt(source,start*lenght,lenght);
//Sets the info about the ECG segment
ecg_data.SetInfoAt(start,m_sComment,i_QRS_count,
i_QRS_ms,i_PR_ms,i_QT_QTc_ms,hh,mm);
UpdateData(false);
}
void CECG_1Dlg::OnBcorect()
{
// TODO: Add your control notification handler code here
//This function sets data in to ecg_data class
SetDataAt(AR_ECG,i_old_ctldata_index,2500);
//Disable control correct, because the correction was done
GetDlgItem(IDC_BCORECT)->EnableWindow(FALSE);
//Gets the selected index string
ecg_data.GetInfoFrom(i_old_ctldata_index,&i_QRS_count,&i_QRS_ms,
&i_PR_ms,&i_QT_QTc_ms,&hh,&mm);
CString str;
str.Format("%d:%d %d
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -