/* ************************************************************** */ /* * Module BLWIRE * This module contains functions to determine the integrated field * strength of a magnet using a stretched wire. The VTwire system * must be initialized prior to using this module. * * Zachary Wolf * 11/24/99 */ /* ************************************************************** */ /* INCLUDES */ #include #include #include #include #include "vtwire.h" #include "blwire.h" #include "blwireui.h" /* ************************************************************** */ /* PRIVATE PARAMETERS */ char log_file[BLWIRE_MAX_NUM_CHAR + 1]; char dat_file[BLWIRE_MAX_NUM_CHAR + 1]; char plt_file[BLWIRE_MAX_NUM_CHAR + 1]; static struct blwire_param_struct blwire_param; /* ************************************************************** */ /* PRIVATE GLOBAL VARIABLES */ static char msg[BLWIRE_MAX_NUM_CHAR + 1]; /* ************************************************************** */ /* PRIVATE FUNCTIONS */ void blwire_error(char* message); int blwire_check_param(void); void blwire_log_measurement(char* meas); void blwire_log_bl_ave(double x0, double dx, double Nw, double vt_ave, double vt_rms, double bl_ave, double bl_rms); void blwire_log_integ_str(int num_str_har, double sl_ave, double sl_rms); void blwire_log_calc_integ_str(int num_str_har, int num_x0_pos, double x0[], double bl_ave[], double bl_rms[], double sl_ave, double sl_rms); void blwire_log_check_quad_str(double slope, double inter, double sig_slope, double sig_sq, double gl_ave, double gl_rms); void blwire_log_mag_center(double bl_center, double inter, double sig_inter, double slope, double sig_slope, double x_center, double x_center_err); void blwire_log_bl_vs_x_fit(int num_x0_pos, double x0[], double bl_ave[], double bl_rms[], int fit_order, double fit_coeff[], double fit_coeff_err[]); /* ************************************************************** */ /* PUBLIC FUNCTIONS */ /* ************************************************************** */ /* * blwire_init * This function is used to initialize the BLwire system. * * Zachary Wolf * 11/24/99 */ void blwire_init(char log_file_in[], char dat_file_in[], char plt_file_in[], struct blwire_param_struct blwire_param_in) { /* Declare variables */ int err; /* Save parameters for future use */ strcpy(log_file, log_file_in); strcpy(dat_file, dat_file_in); strcpy(plt_file, plt_file_in); blwire_param = blwire_param_in; /* Check all parameter values to find any problems */ err = blwire_check_param(); if (err != 0) { blwire_error("Problem with parameter values"); return; } /* Done */ return; } /* ************************************************************** */ /* * blwire_get_bl_ave * This function measures the integrated field strength of a magnet * several times. * It computes the average and rms variation of the measurements. * * Input: * x0, center of the wire motion (m) * dx, distance the wire moves (m) * * Output: * bl_ave, average of integrated field strength measurements (Tm) * bl_rms, rms variation of integrated field strength measurements (Tm) * * Zachary Wolf * 11/24/99 */ void blwire_get_bl_ave(double x0, double dx, double* bl_ave, double* bl_rms) { /* Declare variables */ int err; double vt_ave, vt_rms; double Nw; /* Check all module lever parameter values */ err = blwire_check_param(); if (err != 0) { blwire_error("blwire_get_blwire_ave: Problem with parameter values"); return; } /* Message */ printf("\nBeginning a stretched wire measurement cycle...\n"); /* Debug */ #ifdef DUMMY_DEVICES *bl_ave = x0 - .01; *bl_rms = .001 * *bl_ave; blwire_log_bl_ave(x0, dx, Nw, vt_ave, vt_rms, *bl_ave, *bl_rms); printf("BL = %f +- %f (Tm)\n", *bl_ave, *bl_rms); return; #endif /* Measure the integrated voltage */ vtwire_get_vt_ave(x0, dx, &vt_ave, &vt_rms); /* Calculate the integrated field strength */ Nw = blwire_param.num_turns_wire; *bl_ave = vt_ave / (Nw * fabs(dx)); *bl_rms = vt_rms / (Nw * fabs(dx)); /* Log the results */ blwire_log_bl_ave(x0, dx, Nw, vt_ave, vt_rms, *bl_ave, *bl_rms); /* Write the results to the screen */ printf("BL = %f +- %f Tm\n", *bl_ave, *bl_rms); /* Done */ return; } /* ************************************************************** */ /* * blwire_get_bl_vs_x * This function measures the integrated field strength of a magnet * at specified x positions. * It computes the average and rms variation of the measurements * at each x position. * * Input: * num_x0_pos, the number of positions to measure BL at * x0[0 to num_x0_pos - 1], array of center of the wire motion positions (m) * dx, distance the wire moves (m) * * Output: * bl_ave[0 to num_x0_pos - 1], average of integrated field strength measurements at each position (Tm) * bl_rms[0 to num_x0_pos - 1], rms variation of integrated field strength measurements at each position (Tm) * * Zachary Wolf * 11/24/99 */ void blwire_get_bl_vs_x(int num_x0_pos, double x0[], double dx, double bl_ave[], double bl_rms[]) { /* Declare variables */ int i; /* Check input parameters */ if (num_x0_pos < 1 || num_x0_pos > BLWIRE_MAX_NUM_X0_POS) { printf("blwire_get_bl_vs_x: unknown num_x0_pos"); return; } /* Perform the integrated field strength measurements */ for (i = 0; i < num_x0_pos; i++) { blwire_get_bl_ave(x0[i], dx, &bl_ave[i], &bl_rms[i]); blwireui_update_bl_vs_x(x0[i], bl_ave[i], bl_rms[i]); } /* Message */ printf("\nMoving back to the zero position...\n"); /* Move the wire back to the zero position */ vtwire_move_wire_abs(0.); /* Done */ return; } /* ************************************************************** */ /* * blwire_get_integ_str * This function measures the strength of a magnet. * It returns the integrated field strength of a dipole, the * integrated gradient of a quadrupole, ... * * Input: * num_str_har, number of the field harmonic the strength is being returned for * num_x0_pos, the number of positions to measure BL at * x0[0 to num_x0_pos - 1], array of center of the wire motion positions (m) * dx, distance the wire moves (m) * * Output: * sl_ave, integrated strength (Tm^2/m^n), average * sl_rms, integrated strength (Tm^2/m^n), rms variation * * Zachary Wolf * 11/24/99 */ void blwire_get_integ_str(int num_str_har, int num_x0_pos, double x0[], double dx, double* sl_ave, double* sl_rms) { /* Declare variables */ int err; double bl_ave_vs_x[BLWIRE_MAX_NUM_X0_POS + 1]; double bl_rms_vs_x[BLWIRE_MAX_NUM_X0_POS + 1]; /* Check input parameters */ if (num_str_har < 1 || num_str_har > 4) { printf("blwire_get_integ_str: unknown num_str_har"); return; } if (num_x0_pos < 1 || num_x0_pos > BLWIRE_MAX_NUM_X0_POS) { printf("blwire_get_integ_str: unknown num_x0_pos"); return; } /* Check all module lever parameter values */ err = blwire_check_param(); if (err != 0) { blwire_error("blwire_get_integ_str: Problem with parameter values"); return; } /* Message */ printf("\nMeasuring the magnet strength...\n"); /* Log the measurement */ blwire_log_measurement("Measuring the magnet strength..."); /* Measure BL at the x0 positions */ blwire_get_bl_vs_x(num_x0_pos, x0, dx, bl_ave_vs_x, bl_rms_vs_x); /* Calculate the magnet strength */ blwire_calc_integ_str(num_str_har, num_x0_pos, x0, bl_ave_vs_x, bl_rms_vs_x, sl_ave, sl_rms); /* Log the results */ blwire_log_integ_str(num_str_har, *sl_ave, *sl_rms); /* Write the results to the screen */ if (num_str_har == 1) printf("\nIntegrated Field Strength BL = %f +- %f Tm\n", *sl_ave, *sl_rms); if (num_str_har == 2) printf("\nIntegrated Gradient GL = %f +- %f T\n", *sl_ave, *sl_rms); if (num_str_har == 3) printf("\nIntegrated Sextupole Strength SL = %f +- %f T/m\n", *sl_ave, *sl_rms); if (num_str_har == 4) printf("\nIntegrated Octupole Strength OL = %f +- %f T/m^2\n", *sl_ave, *sl_rms); /* Done */ return; } /* ************************************************************** */ /* * blwire_calc_integ_str * This function uses measurements of the integrated field strength BL(x) * of a magnet at specified x positions to calculate the integrated * strength of a magnet. * By(x) = B + G*x + 1/2*S*x^2 + 1/6*O*x^3 + ... * BL(x) = BL + GL*x + 1/2*SL*x^2 + 1/6*OL*x^3 + ... * The function returns BL for a dipole, GL for a quadrupole, SL for * a sextupole, and OL for an octupole. * * Input: * num_str_har, the number of the main field harmonic (1 = dipole, 2 = quad, ...) * num_x0_pos, the number of positions to measure BL at * x0[0 to num_x0_pos - 1], array of center of the wire motion positions (m) * bl_ave[0 to num_x0_pos - 1], average of integrated field strength measurements at each position (Tm) * bl_rms[0 to num_x0_pos - 1], rms variation of integrated field strength measurements at each position (Tm) * * Output: * sl_ave, integrated strength (Tm/m^(n-1)) * sl_rms, error estimate on SL (Tm/m^(n-1)) * * Zachary Wolf * 12/2/99 */ void blwire_calc_integ_str(int num_str_har, int num_x0_pos, double x0[], double bl_ave[], double bl_rms[], double* sl_ave, double* sl_rms) { /* Declare variables */ int err; double bl_fit[200]; double coeff[20]; double save_coeff[20], save_coeff_err[20]; double mean_sq_err; double factorial; int i, j; double sum_sq; double str_coeff; double bl_adj[200]; double Sxy, Sx, Sy, Sxx, det, slope, inter, sig_sq, sig_slope, gl_ave, gl_rms; /* Check input parameters */ if (num_str_har < 1 || num_str_har > 4) { blwire_error("blwire_calc_integ_str: num_str_har has improper value"); return; } if (num_x0_pos < 1 || num_x0_pos > 200) { blwire_error("blwire_calc_integ_str: num_x0_pos has improper value"); return; } /* Determine the (n-1)! in the Taylor expansion */ if (num_str_har == 1) factorial = 1.; else if (num_str_har == 2) factorial = 1.; else if (num_str_har == 3) factorial = 2.; else if (num_str_har == 4) factorial = 6.; else blwire_error("blwire_calc_integ_str: num_str_har has improper value"); /* Perform a polynomial fit to the BL(x) measurements */ err = PolyFit(x0, bl_ave, num_x0_pos, num_str_har - 1, bl_fit, coeff, &mean_sq_err); if (err != 0) { blwire_error("blwire_calc_integ_str: error in polynomial fit"); return; } for (i = 0; i <= num_str_har - 1; i++) save_coeff[i] = coeff[i]; /* Plot the fitted points */ blwireui_update_bl_vs_x_fit(num_x0_pos, x0, bl_fit); /* Calculate the integrated strength */ str_coeff = coeff[num_str_har - 1]; *sl_ave = str_coeff * factorial; /* Estimate the error */ /* sig_c^2 = Sum_y [(dc/dy)^2 * sig_y^2] */ sum_sq = 0.; for (j = 0; j <= num_str_har - 1; j++) save_coeff_err[j] = 0.; for (i = 0; i < num_x0_pos; i++) { for (j = 0; j < num_x0_pos; j++) bl_adj[j] = bl_ave[j]; bl_adj[i] = bl_ave[i] + bl_rms[i]; err = PolyFit(x0, bl_adj, num_x0_pos, num_str_har - 1, bl_fit, coeff, &mean_sq_err); if (err != 0) { blwire_error("blwire_calc_integ_str: error in polynomial fit"); return; } sum_sq = sum_sq + pow(coeff[num_str_har - 1] - str_coeff, 2); for (j = 0; j <= num_str_har - 1; j++) save_coeff_err[j] = save_coeff_err[j] + pow(coeff[j] - save_coeff[j], 2); } *sl_rms = sqrt(sum_sq) * factorial; for (j = 0; j <= num_str_har - 1; j++) save_coeff_err[j] = sqrt(save_coeff_err[j]); /* Log the calculation */ blwire_log_bl_vs_x_fit(num_x0_pos, x0, bl_ave, bl_rms, num_str_har - 1, save_coeff, save_coeff_err); blwire_log_calc_integ_str(num_str_har, num_x0_pos, x0, bl_ave, bl_rms, *sl_ave, *sl_rms); /* Check */ if (num_str_har == 1) { //printf("\nDipole Strength Calculation\n"); //printf("BL = %f +- %f Tm\n", *sl_ave, *sl_rms); //printf("check:\n"); //printf("num_x0_pos = %i, x0[0] = %f m\n", num_x0_pos, x0[0]); //printf("bl_ave[0] = %f Tm, bl_rms[0] = %f Tm\n", bl_ave[0], bl_rms[0]); } if (num_str_har == 2 && num_x0_pos > 2) { printf("\nQuadrupole Strength Calculation\n"); printf("GL = %f +- %f T\n", *sl_ave, *sl_rms); printf("check:\n"); printf("straight line fit formulas:\n"); Sxy = 0.; Sx = 0.; Sy = 0.; Sxx = 0.; for (i = 0; i < num_x0_pos; i++) { Sxy = Sxy + x0[i] * bl_ave[i]; Sx = Sx + x0[i]; Sy = Sy + bl_ave[i]; Sxx = Sxx + x0[i] * x0[i]; } det = num_x0_pos * Sxx - Sx * Sx; slope = (1. / det) * (num_x0_pos * Sxy - Sx * Sy); inter = (1. / det) * (Sxx * Sy - Sx * Sxy); sig_sq = 0.; for (i = 0; i < num_x0_pos; i++) sig_sq = sig_sq + pow(bl_ave[i] - inter - slope * x0[i], 2) / (num_x0_pos - 2); sig_slope = sqrt(num_x0_pos * sig_sq / det); gl_ave = slope * factorial; gl_rms = sig_slope * factorial; printf("slope = %f, inter = %f, sig_slope = %f, est_sig = %f\n", slope, inter, sig_slope, sqrt(sig_sq)); printf("GL = %f +- %f T\n", gl_ave, gl_rms); blwire_log_check_quad_str(slope, inter, sig_slope, sig_sq, gl_ave, gl_rms); } /* Done */ return; } /* ************************************************************** */ /* * blwire_dat_bl_vs_x * This function writes the results of a magnet strength measurement * to the data file. * * Input: * dx, distance the wire was moved (m) * num_turns_wire, number of turns in the wire * num_meas_ave, number of measurements for averaging * x0, position BL is measured at (m) * imag_ave, magnet current (A) * imag_rms, rms variation of Imag measurements (A) * bl_ave, integrated strength (Tm), average * bl_rms, integrated strength (Tm), rms variation * * Zachary Wolf * 11/24/99 */ void blwire_dat_bl_vs_x(double dx, int num_turns_wire, int num_meas_ave, double x0, double imag_ave, double imag_rms, double bl_ave, double bl_rms) { /* Declare variables */ FILE* file_ptr; static int call_num; /* Open the dat file */ file_ptr = fopen(dat_file, "a"); if (file_ptr == NULL) { printf("blwire_dat_bl_vs_x: Unable to open magnet strength dat file\n"); return; } /* Increment the number of calls */ call_num++; /* Write a header on the first call */ if (call_num == 1) { fprintf(file_ptr, "\n"); fprintf(file_ptr, " Integrated Field Strength vs X\n"); fprintf(file_ptr, "\n"); fprintf(file_ptr, "Distance the wire was moved = %9.6f m\n", dx); fprintf(file_ptr, "Number of turns in the wire = %i\n", num_turns_wire); fprintf(file_ptr, "Number of measurements for averaging = %i\n", num_meas_ave); fprintf(file_ptr, "\n"); fprintf(file_ptr, " X0 Imag sigImag BL sigBL \n"); fprintf(file_ptr, " (m) (A) (A) (Tm) (Tm) \n"); fprintf(file_ptr, " ---------- --------+-------- --------+-------- \n"); } /* Write the data */ fprintf(file_ptr, " %10.6f %8.3f %8.3f %8.5f %8.5f\n", x0, imag_ave, imag_rms, bl_ave, bl_rms); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * blwire_plt_bl_vs_x * This function writes the results of a magnet strength measurement * to the plot file. * * Input: * x0, position BL is measured at (m) * imag_ave, magnet current (A) * imag_rms, rms variation of Imag measurements (A) * bl_ave, integrated strength (Tm), average * bl_rms, integrated strength (Tm), rms variation * * Zachary Wolf * 11/24/99 */ void blwire_plt_bl_vs_x(double x0, double imag_ave, double imag_rms, double bl_ave, double bl_rms) { /* Declare variables */ FILE* file_ptr; static int call_num; /* Open the dat file */ file_ptr = fopen(plt_file, "a"); if (file_ptr == NULL) { printf("blwire_plt_bl_ave_vs_x: Unable to open magnet strength plt file\n"); return; } /* Increment the number of calls */ call_num++; /* Write a header on the first call */ if (call_num == 1) { fprintf(file_ptr, ";x imag simag bl sbl\n"); } /* Write the data */ fprintf(file_ptr, " %8.6f %8.5f %8.5f %8.8f %10.8f\n", x0, imag_ave, imag_rms, bl_ave, bl_rms); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * blwire_dat_integ_str_vs_imag * This function writes the results of a magnet strength measurement * to the data file. * * Input: * dx, distance the wire was moved (m) * num_turns_wire, number of turns in the wire * num_meas_ave, number of measurements for averaging * num_str_har, number of the harmonic the strength is measured for * imag_ave, magnet current (A) * imag_rms, rms variation of Imag measurements (A) * sl_ave, integrated strength (Tm^2/m^n), average * sl_rms, integrated strength (Tm^2/m^n), rms variation * * Zachary Wolf * 11/24/99 */ void blwire_dat_integ_str_vs_imag(double dx, int num_turns_wire, int num_meas_ave, int num_str_har, double imag_ave, double imag_rms, double sl_ave, double sl_rms) { /* Declare variables */ FILE* file_ptr; static int call_num; double tf_ave, tf_rms; /* Check input parameters */ if (num_str_har < 1 || num_str_har > 4) { printf("blwire_dat_str_vs_imag: unknown num_str_har"); return; } /* Open the dat file */ file_ptr = fopen(dat_file, "a"); if (file_ptr == NULL) { printf("blwire_dat_str_vs_imag: Unable to open magnet strength dat file\n"); return; } /* Increment the number of calls */ call_num++; /* Write a header on the first call */ if (call_num == 1 && num_str_har == 1) { fprintf(file_ptr, "\n"); fprintf(file_ptr, "\n"); fprintf(file_ptr, " Integrated Field Strength\n"); fprintf(file_ptr, "\n"); fprintf(file_ptr, "Distance the wire was moved = %f m\n", dx); fprintf(file_ptr, "Number of turns in the wire = %i\n", num_turns_wire); fprintf(file_ptr, "Number of measurements for averaging = %i\n", num_meas_ave); fprintf(file_ptr, "\n"); fprintf(file_ptr, " Imag sigImag BL sigBL BL/I sigBL/I \n"); fprintf(file_ptr, " (A) (A) (Tm) (Tm) (Tm/A) (Tm/A) \n"); fprintf(file_ptr, "---------+--------- ----------+---------- ----------+---------- \n"); } if (call_num == 1 && num_str_har == 2) { fprintf(file_ptr, "\n"); fprintf(file_ptr, "\n"); fprintf(file_ptr, " Integrated Gradient\n"); fprintf(file_ptr, "\n"); fprintf(file_ptr, "Distance the wire was moved = %f m\n", dx); fprintf(file_ptr, "Number of turns in the wire = %i\n", num_turns_wire); fprintf(file_ptr, "Number of measurements for averaging = %i\n", num_meas_ave); fprintf(file_ptr, "\n"); fprintf(file_ptr, " Imag sigImag GL sigGL GL/I sigGL/I \n"); fprintf(file_ptr, " (A) (A) (T) (T) (T/A) (T/A) \n"); fprintf(file_ptr, "---------+--------- ----------+---------- ----------+---------- \n"); } if (call_num == 1 && num_str_har == 3) { fprintf(file_ptr, "\n"); fprintf(file_ptr, "\n"); fprintf(file_ptr, " Integrated Sextupole Strength\n"); fprintf(file_ptr, "\n"); fprintf(file_ptr, "Distance the wire was moved = %f m\n", dx); fprintf(file_ptr, "Number of turns in the wire = %i\n", num_turns_wire); fprintf(file_ptr, "Number of measurements for averaging = %i\n", num_meas_ave); fprintf(file_ptr, "\n"); fprintf(file_ptr, " Imag sigImag SL sigSL SL/I sigSL/I \n"); fprintf(file_ptr, " (A) (A) (T/m) (T/m) (T/m/A) (T/m/A) \n"); fprintf(file_ptr, "---------+--------- ----------+---------- ----------+---------- \n"); } if (call_num == 1 && num_str_har == 4) { fprintf(file_ptr, "\n"); fprintf(file_ptr, "\n"); fprintf(file_ptr, " Integrated Octupole Strength\n"); fprintf(file_ptr, "\n"); fprintf(file_ptr, "Distance the wire was moved = %f m\n", dx); fprintf(file_ptr, "Number of turns in the wire = %i\n", num_turns_wire); fprintf(file_ptr, "Number of measurements for averaging = %i\n", num_meas_ave); fprintf(file_ptr, "\n"); fprintf(file_ptr, " Imag sigImag OL sigOL OL/I sigOL/I \n"); fprintf(file_ptr, " (A) (A) (T/m^2) (T/m^2) (T/m^2/A) \n"); fprintf(file_ptr, "---------+--------- ----------+---------- ----------+---------- \n"); } /* Compute the transfer function */ if (fabs(imag_ave) > .01) { tf_ave = sl_ave / imag_ave; tf_rms = fabs(sl_rms / imag_ave); } else { tf_ave = 0.; tf_rms = 0.; } /* Write the data */ fprintf(file_ptr, "%9.3f %9.3f %10.6f %10.6f %10.7f %10.7f\n", imag_ave, imag_rms, sl_ave, sl_rms, tf_ave, tf_rms); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * blwire_plt_integ_str_vs_imag * This function writes the results of a magnet strength measurement * to the plot file. * * Input: * num_str_har, number of the harmonic the strength is measured for * imag_ave, magnet current (A) * imag_rms, rms variation of Imag measurements (A) * sl_ave, integrated strength (Tm^2/m^n), average * sl_rms, integrated strength (Tm^2/m^n), rms variation * * Zachary Wolf * 11/24/99 */ void blwire_plt_integ_str_vs_imag(int num_str_har, double imag_ave, double imag_rms, double sl_ave, double sl_rms) { /* Declare variables */ FILE* file_ptr; static int call_num; double tf_ave, tf_rms; /* Check input parameters */ if (num_str_har < 1 || num_str_har > 4) { printf("blwire_plt_str_vs_imag: unknown num_str_har"); return; } /* Open the plt file */ file_ptr = fopen(plt_file, "a"); if (file_ptr == NULL) { printf("blwire_plt_str_vs_imag: Unable to open magnet strength plt file\n"); return; } /* Increment the number of calls */ call_num++; /* Write a header on the first call */ if (call_num == 1) { fprintf(file_ptr, ";Imag, sImag, SL, sSL, TF, sTF\n"); } /* Compute the transfer function */ if (fabs(imag_ave) > .01) { tf_ave = sl_ave / imag_ave; tf_rms = fabs(sl_rms / imag_ave); } else { tf_ave = 0.; tf_rms = 0.; } /* Write the data */ fprintf(file_ptr, "%9.3f %9.3f %10.6f %10.6f %10.7f %10.7f\n", imag_ave, imag_rms, sl_ave, sl_rms, tf_ave, tf_rms); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * blwire_calc_mag_center * This function calculates the magnetic center position given * BL vs X measurements. The center is the point where BL has the * specified value. * * Input: * num_main_har, number of the main magnet harmonic, dipole = 1, quad = 2, ... * num_x0_pos, number of x positions BL was measured at * x0[0 to num_x0_pos - 1], x0 positions (m) * bl_ave[0 to num_x0_pos - 1], measured integrated field strengths at the x0 positions (Tm) * bl_rms[0 to num_x0_pos - 1], estimated error on the BL measurements (Tm) * bl_center, integrated field strength which defines the magnetic center (Tm) * * Output: * poly_fit_coeff[0 to num_main_har - 1], coefficients of a polynomial fit to bl vs x * poly_fit_coeff_err[0 to num_main_har - 1], estimated errors on the coefficients of a polynomial fit to bl vs x * x_center, calculated magnetic center position (m) * x_center_err, estimated error on x_center (m) * * Zachary Wolf * 4/6/00 */ void blwire_calc_mag_center(int num_main_har, int num_x0_pos, double x0[], double bl_ave[], double bl_rms[], double bl_center, double poly_fit_coeff[], double poly_fit_coeff_err[], double* x_center, double* x_center_err) { /* Declare variables */ int err; double bl_fit[200]; double coeff[20]; double mean_sq_err; int i, j; double sum_sq_0, sum_sq_1; double bl_adj[200]; double inter, inter_rms; double slope, slope_rms; double Sxy, Sx, Sy, Sxx, det; double sig_sq, sig_slope, sig_inter; double x_center_check, x_center_err_check; /* Check parameters */ if (num_main_har < 1 || num_main_har > 2) { blwire_error("blwire_calc_mag_center: improper num_main_har, only works for n = 1 or 2 at present"); return; } if (num_x0_pos < 3 || num_x0_pos > BLWIRE_MAX_NUM_X0_POS) { blwire_error("blwire_calc_mag_center: improper num_x0_pos"); return; } /* Perform a linear fit to the BL(x) measurements */ err = PolyFit(x0, bl_ave, num_x0_pos, 1, bl_fit, coeff, &mean_sq_err); if (err != 0) { blwire_error("blwire_calc_mag_center: error in polynomial fit"); return; } inter = coeff[0]; slope = coeff[1]; /* Estimate the error */ /* sig_c^2 = Sum_y [(dc/dy)^2 * sig_y^2] = Sum_y [dc^2] for dy = sig_y */ sum_sq_0 = 0.; sum_sq_1 = 0.; for (i = 0; i < num_x0_pos; i++) { for (j = 0; j < num_x0_pos; j++) bl_adj[j] = bl_ave[j]; bl_adj[i] = bl_ave[i] + bl_rms[i]; err = PolyFit(x0, bl_adj, num_x0_pos, 1, bl_fit, coeff, &mean_sq_err); if (err != 0) { blwire_error("blwire_calc_mag_center: error in polynomial fit"); return; } sum_sq_0 = sum_sq_0 + pow(coeff[0] - inter, 2); sum_sq_1 = sum_sq_1 + pow(coeff[1] - slope, 2); } inter_rms = sqrt(sum_sq_0); slope_rms = sqrt(sum_sq_1); /* Calculate the center and the error on the center */ /* BL(x) = inter + slope * x */ /* BL(x_center) = BL_center, ie. BL_center = inter + slope * x_center */ /* x_center = (BL_center - inter) / slope */ /* x_center_err^2 = x_center^2 * [(inter_rms^2 / (BL_center - inter)^2) + (slope_rms^2 / slope^2)] */ if (fabs(slope) > 0 && fabs(bl_center - inter) > 0) { *x_center = (bl_center - inter) / slope; *x_center_err = sqrt(pow(*x_center, 2) * (pow(inter_rms/(bl_center - inter), 2) + pow(slope_rms/slope, 2))); } else { *x_center = 0; *x_center_err = 0; } /* Return the fit parameters */ poly_fit_coeff[0] = inter; poly_fit_coeff[1] = slope; poly_fit_coeff_err[0] = inter_rms; poly_fit_coeff_err[1] = slope_rms; /* Message */ printf("\nMagnetic Center Calculation\n"); printf("Xcenter = %f +- %f m\n", *x_center, *x_center_err); /* Log the result */ blwire_log_bl_vs_x_fit(num_x0_pos, x0, bl_ave, bl_rms, 1, poly_fit_coeff, poly_fit_coeff_err); blwire_log_mag_center(bl_center, inter, inter_rms, slope, slope_rms, *x_center, *x_center_err); /* Check */ /* Fit a line to the bl_ave vs x data, Bevington p. 104 */ /* x = x0, y = bl_ave */ Sxy = 0.; Sx = 0.; Sy = 0.; Sxx = 0.; for (i = 0; i < num_x0_pos; i++) { Sxy = Sxy + x0[i] * bl_ave[i]; Sx = Sx + x0[i]; Sy = Sy + bl_ave[i]; Sxx = Sxx + x0[i] * x0[i]; } det = num_x0_pos * Sxx - Sx * Sx; slope = (1. / det) * (num_x0_pos * Sxy - Sx * Sy); inter = (1. / det) * (Sxx * Sy - Sx * Sxy); if (slope == 0.) { blwire_error("blwire_calc_mag_center: The slope is zero. The center is ill defined."); return; } x_center_check = (bl_center - inter) / slope; /* Estimate the error on x_center, Bevington p. 114 */ sig_sq = 0.; for (i = 0; i < num_x0_pos; i++) sig_sq = sig_sq + pow(bl_ave[i] - inter - slope * x0[i], 2) / (num_x0_pos - 2); sig_inter = sqrt(sig_sq * Sxx / det); sig_slope = sqrt(num_x0_pos * sig_sq / det); x_center_err_check = sqrt((pow(sig_inter, 2) / pow(slope, 2)) + (pow(bl_center - inter, 2) * pow(sig_slope, 2) / pow(slope, 4))); /* Message */ //printf("check:\n"); //printf("straight line fit formulas:\n"); //printf("slope = %f +- %f Tm/m, inter = %f +- %f Tm\n", slope, sig_slope, inter, sig_inter); //printf("X = %f +- %f m\n", x_center_check, x_center_err_check); /* Log the result of the check */ blwire_log_mag_center(bl_center, inter, sig_inter, slope, sig_slope, x_center_check, x_center_err_check); /* Done */ return; } /* ************************************************************** */ /* * blwire_dat_mag_center * This function writes the results of a magnetic center measurement * to the data file. * * Input: * x_center, the position of the magnetic center (m) * x_center_err, the error on the magnetic center position (m) * * Zachary Wolf * 3/31/00 */ void blwire_dat_mag_center(double x_center, double x_center_err) { /* Declare variables */ FILE* file_ptr; /* Open the dat file */ file_ptr = fopen(dat_file, "a"); if (file_ptr == NULL) { printf("blwire_dat_mag_center: Unable to open magnet strength dat file\n"); return; } /* Write the data */ fprintf(file_ptr, "\nThe magnetic center is at\n"); fprintf(file_ptr, "X = %10.6f +- %10.6f m\n", x_center, x_center_err); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * blwire_dat_mag_center_check * This function writes the results of a magnet strength measurement * to the data file. This measurement is to check the magnetic center * measurement. * * Input: * x0, position BL is measured at (m) * imag_ave, magnet current (A) * imag_rms, rms variation of Imag measurements (A) * bl_ave, integrated strength (Tm), average * bl_rms, integrated strength (Tm), rms variation * bl_center, integrated strength (Tm) at the magnetic center at the measured current * inter, intercept in the linear fit (Tm) * inter_rms, estimated error on the intercept (Tm) * slope, slope in the linear fit (Tm/m) * slope_rms, estimated error on the slope (Tm/m) * * Zachary Wolf * 11/24/99 */ void blwire_dat_mag_center_check(double x0, double imag_ave, double imag_rms, double bl_ave, double bl_rms, double bl_center, double inter, double inter_rms, double slope, double slope_rms) { /* Declare variables */ FILE* file_ptr; /* Open the dat file */ file_ptr = fopen(dat_file, "a"); if (file_ptr == NULL) { printf("blwire_dat_mag_center_check: Unable to open magnet strength dat file\n"); return; } /* Write a header */ fprintf(file_ptr, "\n"); fprintf(file_ptr, " Integrated Strength At The Magnetic Center\n"); fprintf(file_ptr, "\n"); fprintf(file_ptr, " X0 Imag sigImag BL sigBL \n"); fprintf(file_ptr, " (m) (A) (A) (Tm) (Tm) \n"); fprintf(file_ptr, " ---------- --------+-------- --------+-------- \n"); /* Write the data */ fprintf(file_ptr, " %10.6f %8.3f %8.3f %8.5f %8.5f\n", x0, imag_ave, imag_rms, bl_ave, bl_rms); /* Describe how close we are to the center */ fprintf(file_ptr, "\nBL_center = %8.5f Tm\n", bl_center); fprintf(file_ptr, "(BL_meas - BL_center)/sigBL = %8.4f\n", (bl_ave - bl_center) / bl_rms); //fprintf(file_ptr, "Fit: BL = (%10.5f +- %10.5f Tm) + (%10.5f +- %10.5f Tm/m) * x\n", inter, inter_rms, slope, slope_rms); //if (slope != 0.) fprintf(file_ptr, "sigBL/Gradient = %10.6f m\n", bl_rms / slope); //if (slope != 0.) fprintf(file_ptr, "(BL - BL_center)/Gradient = %10.6f m\n", (bl_ave - bl_center) / slope); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* INTERNAL FUNCTIONS */ /* ************************************************************** */ /* * blwire_error * This function handles errors for the IMAG module. * * Input: * message, string to display in standard I/O * * Zachary Wolf * 10/11/98 */ void blwire_error(char* message) { /* Declare variables */ char buf[80]; /* Notify the operator of the error */ printf("\nERROR: %s\n", message); Beep(); Delay(.5); Beep(); /* Terminate the program if the operator desires */ printf("Press ENTER to continue.\nPress any key then ENTER to terminate program.\n"); fgets(buf, 80, stdin); if (buf[0] == '\n') return; else exit(0); } /* ************************************************************** */ /* * blwire_check_param * This function checks that all required parameters have been assigned * appropriate values. * * Output: * err, 0 = no error, non-zero = error * * Zachary Wolf * 8/11/98 */ int blwire_check_param() { /* Declare variables */ int i; /* log_file */ if (CompareStrings(log_file, 0, "", 0, 0) == 0) { blwire_error("blwire_check_param: Log file not defined."); return -1; } /* dat_file */ if (CompareStrings(dat_file, 0, "", 0, 0) == 0) { blwire_error("blwire_check_param: Magnet strength dat file not defined."); return -1; } /* plt_file */ if (CompareStrings(plt_file, 0, "", 0, 0) == 0) { blwire_error("blwire_check_param: Magnet strength plt file not defined."); return -1; } /* num_turns_wire */ if (blwire_param.num_turns_wire < 1 || blwire_param.num_turns_wire > 100) { blwire_error("blwire_check_param: num_turns_wire is invalid"); return -1; } /* show_ui */ /* OK, enum */ /* If we made it this far, all parameters have values */ return 0; } /* ************************************************************** */ /* * blwire_log_measurement * This function logs a measurement to the log file. * * Input: * meas, a description of the measurement for the log file * * Zachary Wolf * 7/8/99 */ void blwire_log_measurement(char* meas) { /* Declare variables */ FILE* file_ptr; /* Open the log file */ file_ptr = fopen(log_file, "a"); if (file_ptr == NULL) { printf("blwire_log_measurement: Unable to open log file\n"); return; } /* Write to the log file */ fprintf(file_ptr, "%s Magnetic Field Measurement\n", TimeStr()); fprintf(file_ptr, " %s\n", meas); /* Close the log file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * blwire_log_bl_ave * This function logs the result of a stretched wire BL measurement. * * Input: * x0, center of the wire motion (m) * dx, distance the wire moves (m) * Nw, number of turns in the wire * vt_ave, average of several integrated voltage measurements (Vs) * vt_rms, rms variation of several integrated voltage measurements (Vs) * bl_ave, average of integrated field strength measurements (Tm) * bl_rms, rms variation of integrated field strength measurements (Tm) * * Zachary Wolf * 11/24/99 */ void blwire_log_bl_ave(double x0, double dx, double Nw, double vt_ave, double vt_rms, double bl_ave, double bl_rms) { /* Declare variables */ FILE* file_ptr; /* Open the log file */ file_ptr = fopen(log_file, "a"); if (file_ptr == NULL) { printf("blwire_log_blwire_ave: Unable to open log file\n"); return; } /* Write the measured values to the log file */ fprintf(file_ptr, "%s Integrated Field Strength, Average and RMS of Measurements\n", TimeStr()); fprintf(file_ptr, " X0 = %10.7f m, dx = %10.7f m, Nturns = %6.1f\n", x0, dx, Nw); fprintf(file_ptr, " VT = %14.9f +- %14.9f Vs\n", vt_ave, vt_rms); fprintf(file_ptr, " BL = %12.8f +- %12.8f Tm\n", bl_ave, bl_rms); /* Close the log file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * blwire_log_integ_str * This function logs the result of a magnet strength measurement. * * Input: * num_str_har, number of the field harmonic the strength is being measured for * sl_ave, integrated strength (Tm^2/m^n), average * sl_rms, integrated strength (Tm^2/m^n), rms variation * * Zachary Wolf * 12/3/99 */ void blwire_log_integ_str(int num_str_har, double sl_ave, double sl_rms) { /* Declare variables */ FILE* file_ptr; int i; /* Open the log file */ file_ptr = fopen(log_file, "a"); if (file_ptr == NULL) { printf("blwire_log_integ_str: Unable to open log file\n"); return; } /* Write the measured values to the log file */ fprintf(file_ptr, "%s Magnet Strength Measurement\n", TimeStr()); fprintf(file_ptr, " Harmonic Number = %i\n", num_str_har); fprintf(file_ptr, " SL = %12.7f +- %12.7f Tm^2/m^n\n", sl_ave, sl_rms); /* Close the log file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * blwire_log_calc_integ_str * This function logs the result of a magnet strength calculation. * * Input: * num_str_har, the number of the main field harmonic (1 = dipole, 2 = quad, ...) * num_x0_pos, the number of positions to measure BL at * x0[0 to num_x0_pos - 1], array of center of the wire motion positions (m) * bl_ave[0 to num_x0_pos - 1], average of integrated field strength measurements at each position (Tm) * bl_rms[0 to num_x0_pos - 1], rms variation of integrated field strength measurements at each position (Tm) * sl_ave, integrated strength (Tm/m^(n-1)) * sl_rms, error estimate on SL (Tm/m^(n-1)) * * Zachary Wolf * 12/3/99 */ void blwire_log_calc_integ_str(int num_str_har, int num_x0_pos, double x0[], double bl_ave[], double bl_rms[], double sl_ave, double sl_rms) { /* Declare variables */ FILE* file_ptr; int i; /* Open the log file */ file_ptr = fopen(log_file, "a"); if (file_ptr == NULL) { printf("blwire_log_calc_integ_str: Unable to open log file\n"); return; } /* Write the data to the log file */ fprintf(file_ptr, "%s Magnet Strength Calculation\n", TimeStr()); fprintf(file_ptr, " Harmonic Number = %i\n", num_str_har); fprintf(file_ptr, " Number Of X0 Positions = %i\n", num_x0_pos); fprintf(file_ptr, " X0 BL sigBL \n"); fprintf(file_ptr, " (m) (Tm) (Tm) \n"); fprintf(file_ptr, " -------- --------+-------- \n"); for (i = 0; i < num_x0_pos; i++) fprintf(file_ptr, " %8.4f %8.5f %8.5f\n", x0[i], bl_ave[i], bl_rms[i]); fprintf(file_ptr, " SL = %12.7f +- %12.7f Tm^2/m^n\n", sl_ave, sl_rms); /* Close the log file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * blwire_log_check_quad_str * This function logs the result of a quadrupole strength calculation. * * Input: * slope, slope of the fitted BL vs X line (Tm/m) * inter, intercept of the fitted BL vs X line (Tm) * sig_slope, estimated error on the fitted slope (Tm/m) * sig_sq, square of the estimated error on the data points, calculated from the residuals (Tm^2) * gl_ave, integrated gradient (T) * gl_rms, estimated error on GL (T) * * Zachary Wolf * 12/17/99 */ void blwire_log_check_quad_str(double slope, double inter, double sig_slope, double sig_sq, double gl_ave, double gl_rms) { /* Declare variables */ FILE* file_ptr; int i; /* Open the log file */ file_ptr = fopen(log_file, "a"); if (file_ptr == NULL) { printf("blwire_log_check_quad_str: Unable to open log file\n"); return; } /* Write the data to the log file */ fprintf(file_ptr, "%s Quadrupole Strength Calculation Check\n", TimeStr()); fprintf(file_ptr, " Slope = %f Tm/m, Inter = %f Tm, Sig_slope = %f Tm/m, Est_sig = %f Tm\n", slope, inter, sig_slope, sqrt(sig_sq)); fprintf(file_ptr, " GL = %f +- %f T\n", gl_ave, gl_rms); /* Close the log file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * blwire_log_mag_center * This function writes the results of a magnetic center measurement * to the log file. * * Input: * bl_center, BL at the magnet center (Tm) * inter, intercept in BL vs X fit (Tm) * sig_inter, error on inter (Tm) * slope, slope of BL vs X fit (Tm/m) * sig_slope, error on slope (Tm/m) * x_center, the position of the magnetic center (m) * x_center_err, the error on the magnetic center position (m) * * Zachary Wolf * 3/31/00 */ void blwire_log_mag_center(double bl_center, double inter, double sig_inter, double slope, double sig_slope, double x_center, double x_center_err) { /* Declare variables */ FILE* file_ptr; int i; /* Open the dat file */ file_ptr = fopen(log_file, "a"); if (file_ptr == NULL) { printf("blwire_log_mag_center: Unable to open log file\n"); return; } /* Write the data */ fprintf(file_ptr, "%s Magnetic center calculation:\n", TimeStr()); fprintf(file_ptr, " (The first calculation is from PolyFit, the second is the check.)\n"); fprintf(file_ptr, " BL_fit = (%10.6f +- %10.6f Tm) +\n", inter, sig_inter); fprintf(file_ptr, " (%12.5f +- %12.5f Tm/m) * X\n", slope, sig_slope); fprintf(file_ptr, " BL_center = %10.6f Tm\n", bl_center); fprintf(file_ptr, " X = %12.8f +- %12.8f m\n", x_center, x_center_err); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * blwire_log_bl_vs_x_fit * This function writes the results of a fit to bl vs x data * to the data file. * * Input: * num_x0_pos, number of x positions BL is measured at * x0[0 to num_x0_pos - 1], position BL is measured at (m) * bl_ave[0 to num_x0_pos - 1], integrated strength (Tm), average * bl_rms[0 to num_x0_pos - 1], integrated strength (Tm), rms variation * fit_order, order of the polynomial fit * fit_coeff[0 to fit_order], polynomial fit coefficients (Tm/m^n) * fit_coeff_err[0 to fit_order], estimated errors on the polynomial fit coefficients (Tm/m^n) * * Zachary Wolf * 11/27/00 */ void blwire_log_bl_vs_x_fit(int num_x0_pos, double x0[], double bl_ave[], double bl_rms[], int fit_order, double fit_coeff[], double fit_coeff_err[]) { /* Declare variables */ FILE* file_ptr; int i, j; double bl_fit; /* Open the dat file */ file_ptr = fopen(log_file, "a"); if (file_ptr == NULL) { printf("blwire_dat_bl_vs_x_fit: Unable to open log file\n"); return; } /* Write a header */ fprintf(file_ptr, "%s BL vs X Fit Coefficients:\n", TimeStr()); fprintf(file_ptr, " Cn sigCn \n"); fprintf(file_ptr, " n (Tm/m^n) \n"); fprintf(file_ptr, " ----- --------+-------- \n"); /* Write the data */ for (i = 0; i <= fit_order; i++) fprintf(file_ptr, " %3i %8.5f %8.5f\n", i, fit_coeff[i], fit_coeff_err[i]); /* Write a header */ fprintf(file_ptr, " Compute Fit Residuals:\n"); fprintf(file_ptr, " X0 BL sigBL BLfit BL-BLfit\n"); fprintf(file_ptr, " (m) (Tm) (Tm) (Tm) (Tm) \n"); fprintf(file_ptr, " ---------- --------+-------- -------- --------\n"); /* Write the data */ for (j = 0; j < num_x0_pos; j++) { bl_fit = 0.; for (i = 0; i <= fit_order; i++) bl_fit = bl_fit + fit_coeff[i] * pow(x0[j], i); fprintf(file_ptr, " %10.6f %8.5f %8.5f %8.5f %8.5f\n", x0[j], bl_ave[j], bl_rms[j], bl_fit, bl_ave[j] - bl_fit); } /* Close the log file */ fclose(file_ptr); /* Done */ return; }