void do_ss_frame(Widget w, XtPointer client_data, XtPointer call_data) /* * Gte the selected set and call the routine to open up an Xbae widget */ { EditPoints *ep; int gno = cg; int setno = GetSelectedSet(editp_set_item); if (setno == SET_SELECT_ERROR) { errwin("No set selected"); return; } if( setno == SET_SELECT_NEXT ) { if( (setno=nextset(gno)) != -1 ) { add_point(gno, setno, 0., 0., 0, 0, SET_XY); add_point(gno, setno, 1, 1, 0, 0, SET_XY); setcomment( gno, setno, "editor" ); update_set_status( gno, setno ); } else { errwin("No set selected"); return; } } if (isactive_set(gno, setno)) { if (((ep = (EditPoints *) geteditpoints(gno, setno)) != NULL) && (ep->top != NULL)) { XtRaise(ep->top); } else { ep = newep(gno, setno); create_ss_frame(ep); } } else { errwin("Set not active"); } }
/* * Start up editor using GR_EDITOR variable * Note the change to the GR_EDITOR variable: If it requires a text * terminal it must provide it explicitly with an xterm -e prefix */ void do_ext_editor(Widget w, XtPointer client_data, XtPointer call_data) { char buf[256], tbuf[256], *fname, *mktemp(char *); char ebuf[256], *s; int setno = GetSelectedSet(editp_set_item), curgraph=cg; if (setno == SET_SELECT_ERROR) { errwin("No set selected"); return; } strcpy(tbuf, "/tmp/xmgrXXXXXX"); fname = mktemp(tbuf); if( setno == SET_SELECT_NEXT ){ if( (setno=nextset(curgraph)) == -1 ){ errwin("Not enough sets"); return; } activateset( curgraph, setno ); do_writesets(curgraph, setno, 0, fname, sformat); } else do_writesets(curgraph, setno, 0, fname, sformat); if ((s = getenv("GR_EDITOR")) != NULL) { strcpy(ebuf, s); } else { strcpy(ebuf, "xterm -e vi"); } sprintf(buf, "%s %s", ebuf, fname); system(buf); if( isactive_set( curgraph, setno ) ) { softkillset( curgraph, setno ); getdata(curgraph, fname, SOURCE_DISK, dataset_type( curgraph, setno ) ); } else { setcomment( curgraph, setno, "editor" ); getdata(curgraph, fname, SOURCE_DISK, SET_XY ); } sprintf(buf, "rm %s", fname); system(buf); update_all( curgraph ); doforce_redraw(); }
static void eblock_accept_notify_proc(Widget, XtPointer, XtPointer) { int i = 0; char buf[256]; int setno, graphno; int cx, cy, c1 = 0, c2 = 0, c3 = 0, c4 = 0; //d1, double *tx, *ty, *t2, *t3, *t4, *t5; //d1 = (int) GetChoice(eblock_type_choice_item); cx = (int)GetChoice(eblock_x_choice_item) - 1; cy = (int)GetChoice(eblock_y_choice_item); if (cx >= 0 && cx >= blockncols) { errwin("Column for X exceeds the number of columns in block data"); return; } if (cy >= blockncols) { errwin("Column for Y exceeds the number of columns in block data"); return; } switch (block_curtype) { case XY: break; case XYRT: case XYDX: case XYDY: case XYZ: c1 = (int)GetChoice(eblock_e1_choice_item); if (c1 >= blockncols) { errwin("Column for E1 exceeds the number of columns in block data"); return; } break; case XYDXDX: case XYDYDY: case XYDXDY: c1 = (int)GetChoice(eblock_e1_choice_item); c2 = (int)GetChoice(eblock_e2_choice_item); if (c1 >= blockncols) { errwin("Column for E1 exceeds the number of columns in block data"); return; } if (c2 >= blockncols) { errwin("Column for E2 exceeds the number of columns in block data"); return; } break; case XYHILO: case XYBOX: c1 = (int)GetChoice(eblock_e1_choice_item); c2 = (int)GetChoice(eblock_e2_choice_item); c3 = (int)GetChoice(eblock_e3_choice_item); if (c1 >= blockncols) { errwin("Column for E1 exceeds the number of columns in block data"); return; } if (c2 >= blockncols) { errwin("Column for E2 exceeds the number of columns in block data"); return; } if (c3 >= blockncols) { errwin("Column for E3 exceeds the number of columns in block data"); return; } break; case XYBOXPLOT: c1 = (int)GetChoice(eblock_e1_choice_item); c2 = (int)GetChoice(eblock_e2_choice_item); c3 = (int)GetChoice(eblock_e3_choice_item); c4 = (int)GetChoice(eblock_e4_choice_item); if (c1 >= blockncols) { errwin("Column for E1 exceeds the number of columns in block data"); return; } if (c2 >= blockncols) { errwin("Column for E2 exceeds the number of columns in block data"); return; } if (c3 >= blockncols) { errwin("Column for E3 exceeds the number of columns in block data"); return; } if (c4 >= blockncols) { errwin("Column for E4 exceeds the number of columns in block data"); return; } } setno = -1; graphno = (int)GetChoice(eblock_graph_choice_item) - 1; if (graphno == -1) { graphno = cg; } if (setno == -1) { setno = nextset(graphno); } if (setno == -1) { return; } if (g[graphno].active == OFF) { set_graph_active(graphno); } activateset(graphno, setno); settype(graphno, setno, block_curtype); tx = (double *)calloc(blocklen, sizeof(double)); if (tx == NULL) { errwin("Can't allocate memory for X"); return; } ty = (double *)calloc(blocklen, sizeof(double)); if (ty == NULL) { cfree(tx); errwin("Can't allocate memory for Y"); return; } for (i = 0; i < blocklen; i++) { if (cx == -1) { tx[i] = i + 1; } else { tx[i] = blockdata[cx][i]; } ty[i] = blockdata[cy][i]; } setcol(graphno, tx, setno, blocklen, 0); setcol(graphno, ty, setno, blocklen, 1); switch (block_curtype) { case XY: sprintf(buf, "Cols %d %d", cx + 1, cy + 1); break; case XYRT: case XYDX: case XYDY: case XYZ: sprintf(buf, "Cols %d %d %d", cx + 1, cy + 1, c1 + 1); t2 = (double *)calloc(blocklen, sizeof(double)); for (i = 0; i < blocklen; i++) { t2[i] = blockdata[c1][i]; } setcol(graphno, t2, setno, blocklen, 2); break; case XYDXDX: case XYDYDY: case XYDXDY: sprintf(buf, "Cols %d %d %d %d", cx + 1, cy + 1, c1 + 1, c2 + 1); t2 = (double *)calloc(blocklen, sizeof(double)); t3 = (double *)calloc(blocklen, sizeof(double)); for (i = 0; i < blocklen; i++) { t2[i] = blockdata[c1][i]; t3[i] = blockdata[c2][i]; } setcol(graphno, t2, setno, blocklen, 2); setcol(graphno, t3, setno, blocklen, 3); break; case XYHILO: case XYBOX: sprintf(buf, "Cols %d %d %d %d %d", cx + 1, cy + 1, c1 + 1, c2 + 1, c3 + 1); t2 = (double *)calloc(blocklen, sizeof(double)); t3 = (double *)calloc(blocklen, sizeof(double)); t4 = (double *)calloc(blocklen, sizeof(double)); for (i = 0; i < blocklen; i++) { t2[i] = blockdata[c1][i]; t3[i] = blockdata[c2][i]; t4[i] = blockdata[c3][i]; } setcol(graphno, t2, setno, blocklen, 2); setcol(graphno, t3, setno, blocklen, 3); setcol(graphno, t4, setno, blocklen, 4); break; case XYBOXPLOT: sprintf(buf, "Cols %d %d %d %d %d %d", cx + 1, cy + 1, c1 + 1, c2 + 1, c3 + 1, c4 + 1); t2 = (double *)calloc(blocklen, sizeof(double)); t3 = (double *)calloc(blocklen, sizeof(double)); t4 = (double *)calloc(blocklen, sizeof(double)); t5 = (double *)calloc(blocklen, sizeof(double)); for (i = 0; i < blocklen; i++) { t2[i] = blockdata[c1][i]; t3[i] = blockdata[c2][i]; t4[i] = blockdata[c3][i]; t5[i] = blockdata[c4][i]; } setcol(graphno, t2, setno, blocklen, 2); setcol(graphno, t3, setno, blocklen, 3); setcol(graphno, t4, setno, blocklen, 4); setcol(graphno, t5, setno, blocklen, 5); break; } setcomment(graphno, setno, buf); updatesetminmax(graphno, setno); update_status_popup(NULL, NULL, NULL); drawgraph(); }
/* ARGSUSED */ static void do_nonl_proc(Widget, XtPointer, XtPointer) { int i, setno, loadset, loadto, graphto, npar, info; double tol, a[MAXPARM]; char fstr[256]; double *y, *yp; set_wait_cursor(); curset = setno = (int)GetChoice(nonl_set_item); loadto = (int)GetChoice(nonl_load_item); graphto = (int)GetChoice(nonl_loadgraph_item) - 1; tol = atof((char *)xv_getstr(nonl_tol_item)); if (graphto < 0) { graphto = cg; } npar = atoi((char *)xv_getstr(nonl_nparm_item)); strcpy(fstr, (char *)xv_getstr(nonl_formula_item)); for (i = 0; i < MAXPARM; i++) { a[i] = 0.0; strcpy(buf, (char *)xv_getstr(nonl_initial_item[i])); sscanf(buf, "%lf", &a[i]); } yp = (double *)calloc(getsetlength(cg, setno), sizeof(double)); if (yp == NULL) { errwin("Memory allocation error, operation cancelled"); unset_wait_cursor(); return; } y = gety(cg, setno); for (i = 0; i < getsetlength(cg, setno); i++) { yp[i] = y[i]; } sprintf(buf, "Fitting: %s\n", fstr); stufftext(buf, 0); sprintf(buf, "Initial guess:\n"); stufftext(buf, 0); for (i = 0; i < npar; i++) { sprintf(buf, "\ta%1d = %.9lf\n", i, a[i]); stufftext(buf, 0); } sprintf(buf, "Tolerance = %.9lf\n", tol); stufftext(buf, 0); lmfit(fstr, getsetlength(cg, setno), getx(cg, setno), yp, y, npar, a, tol, &info); for (i = 0; i < getsetlength(cg, setno); i++) { y[i] = yp[i]; } free(yp); for (i = 0; i < MAXPARM; i++) { sprintf(buf, "%.9lf", a[i]); xv_setstr(nonl_computed_item[i], buf); nonl_parms[i] = a[i]; } if (info > 0 && info < 4) { sprintf(buf, "Computed values:\n"); stufftext(buf, 0); for (i = 0; i < npar; i++) { sprintf(buf, "\ta%1d = %.9lf\n", i, a[i]); stufftext(buf, 0); } loadset = nextset(cg); if (loadset != -1) { do_copyset(cg, setno, cg, loadset); } else { unset_wait_cursor(); return; } switch (loadto) { case 0: sprintf(buf, "Evaluating function and loading result to set %d:\n", loadset); stufftext(buf, 0); do_compute(loadset, 0, graphto, fstr); break; case 1: sprintf(buf, "Evaluating function and loading residuals to set %d:\n", loadset); stufftext(buf, 0); do_compute(loadset, 0, graphto, fstr); break; case 2: sprintf(buf, "Computed function not evaluated\n"); stufftext(buf, 0); break; } } /* if (info >= 4) { do_compute(setno, 1, graphto, fstr); } */ if (info >= 0 && info <= 7) { char *s; switch (info) { case 0: s = (char *)"Improper input parameters.\n"; break; case 1: s = (char *)"Relative error in the sum of squares is at most tol.\n"; break; case 2: s = (char *)"Relative error between A and the solution is at most tol.\n"; break; case 3: s = (char *)"Relative error in the sum of squares and A and the solution is at most tol.\n"; break; case 4: s = (char *)"Fvec is orthogonal to the columns of the jacobian to machine precision.\n"; break; case 5: s = (char *)"Number of calls to fcn has reached or exceeded 200*(n+1).\n"; break; case 6: s = (char *)"Tol is too small. No further reduction in the sum of squares is possible.\n"; break; case 7: s = (char *)"Tol is too small. No further improvement in the approximate solution A is possible.\n"; break; } stufftext(s, 0); stufftext((char *)"\n", 0); } unset_wait_cursor(); }
/* ARGSUSED */ static void do_nonl_proc(Widget w, XtPointer client_data, XtPointer call_data) { int i, npts = 0, info; double delx, *xfit, *y, *yfit; int nsteps = (int) client_data; set_wait_cursor(); curset = nlsetno = GetSelectedSet(nonl_set_item); if (curset == SET_SELECT_ERROR) { errmsg("No set selected"); unset_wait_cursor(); return; } nonl_opts.tolerance = atof((char *) xv_getstr(nonl_tol_item)); nonl_opts.parnum = GetChoice(nonl_nparm_item); strcpy(nonl_opts.formula, (char *) xv_getstr(nonl_formula_item)); for (i = 0; i < nonl_opts.parnum; i++) { strcpy(buf, (char *) xv_getstr(nonl_value_item[i])); if (sscanf(buf, "%lf", &nonl_parms[i].value) != 1) { errmsg("Invalid input in parameter field"); unset_wait_cursor(); return; } nonl_parms[i].constr = XmToggleButtonGetState(nonl_constr_item[i]); if (nonl_parms[i].constr) { strcpy(buf, (char *) xv_getstr(nonl_lowb_item[i])); if (sscanf(buf, "%lf", &nonl_parms[i].min) != 1) { errmsg("Invalid input in low-bound field"); unset_wait_cursor(); return; } strcpy(buf, (char *) xv_getstr(nonl_uppb_item[i])); if (sscanf(buf, "%lf", &nonl_parms[i].max) != 1) { errmsg("Invalid input in upper-bound field"); unset_wait_cursor(); return; } if ((nonl_parms[i].value < nonl_parms[i].min) || (nonl_parms[i].value > nonl_parms[i].max)) { errmsg("Initial values must be within bounds"); unset_wait_cursor(); return; } } } nonl_prefs.autoload = XmToggleButtonGetState(nonl_autol_item); for (i = 0; i < 3; i++) { if (XmToggleButtonGetState(nonl_load_item[i])) { nonl_prefs.load = i; break; } } if (nonl_prefs.load == LOAD_FUNCTION) { strcpy(buf, (char *) xv_getstr(nonl_start_item)); if (sscanf(buf, "%lf", &nonl_prefs.start) != 1) { errmsg("Invalid input in start field"); unset_wait_cursor(); return; } strcpy(buf, (char *) xv_getstr(nonl_stop_item)); if (sscanf(buf, "%lf", &nonl_prefs.stop) != 1) { errmsg("Invalid input in stop field"); unset_wait_cursor(); return; } strcpy(buf, (char *) xv_getstr(nonl_npts_item)); if (sscanf(buf, "%d", &nonl_prefs.npoints) != 1) { errmsg("Invalid input in start field"); unset_wait_cursor(); return; } } if (nsteps) { /* we are asked to fit */ sprintf(buf, "Fitting with formula: %s\n", nonl_opts.formula); stufftext(buf, 0); sprintf(buf, "Initial guesses:\n"); stufftext(buf, 0); for (i = 0; i < nonl_opts.parnum; i++) { sprintf(buf, "\ta%1d = %g\n", i, nonl_parms[i].value); stufftext(buf, 0); } sprintf(buf, "Tolerance = %g\n", nonl_opts.tolerance); stufftext(buf, 0); /* * The fit itself! */ info = do_nonlfit(cg, nlsetno, nsteps); if (info == -1) { errmsg("Memory allocation error in do_nonlfit()"); unset_wait_cursor(); return; } for (i = 0; i < nonl_opts.parnum; i++) { sprintf(buf, "%g", nonl_parms[i].value); xv_setstr(nonl_value_item[i], buf); } if ((info > 0 && info < 4) || (info == 5)) { sprintf(buf, "Computed values:\n"); stufftext(buf, 0); for (i = 0; i < nonl_opts.parnum; i++) { sprintf(buf, "\ta%1d = %g\n", i, nonl_parms[i].value); stufftext(buf, 0); } } if (info >= 0 && info <= 7) { char *s; switch (info) { case 0: s = "Improper input parameters.\n"; break; case 1: s = "Relative error in the sum of squares is at most tol.\n"; break; case 2: s = "Relative error between A and the solution is at most tol.\n"; break; case 3: s = "Relative error in the sum of squares and A and the solution is at most tol.\n"; break; case 4: s = "Fvec is orthogonal to the columns of the jacobian to machine precision.\n"; break; case 5: s = "\n"; break; case 6: s = "Tol is too small. No further reduction in the sum of squares is possible.\n"; break; case 7: s = "Tol is too small. No further improvement in the approximate solution A is possible.\n"; break; default: s = "\n"; errmsg("Internal error in do_nonl_proc(), please report"); break; } stufftext(s, 0); stufftext("\n", 0); } } /* endif (nsteps) */ /* * Select & activate a set to load results to */ if (!nsteps || nonl_prefs.autoload) { /* check if the set is already allocated */ if ((nlloadset == -1) || (nlloadset == nlsetno) || !getsetlength(cg, nlloadset)) { nlloadset = nextset(cg); if (nlloadset == -1) { errmsg("No more sets!"); unset_wait_cursor(); return; } else { activateset(cg, nlloadset); setlength(cg, nlloadset, 1); } } switch (nonl_prefs.load) { case LOAD_VALUES: sprintf(buf, "Evaluating fitted values and loading result to set %d:\n", nlloadset); stufftext(buf, 0); npts = getsetlength(cg, nlsetno); setlength(cg, nlloadset, npts); copycol2(cg, nlsetno, cg, nlloadset, 0); break; case LOAD_RESIDUALS: sprintf(buf, "Evaluating fitted values and loading residuals to set %d:\n", nlloadset); stufftext(buf, 0); npts = getsetlength(cg, nlsetno); setlength(cg, nlloadset, npts); copycol2(cg, nlsetno, cg, nlloadset, 0); break; case LOAD_FUNCTION: sprintf(buf, "Computing fitting function and loading result to set %d:\n", nlloadset); stufftext(buf, 0); npts = nonl_prefs.npoints; if (npts <= 1) { errmsg("Number of points must be > 1"); unset_wait_cursor(); return; } setlength(cg, nlloadset, npts); delx = (nonl_prefs.stop - nonl_prefs.start)/(npts - 1); xfit = getx(cg, nlloadset); for (i = 0; i < npts; i++) { xfit[i] = nonl_prefs.start + i * delx; } break; } setcomment(cg, nlloadset, nonl_opts.formula); do_compute(nlloadset, 0, cg, nonl_opts.formula); if (nonl_prefs.load == LOAD_RESIDUALS) { /* load residuals */ y = gety(cg, nlsetno); yfit = gety(cg, nlloadset); for (i = 0; i < npts; i++) { yfit[i] -= y[i]; } } update_set_lists(cg); drawgraph(); } unset_wait_cursor(); }
void fext_routine( int gto, int feature, int abs_src, int abs_set, int abs_graph ) { int i, cs, ns, fts, ncurves, extract_err; double datum, dummy, *absy; double y1, y2; int iy1, iy2; char tbuf[1024]; float *abscissa; abscissa = (float *)malloc( maxplot*sizeof(float) ); if( !isactive_graph( gto ) ){ errwin("Graph for results must be active"); return; } if( (ns=nextset( gto ) )== -1 ) { errwin("Choose a new graph or kill sets!"); return; } ncurves = nactive(cg); switch( abs_src ) { case 0: /* use index */ for( i=0; i<ncurves; i++ ) abscissa[i] = i+1; break; case 1: /* use legend label */ cs = 0; for( i=0; i<ncurves; i++ ){ while( !isactive_set( cg, cs ) ) cs++; if(!sscanf( g[cg].p[cs].lstr, "%f", &abscissa[i])) break; cs++; } if( i != ncurves ) { errwin("Bad legend label"); return; } break; case 2: /* use X from set */ if( !isactive_set( abs_graph, abs_set ) ){ errwin("Abscissa set not active"); return; } if( getsetlength( abs_graph, abs_set ) < ncurves ) { errwin("Not enough points in set"); return; } absy = getx( abs_graph, abs_set ); for( i=0; i<ncurves; i++ ) abscissa[i] = absy[i]; break; case 3: /* use Y from set */ if( !isactive_set( abs_graph, abs_set ) ){ errwin("Abscissa set not active"); return; } if( getsetlength( abs_graph, abs_set ) < ncurves ) { errwin("Not enough points in set"); return; } absy = gety( abs_graph, abs_set ); for( i=0; i<ncurves; i++ ) abscissa[i] = absy[i]; break; } cs = 0; tbuf[0] = '\0'; for( i=0; i<ncurves; i++ ) { while( !isactive_set( cg, cs ) ) cs++; extract_err = 0; switch( feature ) { case 0: /* Y minimum */ datum = g[cg].p[cs].ymin; break; case 1: /* Y maximum */ datum = g[cg].p[cs].ymax; break; case 2: /* Y mean */ stasum(gety(cg, cs), getsetlength(cg, cs), &datum, &dummy, 0); break; case 3: /* Y std dev */ stasum(gety(cg, cs), getsetlength(cg, cs), &dummy, &datum, 0); break; case 4: /* Y median */ getmedian( cg, cs, DATA_Y, &datum ); break; case 5: /* X minimum */ datum = g[cg].p[cs].xmin; break; case 6: /* X maximum */ datum = g[cg].p[cs].xmax; break; case 7: /* X mean */ stasum(getx(cg, cs), getsetlength(cg, cs), &datum, &dummy, 0); break; case 8: /* X std dev */ stasum(getx(cg, cs), getsetlength(cg, cs), &dummy, &datum, 0); break; case 9: /* X median */ getmedian( cg, cs, DATA_X, &datum ); break; case 10: /* frequency and period */ case 11: if ( ilog2(getsetlength(cg, cs)) <= 0) /* only DFT */ do_fourier(0, cs, 0, 1, 0, 0, 0); else /* FFT */ do_fourier(1, cs, 0, 1, 0, 0, 0); sprintf( tbuf, "FT of set %d", cs ); fts = 0; while( strcmp( tbuf, g[cg].p[fts].comments+1 ) ) fts++; minmax(gety(cg, fts), getsetlength(cg, fts),&y1,&y2,&iy1,&iy2); if( feature == 8 ) datum = g[cg].p[fts].ex[0][iy2-1]; else datum = 1./g[cg].p[fts].ex[0][iy2-1]; killset( cg, fts ); /* get rid of Fourier set */ break; case 12: /* first zero crossing */ if( get_zero_crossing( getsetlength( cg, cs ), getx( cg, cs ),gety( cg, cs ), &datum ) ){ sprintf( tbuf+strlen(tbuf), "Unable to find zero crossing of set %d\n", cs ); errwin( tbuf ); extract_err = 1; } break; case 13: /* rise time */ if( get_rise_time( getsetlength(cg,cs), getx(cg,cs), gety(cg,cs), g[cg].p[cs].ymin, g[cg].p[cs].ymax, &datum ) ){ sprintf( tbuf+strlen(tbuf), "Unable to find rise time of set %d\n", cs ); errwin( tbuf ); extract_err = 1; } break; case 14: /* fall time */ if( get_fall_time( getsetlength(cg,cs), getx(cg,cs), gety(cg,cs), g[cg].p[cs].ymin, g[cg].p[cs].ymax, &datum ) ){ sprintf( tbuf+strlen(tbuf), "Unable to find fall time of set %d\n", cs ); extract_err = 1; errwin( tbuf ); } break; case 15: /* slope */ if( mute_linear_regression( getsetlength( cg, cs ), getx( cg, cs ),gety( cg, cs ), &datum, &dummy ) ) { sprintf( tbuf+strlen(tbuf), "Unable to find slope of set %d\n", cs ); errwin( tbuf ); extract_err = 1; } break; case 16: /* Y intercept */ if( mute_linear_regression( getsetlength( cg, cs ), getx( cg, cs ), gety( cg, cs ), &dummy, &datum ) ) { sprintf( tbuf+strlen(tbuf), "Unable to find y-intercept of set %d\n", cs ); errwin( tbuf ); extract_err = 1; } break; case 17: /* set length */ datum = getsetlength( cg, cs ); break; case 18: /* half maximal widths */ if( get_half_max_width(getsetlength( cg, cs ), getx(cg,cs), gety(cg,cs), g[cg].p[cs].ymin, g[cg].p[cs].ymax,&datum) ) { sprintf( tbuf+strlen(tbuf), "Unable to find half maximal width of set %d\n", cs ); extract_err = 1; errwin( tbuf ); } break; case 19: /* Barycenter X */ get_barycenter( getsetlength( cg, cs ), gety(cg,cs), getx(cg,cs), &datum ); break; case 20: /* Barycenter Y */ get_barycenter( getsetlength( cg, cs ), getx(cg,cs), gety(cg,cs), &datum ); break; case 21: /* X of Maximum Y */ get_max_pos( gety(cg, cs), getx( cg, cs ), getsetlength( cg, cs ), g[cg].p[cs].ymax, &datum ); break; case 22: /* Y of Maximum X */ get_max_pos( getx(cg, cs), gety( cg, cs ), getsetlength( cg, cs ), g[cg].p[cs].xmax, &datum ); break; } if( !extract_err ) add_point( gto, ns, abscissa[i], datum, 0, 0, SET_XY ); cs++; } /* set comment */ switch( feature ) { case 0: /* Y minimum */ sprintf(tbuf,"Y minima of graph %d",cg); break; case 1: /* Y maximum */ sprintf(tbuf,"Y maxima of graph %d",cg); break; case 2: /* Y mean */ sprintf(tbuf,"Y means of graph %d",cg); break; case 3: /* Y std dev */ sprintf(tbuf,"Y std. dev.'s of graph %d",cg); break; case 4: /* Y median */ sprintf(tbuf,"Y medians of graph %d",cg); break; case 5: /* X minimum */ sprintf(tbuf,"X minima of graph %d",cg); break; case 6: /* X maximum */ sprintf(tbuf,"X maxima of graph %d",cg); break; case 7: /* X mean */ sprintf(tbuf,"X means of graph %d",cg); break; case 8: /* X std dev */ sprintf(tbuf,"X std. dev.'s of graph %d",cg); break; case 9: /* X median */ sprintf(tbuf,"X medians of graph %d",cg); break; case 10: /* frequency and period */ sprintf(tbuf,"frequencies of graph %d",cg); break; case 11: sprintf(tbuf,"periods of graph %d",cg); break; case 12: /* first zero crossing */ sprintf(tbuf,"zero crossings of graph %d",cg); break; case 13: /* rise time */ sprintf(tbuf,"rise times of graph %d",cg); break; case 14: /* fall time */ sprintf(tbuf,"fall times of graph %d",cg); break; case 15: /* slopes */ sprintf(tbuf,"slopes of graph %d",cg); break; case 16: /* Y intercepts */ sprintf(tbuf,"Y intercepts of graph %d",cg); break; case 17: /* set lengths */ sprintf(tbuf,"set lengths of graph %d",cg); break; case 18: /* 1/2 maximal widths */ sprintf(tbuf,"half maximal widths of graph %d",cg); break; case 19: /* barycenter X */ sprintf(tbuf,"X barycenters of graph %d",cg); break; case 20: /* barycenter Y */ sprintf(tbuf,"Y barycenters of graph %d",cg); break; case 21: /* X of maximum Y */ sprintf(tbuf,"X positions of maximum Y's of graph %d",cg); break; case 22: /* Y of maximum X */ sprintf(tbuf,"Y positions of maximum X's of graph %d",cg); break; } setcomment( gto, ns, tbuf ); free( abscissa ); plotone( gto ); }