Results 1 to 5 of 5
  1. #1
    CHIDIONYZUZ is offline Member
    Join Date
    Dec 2012
    Posts
    2
    Rep Power
    0

    Default Need help finding the ECG algorithm

    I have a Java applet that was made from a developer who shared his realtime ECG graph code. Would anyone be able to point out the part of the code where the x and y coordinates are located and the variables needed just for the algorithm? I am currently developing an app for android and found a graphview that would plot the data using the paint canvas command. here part of the code:

    /*************************
    * THE ECG FUNCTION
    **************************/
    boolean ecgFunction(){
    boolean RetValue;

    txtStatus.append("Starting to generate ECG table data....\n");

    ecgCalc Ecg = new ecgCalc();
    RetValue = Ecg.dorun();

    txtStatus.append("Finished generating ECG table data.\n\n");

    return(RetValue);
    }

    private void generateButtonActionPerformed(java.awt.event.Actio nEvent evt) {//GEN-FIRST:event_generateButtonActionPerformed
    desktopPane.setCursor(java.awt.Cursor.getPredefine dCursor(java.awt.Cursor.WAIT_CURSOR));
    paramDialog.hide();

    /*
    * Clear Status text.
    */
    txtStatus.setText(null);
    txtStatus.append("******************************** ****************************\n");
    txtStatus.append("ECGSYN:\nA program for generating a realistic synthetic ECG\n\n");
    txtStatus.append("Copyright (c) 2003 by Patrick McSharry & Gari Clifford.\n");
    txtStatus.append("All rights reserved.\n");
    txtStatus.append("See IEEE Transactions On Biomedical Engineering, 50(3),\n289-294, March 2003.\n\n");
    txtStatus.append("Contact:\nP. McSharry (patrick@mcsharry.net)\nG. Clifford (gari@mit.edu)\n");
    txtStatus.append("******************************** ****************************\n\n");
    txtStatus.append("ECG process started.\n\n");
    txtStatus.append("Starting to clear table data and widgets values....\n");

    /*
    * Set the Amplitude labels
    */
    lblMaxAmplitude.setText(txtAmplitude.getText());
    lblMinAmplitude.setText("-" + txtAmplitude.getText());

    /*
    * Re init the plot state.
    * Disable repaint for the moment, until we finish the FFT function.
    */
    readyToPlot = false;
    plotScrollBarValue = 0;
    plotScrollBar.setMaximum(0);

    /* Delete any data on the Data Table. */
    clearDataTable();

    txtStatus.append("Finished clearing table data and widgets values.\n\n");
    /*
    * Call the ECG funtion to calculate the data into the Data Table.
    */
    if(ecgFunction()){

    txtStatus.append("Starting to plot ECG table data....\n");

    /*
    * if the # Data Table rows is less than the ecgFrame width, we do not
    * need the scrollbar
    */
    int rows = tableValuesModel.getRowCount();
    if(rows > ecgFrame.getBounds().width){
    plotScrollBar.setMaximum(rows - ecgFrame.getBounds().width - 1);
    }

    /*
    * Only plot if there's data in the table.
    */
    if(rows > 0){
    readyToPlot = true;
    ecgGenerated = true;
    enableButtons();
    }else{
    txtStatus.append("No data to plot!.\n");
    }

    ecgFrame.repaint();
    txtStatus.append("Finished plotting ECG table data.\n\n");

    }
    txtStatus.append("Finsihed ECG process.\n");
    txtStatus.append("******************************** ****************************\n");

    desktopPane.setCursor(java.awt.Cursor.getPredefine dCursor(java.awt.Cursor.DEFAULT_CURSOR));
    }//GEN-LAST:event_generateButtonActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane ExtremaLabelScrollPane;
    private javax.swing.JTable ExtremaLabelTable;
    private javax.swing.JScrollPane TableScrollPane;
    private javax.swing.JScrollPane aiScrollPane;
    private javax.swing.JTable aiTable;
    private javax.swing.JDialog alert;
    private javax.swing.JButton alertButton;
    private javax.swing.JDesktopPane alertDesktopPane;
    private javax.swing.JTextArea alertText;
    private javax.swing.JLabel alertTitle;
    private javax.swing.JDesktopPane animateDesktopPane;
    private javax.swing.JScrollPane biScrollPane;
    private javax.swing.JTable biTable;
    private javax.swing.JDesktopPane calculateDesktopPane;
    private javax.swing.JButton clearButton;
    private javax.swing.JButton closeParamDialogButton;
    private javax.swing.JDesktopPane desktopPane;
    private javax.swing.JScrollPane ecgPlotArea;
    private javax.swing.JInternalFrame ecgWindow;
    private javax.swing.JButton exportButton;
    private javax.swing.JDialog exportDialog;
    private javax.swing.JPanel extremaPanel;
    private javax.swing.JPanel generalInterfacePanel;
    private javax.swing.JButton generateButton;
    private javax.swing.JDialog helpDialog;
    private javax.swing.JEditorPane helpEditorPane;
    private javax.swing.JInternalFrame helpInternalFrame;
    private javax.swing.JScrollPane helpScrollPane;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel lblAmplitude;
    private javax.swing.JLabel lblAnoise;
    private javax.swing.JLabel lblFhi;
    private javax.swing.JLabel lblFhistd;
    private javax.swing.JLabel lblFlo;
    private javax.swing.JLabel lblFlostd;
    private javax.swing.JLabel lblGeneralTitle;
    private javax.swing.JLabel lblHrmean;
    private javax.swing.JLabel lblHrstd;
    private javax.swing.JLabel lblLfhfratio;
    private javax.swing.JLabel lblMaxAmplitude;
    private javax.swing.JLabel lblMinAmplitude;
    private javax.swing.JLabel lblMorphologyTitle;
    private javax.swing.JLabel lblN;
    private javax.swing.JLabel lblOrigin;
    private javax.swing.JLabel lblSeed;
    private javax.swing.JLabel lblSf;
    private javax.swing.JLabel lblSfecg;
    private javax.swing.JLabel lblSpectralTitle;
    private javax.swing.JLabel lblXAxis;
    private javax.swing.JButton paramButton;
    private javax.swing.JDesktopPane paramDesktopPane;
    private javax.swing.JDialog paramDialog;
    private javax.swing.JButton paramHelpButton;
    private javax.swing.JTabbedPane paramTabbedPane;
    private javax.swing.JScrollBar plotScrollBar;
    private javax.swing.JButton resetParamDialogButton;
    private javax.swing.JButton saveParamDialogButton;
    private javax.swing.JPanel spectralCharacteristicsPanel;
    private javax.swing.JButton startAnimateButton;
    private javax.swing.JScrollPane statusScrollPane;
    private javax.swing.JButton stopAnimateButton;
    private javax.swing.JTable tableValues;
    private javax.swing.JScrollPane tiScrollPane;
    private javax.swing.JTable tiTable;
    private javax.swing.JTextField txtAmplitude;
    private javax.swing.JTextField txtAnoise;
    private javax.swing.JTextField txtFhi;
    private javax.swing.JTextField txtFhistd;
    private javax.swing.JTextField txtFlo;
    private javax.swing.JTextField txtFlostd;
    private javax.swing.JTextField txtHrmean;
    private javax.swing.JTextField txtHrstd;
    private javax.swing.JTextField txtLfhfratio;
    private javax.swing.JTextField txtN;
    private javax.swing.JTextField txtSeed;
    private javax.swing.JTextField txtSf;
    private javax.swing.JTextField txtSfecg;
    private javax.swing.JTextArea txtStatus;
    private javax.swing.JDesktopPane zommDesktopPane;
    private javax.swing.JButton zoomInButton;
    private javax.swing.JButton zoomOutButton;
    // End of variables declaration//GEN-END:variables

    private javax.swing.table.DefaultTableModel tableValuesModel;

    private ecgPanel ecgFrame;

    /*
    * This class is the AdjustmentListener for the
    * scroll bar. So the events come here when the
    * scroll bar is moved.
    */
    public void adjustmentValueChanged(AdjustmentEvent evt){
    plotScrollBarValue = plotScrollBar.getValue();
    ecgFrame.repaint();
    }

    class ecgPanel extends javax.swing.JPanel{

    public void paintComponent(Graphics g){
    // First call the paintComponent of the
    // superclass, in this case JPanel.
    super.paintComponent(g);

    /* Draw the plot frame. */
    g.setColor(frameLineColor);
    g.drawLine(0, posFrameY, ecgFrame.getBounds().width, posFrameY);
    g.drawLine(0, posOriginY, this.getBounds().width, posOriginY);
    g.drawLine(0, horzScaleY, this.getBounds().width, horzScaleY);

    if(readyToPlot){
    int rows = tableValuesModel.getRowCount();
    int x, y, i;
    int plotLimit;
    int initialZero;
    int curSecond, lastSecond;
    String strValue;

    /*
    * Set the first point to the current Table row
    */
    initialZero = (int)(Double.valueOf(tableValues.getValueAt(plotSc rollBarValue, 0).toString()).doubleValue() / plotZoom);
    lastSecond = (int)(Double.valueOf(tableValues.getValueAt(plotSc rollBarValue, 0).toString()).doubleValue());
    x = 0;
    y = posOriginY - (int)(Double.valueOf(tableValues.getValueAt(plotSc rollBarValue, 1).toString()).doubleValue() * frameAmplitude / amplitude);
    Point lastPoint = new java.awt.Point(x, y);
    i= plotScrollBarValue;

    while((x <= this.getBounds().width)&& (i <=rows)){
    curSecond = (int)(Double.valueOf(tableValues.getValueAt(i, 0).toString()).doubleValue());
    if(curSecond > lastSecond){
    lastSecond = curSecond;
    // Convert the x value to a string
    strValue = FormatNumber.toString(Double.valueOf(tableValues.g etValueAt(i, 0).toString()).doubleValue(), upLimit, loLimit, 2);
    /*
    * Plot the X axes number values (the Time).
    */
    g.setColor(axesNumColor);
    drawText(g, strValue,
    x, horzScaleY, horzScaleWidth, horzScaleHeight,
    fScaleNumSize,LEFT);
    g.setColor(frameInsideLineColor);
    g.drawLine(x, posFrameY, x, horzScaleY + 5);
    }

    /*
    * Plot a line between the las point and the current point.
    * This to create a illusion to connect the two points.
    */
    g.setColor(ecgPlotColor);
    g.drawLine(lastPoint.x, lastPoint.y, x, y);

    /*
    * Set the current point to be the last, and
    * get a new point to plot in the following loop.
    */
    lastPoint.setLocation(x, y);
    i+= 1;
    x = (int)(Double.valueOf(tableValues.getValueAt(i, 0).toString()).doubleValue() / plotZoom) - initialZero;
    y = posOriginY - (int)(Double.valueOf(tableValues.getValueAt(i, 1).toString()).doubleValue() * frameAmplitude / amplitude);
    }
    }
    }
    }

    class ecgCalc{

    /* C defines */
    private final double PI = 2.0*Math.asin(1.0);
    private final int NR_END = 1;
    private final int IA = 16807;
    private final long IM = 2147483647;
    private final double AM = (1.0/IM);
    private final long IQ = 127773;
    private final int IR = 2836;
    private final int NTAB = 32;
    private final double NDIV = (1+(IM-1)/NTAB);
    private final double EPS = 1.2e-7;
    private final double RNMX = (1.0-EPS);

    /************************************************** ***************************
    * DEFINE PARAMETERS AS GLOBAL VARIABLES *
    ************************************************** ***************************/
    private String outfile ="ecgsyn.dat";
    // Order of extrema: [P Q R S T]
    private double[] ti = new double[6]; /* ti converted in radians */
    private double[] ai = new double[6]; /* new calculated a */
    private double[] bi = new double[6]; /* new calculated b */

    private int Necg = 0; /* Number of ECG outputs */
    private int mstate = 3; /* System state space dimension */
    private double xinitial = 1.0; /* Initial x co-ordinate value */
    private double yinitial = 0.0; /* Initial y co-ordinate value */
    private double zinitial = 0.04; /* Initial z co-ordinate value */
    private long rseed;
    private double h;
    private double[] rr, rrpc;

    /*
    * Variables for static function rand()
    */
    private long iy;
    private long[] iv;

    public ecgCalc(){
    /* variables for static function ranq() */
    iy=0;
    iv = new long[NTAB];
    }

    /*--------------------------------------------------------------------------*/
    /* UNIFORM DEVIATES */
    /*--------------------------------------------------------------------------*/

    private double rand(){

    int j;
    long k;
    double temp;
    boolean flg;

    if(iy == 0)
    flg = false;
    else
    flg = true;

    if((rseed <= 0) || !flg){
    if (-(rseed) < 1)
    rseed = 1;
    else
    rseed = -rseed;

    for (j=NTAB+7; j>=0; j--) {
    k=(rseed)/IQ;
    rseed=IA*(rseed-k*IQ)-IR*k;
    if (rseed < 0)
    rseed += IM;
    if (j < NTAB)
    iv[j] = rseed;
    }
    iy=iv[0];
    }

    k=(rseed)/IQ;
    rseed=IA*(rseed-k*IQ)-IR*k;
    if (rseed< 0)
    rseed += IM;

    j = (int)(iy/NDIV);
    iy=iv[j];
    iv[j] = rseed;

    if ((temp=AM*iy) > RNMX)
    return RNMX;
    else
    return temp;
    }

    /*
    * FFT
    */
    private void ifft(double[] data, long nn, int isign){

    long n, mmax, m, istep, i, j;
    double wtemp,wr,wpr,wpi,wi,theta;
    double tempr,tempi;
    double swap;

    n=nn << 1;
    j=1;
    for (i=1; i< n; i+=2) {
    if (j > i) {
    //SWAP(data[j],data[i]);
    swap = data[(int) j];
    data[(int)j] = data[(int)i];
    data[(int)i] = swap;
    //SWAP(data[j+1],data[i+1]);
    swap = data[(int)j+1];
    data[(int)j+1] = data[(int)i+1];
    data[(int)i+1] = swap;
    }
    m=n >> 1;
    while (m >= 2 && j > m) {
    j -= m;
    m >>= 1;
    }
    j += m;
    }
    mmax=2;
    while (n > mmax) {
    istep=mmax << 1;
    theta=isign*(6.28318530717959/mmax);
    wtemp=Math.sin(0.5*theta);
    wpr = -2.0*wtemp*wtemp;
    wpi=Math.sin(theta);
    wr=1.0;
    wi=0.0;
    for (m=1; m<mmax; m+=2) {
    for (i=m; i<=n; i+=istep) {
    j= i + mmax;
    tempr=wr * data[(int)j] - wi * data[(int)j+1];
    tempi=wr * data[(int)j+1] + wi * data[(int)j];
    data[(int)j]= data[(int)i] - tempr;
    data[(int)j+1]= data[(int)i+1] - tempi;
    data[(int)i] += tempr;
    data[(int)i+1] += tempi;
    }
    wr=(wtemp=wr)*wpr-wi*wpi+wr;
    wi=wi*wpr+wtemp*wpi+wi;
    }
    mmax=istep;
    }
    }

    /*
    * STANDARD DEVIATION CALCULATOR
    */
    /* n-by-1 vector, calculate standard deviation */
    private double stdev(double[] x, int n){
    int j;
    double add,mean,diff,total;

    add = 0.0;
    for(j=1;j<=n;j++)
    add += x[j];

    mean = add/n;

    total = 0.0;
    for(j=1;j<=n;j++){
    diff = x[j] - mean;
    total += diff*diff;
    }
    return (Math.sqrt(total/((double)n-1)));
    }

    /*
    * THE ANGULAR FREQUENCY
    */
    private double angfreq(double t){
    int i = 1 + (int)Math.floor(t/h);
    return(2.0*PI/rrpc[i]);
    }

    /*--------------------------------------------------------------------------*/
    /* THE EXACT NONLINEAR DERIVATIVES */
    /*--------------------------------------------------------------------------*/
    private void derivspqrst(double t0,double[] x, double[] dxdt){

    int i,k;
    double a0,w0,r0,x0,y0,z0;
    double t,dt,dt2,zbase;
    double[] xi, yi;

    k = 5;
    xi = new double[k + 1];
    yi = new double[k + 1];
    w0 = angfreq(t0);
    r0 = 1.0; x0 = 0.0; y0 = 0.0; z0 = 0.0;
    a0 = 1.0 - Math.sqrt((x[1]-x0)*(x[1]-x0) + (x[2]-y0)*(x[2]-y0))/r0;

    for(i=1; i<=k; i++)
    xi[i] = Math.cos(ti[i]);
    for(i=1; i<=k; i++)
    yi[i] = Math.sin(ti[i]);


    zbase = 0.005* Math.sin(2.0*PI*fhi*t0);

    t = Math.atan2(x[2],x[1]);
    dxdt[1] = a0*(x[1] - x0) - w0*(x[2] - y0);
    dxdt[2] = a0*(x[2] - y0) + w0*(x[1] - x0);
    dxdt[3] = 0.0;

    for(i=1; i<=k; i++){
    dt = Math.IEEEremainder(t-ti[i], 2.0*PI);
    dt2 = dt*dt;
    dxdt[3] += -ai[i] * dt * Math.exp(-0.5*dt2/(bi[i]*bi[i]));
    }
    dxdt[3] += -1.0*(x[3] - zbase);
    }

    /*
    * RUNGA-KUTTA FOURTH ORDER INTEGRATION
    */
    private void Rk4(double[] y, int n, double x, double h, double[] yout){
    int i;
    double xh,hh,h6;
    double[] dydx, dym, dyt, yt;

    dydx= new double[n + 1];
    dym = new double[n + 1];
    dyt = new double[n + 1];
    yt = new double[n + 1];

    hh= h * 0.5;
    h6= h/6.0;
    xh= x + hh;

    derivspqrst(x,y,dydx);
    for (i=1; i<=n; i++)
    yt[i]=y[i]+hh*dydx[i];

    derivspqrst(xh,yt,dyt);
    for (i=1; i<=n; i++)
    yt[i]=y[i] + hh * dyt[i];

    derivspqrst(xh,yt,dym);
    for (i=1; i<=n; i++){
    yt[i]=y[i] + h * dym[i];
    dym[i] += dyt[i];
    }

    derivspqrst(x+h,yt,dyt);
    for (i=1; i<=n; i++)
    yout[i]=y[i] + h6 * (dydx[i]+dyt[i]+2.0*dym[i]);
    }

    /*
    * GENERATE RR PROCESS
    */
    private void rrprocess(double[] rr, double flo, double fhi,
    double flostd, double fhistd, double lfhfratio,
    double hrmean, double hrstd, double sf, int n)
    {
    int i,j;
    double c1,c2,w1,w2,sig1,sig2,rrmean,rrstd,xstd,ratio;
    double df;//,dw1,dw2;
    double[] w, Hw, Sw, ph0, ph, SwC;

    w = new double[n+1];
    Hw = new double[n+1];
    Sw = new double[n+1];
    ph0= new double[(int)(n/2-1 +1)];
    ph = new double[n+1];
    SwC= new double[(2*n)+1];

    w1 = 2.0*PI*flo;
    w2 = 2.0*PI*fhi;
    c1 = 2.0*PI*flostd;
    c2 = 2.0*PI*fhistd;
    sig2 = 1.0;
    sig1 = lfhfratio;
    rrmean = 60.0/hrmean;
    rrstd = 60.0*hrstd/(hrmean*hrmean);

    df = sf/(double)n;
    for(i=1; i<=n; i++)
    w[i] = (i-1)*2.0*PI*df;

    for(i=1; i<=n; i++){
    //dw1 = w[i]-w1;
    //dw2 = w[i]-w2;
    Hw[i] = (sig1*Math.exp(-0.5*(Math.pow(w[i]-w1,2)/Math.pow(c1,2))) / Math.sqrt(2*PI*c1*c1))
    + (sig2*Math.exp(-0.5*(Math.pow(w[i]-w2,2)/Math.pow(c2,2))) / Math.sqrt(2*PI*c2*c2));
    }

    for(i=1; i<=n/2; i++)
    Sw[i] = (sf/2.0)* Math.sqrt(Hw[i]);

    for(i=n/2+1; i<=n; i++)
    Sw[i] = (sf/2.0)* Math.sqrt(Hw[n-i+1]);

    /* randomise the phases */
    for(i=1; i<=n/2-1; i++)
    ph0[i] = 2.0*PI*rand();

    ph[1] = 0.0;
    for(i=1; i<=n/2-1; i++)
    ph[i+1] = ph0[i];

    ph[n/2+1] = 0.0;
    for(i=1; i<=n/2-1; i++)
    ph[n-i+1] = - ph0[i];

    /* make complex spectrum */
    for(i=1; i<=n; i++)
    SwC[2*i-1] = Sw[i]* Math.cos(ph[i]);

    for(i=1; i<=n; i++)
    SwC[2*i] = Sw[i]* Math.sin(ph[i]);

    /* calculate inverse fft */
    ifft(SwC,n,-1);

    /* extract real part */
    for(i=1; i<=n; i++)
    rr[i] = (1.0/(double)n)*SwC[2*i-1];

    xstd = stdev(rr,n);
    ratio = rrstd/xstd;

    for(i=1; i<=n; i++)
    rr[i] *= ratio;

    for(i=1; i<=n; i++)
    rr[i] += rrmean;

    }

    /*
    * DETECT PEAKS
    */
    private void detectpeaks(double[] ipeak, double[] x, double[] y, double[] z, int n){
    int i, j, j1, j2, jmin, jmax, d;
    double thetap1, thetap2, thetap3, thetap4, thetap5;
    double theta1, theta2, d1, d2, zmin, zmax;

    thetap1 = ti[1];
    thetap2 = ti[2];
    thetap3 = ti[3];
    thetap4 = ti[4];
    thetap5 = ti[5];

    for(i=1; i<=n; i++)
    ipeak[i] = 0.0;

    theta1 = Math.atan2(y[1],x[1]);

    for(i=1; i<n; i++){
    theta2 = Math.atan2(y[i+1], x[i+1]);

    if( (theta1 <= thetap1) && (thetap1 <= theta2) ){
    d1 = thetap1 - theta1;
    d2 = theta2 - thetap1;
    if(d1 < d2)
    ipeak[i] = 1.0;
    else
    ipeak[i+1] = 1.0;
    }else if( (theta1 <= thetap2) && (thetap2 <= theta2) ){
    d1 = thetap2 - theta1;
    d2 = theta2 - thetap2;
    if(d1 < d2)
    ipeak[i] = 2.0;
    else
    ipeak[i+1] = 2.0;
    }else if( (theta1 <= thetap3) && (thetap3 <= theta2) ){
    d1 = thetap3 - theta1;
    d2 = theta2 - thetap3;
    if(d1 < d2)
    ipeak[i] = 3.0;
    else
    ipeak[i+1] = 3.0;
    }else if( (theta1 <= thetap4) && (thetap4 <= theta2) ){
    d1 = thetap4 - theta1;
    d2 = theta2 - thetap4;
    if(d1 < d2)
    ipeak[i] = 4.0;
    else
    ipeak[i+1] = 4.0;
    }else if( (theta1 <= thetap5) && (thetap5 <= theta2) ){
    d1 = thetap5 - theta1;
    d2 = theta2 - thetap5;
    if(d1 < d2)
    ipeak[i] = 5.0;
    else
    ipeak[i+1] = 5.0;
    }
    theta1 = theta2;
    }

    /* correct the peaks */
    d = (int)Math.ceil(sfecg/64);
    for(i=1; i<=n; i++){
    if( ipeak[i]==1 || ipeak[i]==3 || ipeak[i]==5 ){

    j1 = (1 > (i-d) ? 1 : (i-d)); //MAX(1,i-d);
    j2 = (n < (i+d) ? n : (i+d)); //MIN(n,i+d);
    jmax = j1;
    zmax = z[j1];
    for(j=j1+1;j<=j2;j++){
    if(z[j] > zmax){
    jmax = j;
    zmax = z[j];
    }
    }
    if(jmax != i){
    ipeak[jmax] = ipeak[i];
    ipeak[i] = 0;
    }
    } else if( ipeak[i]==2 || ipeak[i]==4 ){
    j1 = (1 > (i-d) ? 1 : (i-d));//MAX(1,i-d);
    j2 = (n < (i+d) ? n : (i+d)); //MIN(n,i+d);
    jmin = j1;
    zmin = z[j1];
    for(j=j1+1;j<=j2;j++){
    if(z[j] < zmin){
    jmin = j;
    zmin = z[j];
    }
    }
    if(jmin != i){
    ipeak[jmin] = ipeak[i];
    ipeak[i] = 0;
    }
    }
    }
    }

    /*
    * DORUN PART OF PROGRAM
    */
    public boolean dorun(){

    boolean RetValue = true;

    int i, j, k, Nrr, Nt, Nts;
    int q;
    double[] x;
    double tstep, tecg, rrmean, hrfact, hrfact2;
    double qd;
    double[] xt, yt, zt, xts, yts, zts;
    double timev, zmin, zmax, zrange;
    double[] ipeak;

    // perform some checks on input values
    q = (int) Math.rint(sf/sfecg);
    qd = (double)sf/(double)sfecg;

    /* convert angles from degrees to radians and copy a vector to ai*/
    for(i=1; i <= 5; i++){
    ti[i] = theta[i] * PI/180.0;
    ai[i] = a[i];
    }

    /* adjust extrema parameters for mean heart rate */
    hrfact = Math.sqrt(hrmean/60);
    hrfact2 = Math.sqrt(hrfact);

    for(i=1; i <= 5; i++)
    bi[i] = b[i] * hrfact;

    ti[1] *= hrfact2;
    ti[2] *= hrfact;
    ti[3] *= 1.0;
    ti[4] *= hrfact;
    ti[5] *= 1.0;

    /* declare state vector */
    //x=dvector(1,mstate);
    x= new double[4];

    txtStatus.append("Approximate number of heart beats: " + N +"\n");
    txtStatus.append("ECG sampling frequency: " + sfecg + " Hertz\n");
    txtStatus.append("Internal sampling frequency: " + sf + " Hertz\n");
    txtStatus.append("Amplitude of additive uniformly distributed noise: " + Anoise + " mV\n");
    txtStatus.append("Heart rate mean: " + hrmean + " beats per minute\n");
    txtStatus.append("Heart rate std: " + hrstd + " beats per minute\n");
    txtStatus.append("Low frequency: " + flo + " Hertz\n");
    txtStatus.append("High frequency std: " + fhistd + " Hertz\n");
    txtStatus.append("Low frequency std: " + flostd + " Hertz\n");
    txtStatus.append("High frequency: " + fhi + " Hertz\n");
    txtStatus.append("LF/HF ratio: " + lfhfratio + "\n");
    txtStatus.append("time step milliseconds: " + ecgAnimateInterval + "\n\n");
    txtStatus.append("Order of Extrema:\n");
    txtStatus.append(" theta(radians)\n");
    txtStatus.append("P: ["+ ti[1] + "\t]\n");
    txtStatus.append("Q: ["+ ti[2] + "\t]\n");
    txtStatus.append("R: ["+ ti[3] + "\t]\n");
    txtStatus.append("S: ["+ ti[4] + "\t]\n");
    txtStatus.append("T: ["+ ti[5] + "\t]\n\n");
    txtStatus.append(" a(calculated)\n");
    txtStatus.append("P: ["+ ai[1] + "\t]\n");
    txtStatus.append("Q: ["+ ai[2] + "\t]\n");
    txtStatus.append("R: ["+ ai[3] + "\t]\n");
    txtStatus.append("S: ["+ ai[4] + "\t]\n");
    txtStatus.append("T: ["+ ai[5] + "\t]\n\n");
    txtStatus.append(" b(calculated)\n");
    txtStatus.append("P: ["+ bi[1] + "\t]\n");
    txtStatus.append("Q: ["+ bi[2] + "\t]\n");
    txtStatus.append("R: ["+ bi[3] + "\t]\n");
    txtStatus.append("S: ["+ bi[4] + "\t]\n");
    txtStatus.append("T: ["+ bi[5] + "\t]\n\n");

    /* Initialise the vector */
    x[1] = xinitial;
    x[2] = yinitial;
    x[3] = zinitial;

    /* initialise seed */
    rseed = -seed;

    /* calculate time scales */
    h = 1.0/(double)sf;
    tstep = 1.0/(double)sfecg;

    /* calculate length of RR time series */
    rrmean = (60.0/hrmean);
    Nrr=(int)Math.pow(2.0, Math.ceil(Math.log(N*rrmean*sf)/Math.log(2.0)));

    txtStatus.append("Using " + Nrr + " = 2^ "+ (int)(Math.log(1.0*Nrr)/Math.log(2.0)) + " samples for calculating RR intervals\n");

    /* create rrprocess with required spectrum */
    rr = new double[Nrr + 1];
    rrprocess(rr, flo, fhi, flostd, fhistd, lfhfratio, hrmean, hrstd, sf, Nrr);

    /* create piecewise constant rr */
    rrpc = new double[(2*Nrr) + 1];
    tecg = 0.0;
    i = 1;
    j = 1;
    while(i <= Nrr){
    tecg += rr[j];
    j = (int) Math.rint(tecg/h);
    for(k=i; k<=j; k++)
    rrpc[k] = rr[i];
    i = j+1;
    }
    Nt = j;

    /* integrate dynamical system using fourth order Runge-Kutta*/
    xt = new double[Nt + 1];
    yt = new double[Nt + 1];
    zt = new double[Nt + 1];
    timev = 0.0;
    for(i=1; i<=Nt; i++){
    xt[i] = x[1];
    yt[i] = x[2];
    zt[i] = x[3];
    Rk4(x, mstate, timev, h, x);
    timev += h;
    }

    /* downsample to ECG sampling frequency */
    xts = new double[Nt + 1];
    yts = new double[Nt + 1];
    zts = new double[Nt + 1];

    j=0;
    for(i=1; i<=Nt; i+=q){
    j++;
    xts[j] = xt[i];
    yts[j] = yt[i];
    zts[j] = zt[i];
    }
    Nts = j;

    /* do peak detection using angle */
    ipeak = new double[Nts + 1];
    detectpeaks(ipeak, xts, yts, zts, Nts);

    /* scale signal to lie between -0.4 and 1.2 mV */
    zmin = zts[1];
    zmax = zts[1];
    for(i=2; i<=Nts; i++){
    if(zts[i] < zmin)
    zmin = zts[i];
    else if(zts[i] > zmax)
    zmax = zts[i];
    }
    zrange = zmax-zmin;
    for(i=1; i<=Nts; i++)
    zts[i] = (zts[i]-zmin)*(1.6)/zrange - 0.4;

    /* include additive uniformly distributed measurement noise */
    for(i=1; i<=Nts; i++)
    zts[i] += Anoise*(2.0*rand() - 1.0);

    /*
    * insert into the ECG data table
    */
    txtStatus.append("Inserting rows...\n");
    for(i=1;i<=Nts;i++){
    //fprintf(fp,"%f %f %d\n",(i-1)*tstep,zts[i],(int)ipeak[i]);
    Vector nuevoRow = new Vector(3);
    nuevoRow.addElement(new String(Double.toString((i-1)*tstep)));
    nuevoRow.addElement(new String(Double.toString(zts[i])));
    nuevoRow.addElement(new String(Integer.toString((int)ipeak[i])));
    tableValuesModel.addRow(nuevoRow);
    }

    txtStatus.append("Finished inserting (" + i + ") rows.\n");

    //RetValue = false;

    return(RetValue);
    }
    }

    /*
    * Class to plot the ECG animation
    */
    class ECGAnimate extends TimerTask{

    int x = 0;
    int y = posOriginY - (int)(Double.valueOf(tableValues.getValueAt(ecgAni mateCurRow, 1).toString()).doubleValue() * frameAmplitude / amplitude);
    int curSecond = 0;
    int lastSecond = 0;
    Graphics ga = ecgFrame.getGraphics();

    public void run(){
    curSecond = (int)(Double.valueOf(tableValues.getValueAt(ecgAni mateCurRow, 0).toString()).doubleValue());
    if(curSecond > lastSecond){
    lastSecond = curSecond;
    /*
    * Plot the X axes number values (the Time).
    */
    ga.setColor(axesNumColor);
    drawText(ga, FormatNumber.toString(Double.valueOf(tableValues.g etValueAt(ecgAnimateCurRow, 0).toString()).doubleValue(), upLimit, loLimit, 2),
    x, horzScaleY, horzScaleWidth, horzScaleHeight,
    fScaleNumSize,LEFT);

    ga.setColor(frameInsideLineColor);
    ga.drawLine(x, posFrameY, x, horzScaleY + 5);

    }

    ga.setColor(ecgPlotColor);
    ga.drawLine(ecgAnimateLastPoint.x, ecgAnimateLastPoint.y, x, y);
    ecgAnimateCurRow += 1;

    if(ecgAnimateCurRow >= ecgAnimateNumRows){
    /*
    * If we reach the end of the Data Table, loop again entire table.
    */
    ecgFrame.repaint();
    ecgAnimateCurRow = 0;
    ecgAnimateInitialZero = 0;
    x = 0;
    y = posOriginY - (int)(Double.valueOf(tableValues.getValueAt(ecgAni mateCurRow, 1).toString()).doubleValue() * frameAmplitude / amplitude);
    ecgAnimateLastPoint.setLocation(x, y);
    curSecond = 0;
    lastSecond = 0;

    } else if(x > ecgAnimatePanelWidth){
    /*
    * If we not reached the end of the Data Table, but we reach to the limit of
    * the Plot Area. so reset the X coordinate to begin again.
    */
    ecgFrame.repaint();
    x = 0;
    y = posOriginY - (int)(Double.valueOf(tableValues.getValueAt(ecgAni mateCurRow, 1).toString()).doubleValue() * frameAmplitude / amplitude);
    ecgAnimateInitialZero = (int)(Double.valueOf(tableValues.getValueAt(ecgAni mateCurRow, 0).toString()).doubleValue() / plotZoom);
    ecgAnimateLastPoint.setLocation(x, y);
    //curSecond = 0;
    //lastSecond = 0;
    } else{
    ecgAnimateLastPoint.setLocation(x, y);
    x = (int)(Double.valueOf(tableValues.getValueAt(ecgAni mateCurRow, 0).toString()).doubleValue() / plotZoom) - ecgAnimateInitialZero;
    y = posOriginY - (int)(Double.valueOf(tableValues.getValueAt(ecgAni mateCurRow, 1).toString()).doubleValue() * frameAmplitude / amplitude);
    }
    }
    }

    /*
    * class for verifying that the value of JtextField is a double number
    */
    class doubleVerifier extends InputVerifier{

    public boolean verify(JComponent input) {
    JTextField textF = (JTextField) input;
    double dNumber;
    boolean RetValue = true;

    try {
    dNumber = Double.valueOf(textF.getText()).doubleValue();
    } catch(java.lang.NumberFormatException e){
    getToolkit().beep();
    alert.setTitle("Error!!!");
    alertText.setText("You have to enter a double number, please retry!!!");
    alert.show();
    RetValue = false;
    }
    return(RetValue);
    }
    }

    /*
    * class for verifying that the value of JtextField is an integer number
    */
    class integerVerifier extends InputVerifier{

    public boolean verify(JComponent input) {
    JTextField textF = (JTextField) input;
    int dNumber;
    boolean RetValue = true;

    try {
    dNumber = Integer.valueOf(textF.getText()).intValue();
    } catch(java.lang.NumberFormatException e){
    getToolkit().beep();
    alert.setTitle("Error!!!");
    alertText.setText("You have to enter an integer number, please retry!!!");
    alert.show();
    RetValue = false;
    }
    return(RetValue);
    }
    }

    /*
    * class for verifying the value of the ECG Sampling frequency
    */
    class sfecgVerifier extends InputVerifier{

    public boolean verify(JComponent input) {
    JTextField textF = (JTextField) input;
    int dNumber;
    boolean RetValue = true;

    try {
    dNumber = Integer.valueOf(textF.getText()).intValue();
    txtSf.setText(Integer.toString(dNumber));
    } catch(java.lang.NumberFormatException e){
    getToolkit().beep();
    alert.setTitle("Error!!!");
    alertText.setText("You have to enter an integer number, please retry!!!");
    alert.show();
    RetValue = false;
    }
    return(RetValue);
    }
    }

    /*
    * class for verifying the value of the Internal Sampling frequency
    */
    class sfVerifier extends InputVerifier{

    public boolean verify(JComponent input) {
    JTextField textF = (JTextField) input;
    int dNumber;
    boolean RetValue = true;

    try {
    dNumber = Integer.valueOf(textF.getText()).intValue();
    int sfecgTemp;
    sfecgTemp = Integer.valueOf(txtSfecg.getText()).intValue();
    if(((int)Math.IEEEremainder(dNumber, sfecgTemp)) != 0){
    getToolkit().beep();
    alert.setTitle("Error!!!");
    alertText.setText("Internal sampling frequency must be an integer multiple of the ECG sampling frequency, please retry!");
    alert.show();
    RetValue = false;
    }
    } catch(java.lang.NumberFormatException e){
    getToolkit().beep();
    alert.setTitle("Error!!!");
    alertText.setText("You have to enter an integer number, please retry!!!");
    alert.show();
    RetValue = false;
    }
    return(RetValue);
    }
    }
    }

  2. #2
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,458
    Rep Power
    20

    Default Re: Need help finding the ECG algorithm

    Guide For New Members
    BB Code List - Java Programming Forum

    Even properly formatted, I don't think anyone here or on any forum will be prepared to analyze that much code. Why don't you approach the developer directly?

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  3. #3
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,458
    Rep Power
    20

    Default Re: Need help finding the ECG algorithm

    Quote Originally Posted by CHIDIONYZUZ View Post
    I have a Java applet that was made from a developer who shared his realtime ECG graph code.
    With a copyright notice that you conveniently neglected to include.
    Java Code:
    /************************************************************************/
    /*                                                                      */
    /* ecgApplet.java                                                       */
    /*                                                                      */
    /* Copyright (C) 2003 Mauricio Villarroel                               */
    /*  (mauricio DOT vllarroel AT estudiantes DOT ucb DOT edu DOT bo)      */
    /*                                                                      */
    /* ecgApplet.java and all its components are free software; you can     */
    /* redistribute them and/or modify it under the terms of the            */
    /* GNU General Public License as published by the Free Software         */
    /* Foundation; either version 2 of the License, or (at your option)     */
    /* any later version.                                                   */
    /*                                                                      */
    /* This file is distributed in the hope that it will be useful, but     */
    /* WITHOUT ANY WARRANTY; without even the implied warranty of           */
    /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                 */
    /* See the GNU General Public License for more details.                 */
    /*                                                                      */
    /************************************************************************/
    /*                                                                      */
    /* This file was created for the ECGSYN Application.                    */
    /*                                                                      */
    /* ECGSYN: A program for generating a realistic synthetic               */
    /* Electrocardiogram Signals.                                           */
    /* Copyright (c) 2003 by Patrick McSharry & Gari Clifford.              */
    /* All rights reserved.                                                 */
    /*                                                                      */
    /* See IEEE Transactions On Biomedical Engineering,                     */
    /* 50(3), 289-294, March 2003.                                          */
    /* Contact:                                                             */
    /* P. McSharry (patrick AT mcsharry DOT net)                            */
    /* G. Clifford (gari AT mit DOT edu)                                    */
    /*                                                                      */
    /************************************************************************/
    /*                                                                      */
    /* Further updates to this software will be published on:               */
    /* http://www.physionet.org/                             */
    /*                                                                      */
    /************************************************************************/
    http://www.physionet.org/physiotools...ecgApplet.java

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  4. #4
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,458
    Rep Power
    20

    Default Re: Need help finding the ECG algorithm

    My recommendation is that you sort out your requirement and write your own code. In any case, none of the NetBeans-generated GUI code will be of use to you in Android.

    If you have any problems with the Android code, be sure to post in the Android section.

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  5. #5
    CHIDIONYZUZ is offline Member
    Join Date
    Dec 2012
    Posts
    2
    Rep Power
    0

    Default Re: Need help finding the ECG algorithm

    Yea I could not fit the whole code, but it clearly states the code may be used for other purposes. I was thinking it's the part with the random function near the y values, I thought someone would be able to easily tell, but a programmer's code is unique to his or herself and not always easy to distinguish from other programmers. I guess I could try finding the ECG algorithm somewhere else, but I'll try asking my professor who teaches Java if he could point me in the right direction.
    Thanks anyways

Similar Threads

  1. Algorithm for finding max and min in an array.
    By Shyamz1 in forum New To Java
    Replies: 4
    Last Post: 10-04-2011, 11:45 PM
  2. Help with an Algorithm
    By Manfizy in forum New To Java
    Replies: 22
    Last Post: 07-03-2009, 08:16 AM
  3. Difficulty in finding the right algorithm
    By SolidCobra in forum New To Java
    Replies: 3
    Last Post: 10-06-2008, 12:55 AM
  4. O(log n) algorithm help !!!!!!
    By itseeker87 in forum New To Java
    Replies: 8
    Last Post: 09-09-2008, 06:12 PM
  5. Replies: 0
    Last Post: 04-12-2008, 09:38 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •