#include /* ************************************************************** */ /* * Module VIBRATINGWIRE * This module contains functions to make vibrating wire * fiducialization measurements. * * Zachary Wolf * 10/6/05 */ /* ************************************************************** */ /* INCLUDES */ #include "repository.h" #include DELAY //adds most commonly used functions #include #include #include #include #include "param.h" #include "runparam.h" #include "vibwire.h" #include "vibwireparam.h" #include "vibwireui.h" #include "cam_movers_dec.h" #include "cam_movers_param.h" #include "wirpos.h" #include "wirposparam.h" #include "wirposui.h" #include "imag.h" #include "imagparam.h" #include "imagui.h" #include "vibrating wire ui.h" /* ************************************************************** */ /* PRIVATE GLOBAL VARIABLES */ static char log_file[100]; static char cam_log_file[100]; static char dat_file[100]; static char plt_file[100]; static char wire_plt_file[100]; static char msg[100]; static double harm_freq2; static double harm_freq4; /* ************************************************************** */ /* PRIVATE FUNCTION DECLARATIONS */ void vibratingwire_init(struct move_param *mv_param, struct com_param *cm_param); void vibratingwire_meas(struct move_param *mv_param, struct com_param *cm_param); void vibratingwire_move_mag_to_wire(char move_dir[], int num_pos, double step_size, struct move_param *mv_param, struct com_param *cm_param); void vibratingwire_move_mag(int index, double pos, struct move_param *mv_param, struct com_param *cm_param, int mode); void vibratingwire_dat_meas_header(char move_dir[], double imag, double sigimag,double ampl, double freq); void vibratingwire_dat_meas(int meas_num, double mag_pos, double xdet_vxrms, double xdet_vyrms, double ydet_vxrms, double ydet_vyrms); void vibratingwire_calc_dat_center_pos(char move_dir[], double pos, double rms, double xdet_vyrms, double ydet_vyrms, double vyrms_x_slope, double *offset); void vibratingwire_write_dat_center_pos(char move_dir[], double pos, double rms, double xdet_vyrms, double ydet_vyrms, double vyrms_x_slope, double *offset); void vibratingwire_dat_wire_pos(int det_num, double pos); void vibratingwire_plt_wire_header(void); void vibratingwire_plt_wire_pos(int det_num, double pos); void vibratingwire_plt_meas_header(void); void vibratingwire_plt_meas(char move_dir[], int meas_num, double mag_pos, double imag, double ampl, double freq, double xdet_vxrms, double xdet_vyrms, double ydet_vxrms, double ydet_vyrms); void vibratingwire_exit(void); void vibratingwire_error(char* message); int vibratingwire_adjust_step(double dx,double dy,double dpitch,double dyaw,double *x_step,double *y_step,double *pitch_step,double *yaw_step); void vibratingwire_write_to_log(char* msg) ; void vibratingwire_dat_mag_move_summary (double *x_data, double *y_data, double *pitch_data, double *yaw_data, int num_data_points); void vibratingwire_plt_mag_move_summary (double *x_data, double *y_data, double *pitch_data, double *yaw_data, int num_data_points); void vibratingwire_dat_mag_move_converge_check (char* msg, double dx, double dy, double dpitch, double dyaw); /* ************************************************************** */ /* PUBLIC FUNCTIONS */ /* ************************************************************* */ int main(int argc, char *argv[]) { struct move_param mv_param; struct com_param cm_param; /* Perform all initialization for the program */ vibratingwire_init(&mv_param, &cm_param); /* Perform the measurements */ vibratingwire_meas(&mv_param, &cm_param); /*Notify User As Requested*/ if (MAIL_SEND_NOTIFICATION == 1) { static char cmd[80]; Fmt(cmd, "%s 0) { printf("Warming up the Magnet for %f minutes",VIBRATINGWIRE_WARMUP_TIME/60.0); imag_ramp(VIBRATINGWIRE_WARMUP_CURRENT); delay(VIBRATINGWIRE_WARMUP_TIME); } // Loop over the test currents for (i = 0; i < VIBRATINGWIRE_NUM_TEST_CURRENTS; i++) { /* Standardize the magnet */ if (VIBRATINGWIRE_NUM_STAND_CYCLES > 0) { printf("\nStandardizing the magnet...\n"); imag_standardize(VIBRATINGWIRE_STAND_MAX, VIBRATINGWIRE_STAND_MIN, VIBRATINGWIRE_NUM_STAND_CYCLES); } /* Message */ printf("\nBeginning the vibrating wire measurements...\n"); /* Turn on wire vibration again */ vibwire_output_on(); //Measure and record the initial coordinates cam_move_get_coordinates(mv_param, cm_param); cam_move_log_motion_data("Initial coordinates", mv_param); x_init=mv_param->cam_coord[X_CIND]; y_init=mv_param->cam_coord[Y_CIND]; pitch_init=mv_param->cam_coord[PITCH_CIND]; yaw_init=mv_param->cam_coord[YAW_CIND]; /* Add initial cam positions to data archive */ x_data[0]=mv_param->cam_coord[X_CIND]; y_data[0]=mv_param->cam_coord[Y_CIND]; pitch_data[0]=mv_param->cam_coord[PITCH_CIND]; yaw_data[0]=mv_param->cam_coord[YAW_CIND]; /* Ramp the magnet */ imag_ramp(VIBRATINGWIRE_TEST_CURRENTS[i]); for (j = 1; j <= 30; j++) imagui_update(VIBRATINGWIRE_TEST_CURRENTS[i]); /* Skip cam movement if only doing Flip Test */ if(VIBRATINGWIRE_FLIP_TEST == 1) { printf("Flip Test, Skipping Magnet Center"); } else { /* Initialize the step size */ x_step=VIBRATINGWIRE_X_STEP; y_step=VIBRATINGWIRE_Y_STEP; pitch_step=VIBRATINGWIRE_PITCH_STEP; yaw_step=VIBRATINGWIRE_YAW_STEP; /* VIBRATINGWIRE_FLIP_TEST skips the magnet cetering which is not needed for a detector flip test */ if(VIBRATINGWIRE_FLIP_TEST == 1) done=1; else done = 0; k=0; /* Cycle until maximum number of cycles is reached or complete */ while(done!=1) { k++; /* Save the cam coordinates (poistions) before the move */ x_pos=mv_param->cam_coord[X_CIND]; y_pos=mv_param->cam_coord[Y_CIND]; pitch_pos=mv_param->cam_coord[PITCH_CIND]; yaw_pos=mv_param->cam_coord[YAW_CIND]; /* Move the magnet in pitch until it is centered on the wire */ vibratingwire_move_mag_to_wire("pitch", VIBRATINGWIRE_NUM_PITCH_POS, pitch_step, mv_param, cm_param); /* Move the magnet in yaw until it is centered on the wire */ vibratingwire_move_mag_to_wire("yaw", VIBRATINGWIRE_NUM_YAW_POS, yaw_step, mv_param, cm_param); /* Move the magnet in x until it is centered on the wire */ vibratingwire_move_mag_to_wire("x", VIBRATINGWIRE_NUM_X_POS, x_step, mv_param, cm_param); /* Move the magnet in y until it is centered on the wire */ vibratingwire_move_mag_to_wire("y", VIBRATINGWIRE_NUM_Y_POS, y_step, mv_param, cm_param); dx=fabs(x_pos - mv_param->cam_coord[X_CIND]); dy=fabs(y_pos - mv_param->cam_coord[Y_CIND]); dpitch=fabs(pitch_pos - mv_param->cam_coord[PITCH_CIND]); dyaw=fabs(yaw_pos - mv_param->cam_coord[YAW_CIND]); /* Add current cam positions to data archive */ x_data[k]= mv_param->cam_coord[X_CIND]; y_data[k]= mv_param->cam_coord[Y_CIND]; pitch_data[k]= mv_param->cam_coord[PITCH_CIND]; yaw_data[k]= mv_param->cam_coord[YAW_CIND]; /* Check data */ if((dx < VIBRATINGWIRE_X_CONV) && (dy < VIBRATINGWIRE_Y_CONV) && (dpitch < VIBRATINGWIRE_PITCH_CONV) && (dyaw < VIBRATINGWIRE_YAW_CONV)) { done = 1; } if(done==0) { if(k >= VIBRATINGWIRE_MAX_MOVE_CYCLES) { printf("Measurement failed to converge in %i possible cycles...\n", VIBRATINGWIRE_MAX_MOVE_CYCLES); Fmt(msg, "%scam_coord[X_CIND]-x_init)*1.e6); printf("%.2f microns in y direction\n",(mv_param->cam_coord[Y_CIND]-y_init)*1.e6); printf("%.3f mrads of pitch\n",(mv_param->cam_coord[PITCH_CIND]-pitch_init)*1.e3); printf("%.3f mrads of yaw.\n\n",(mv_param->cam_coord[YAW_CIND]-yaw_init)*1.e3); vibratingwire_dat_mag_move_summary(x_data, y_data, pitch_data, yaw_data, k); vibratingwire_plt_mag_move_summary(x_data, y_data, pitch_data, yaw_data, k); Fmt(msg, "%snum_cams;i++) coord_init[i]=mv_param->cam_coord[i]; /* Send the magnet to the initial position */ /* If it is a yaw move half a step size past magnet to the initial position */ if (strcmp(move_dir, "yaw") == 0) { vibratingwire_move_mag(coord_index, - ((num_pos-1)/2)*1.1*step_size, mv_param, cm_param,1); Fmt(msg, "%s< %s yaw 1st coordinates", move_dir); cam_move_log_motion_data(msg, mv_param); vibratingwire_move_mag(coord_index, 0.3*step_size, mv_param, cm_param,1); Fmt(msg, "%s< %s start coordinates", move_dir); cam_move_log_motion_data(msg, mv_param); } else { vibratingwire_move_mag(coord_index, - ((num_pos-1)/2)*step_size, mv_param, cm_param,1); Fmt(msg, "%s< %s start coordinates", move_dir); cam_move_log_motion_data(msg, mv_param); } /* Set the resonant frequency if required */ if (res_freq[har] == 0. || current_har != har) { printf("\nFind the resonant frequency...\n"); /* Set the signal generator amplitude, depending on which harmonic is used */ vibwire_set_ampl(signal_ampl); //Clear errors, which might show up when changing the amplitude vibwire_xdet_clear_errors(); vibwire_ydet_clear_errors(); /* Set the x and y detectors to low sensitivity, just in case */ vibwire_xdet_set_low_sensitivity(); vibwire_ydet_set_low_sensitivity(); vibwire_ydet_lower_sensitivity(); /* Initialize the user interface */ vibwireui_clear_vx_graph(); vibwireui_clear_vy_graph(); vibwireui_set_har_num(har); if(current_har == 0) //Make sure to scan a wide range if it is the first scan coarse_num_points = VIBWIRE_EXTRA_COARSE_NUM_FREQ; else coarse_num_points = VIBWIRE_COARSE_NUM_FREQ; /* Set the frequency for magnet centering, use the appropriate harmonic */ vibwire_find_res_freq_coarse(wire_vib_det, har, &res_freq[har], coarse_num_points); /* Find the fine resonance frequency */ vibwire_find_res_freq_fine(wire_vib_det, res_freq[har], &res_freq[har]); } /* Done setting resonant frequency */ current_har=har; vibwire_set_freq(res_freq[har]); /* Get the signal generator frequency */ vibwire_get_freq(&res_freq[har]); printf("Resonant frequency is %10.7f \n", res_freq[har]); /* Write a header to the data file */ vibratingwire_dat_meas_header(move_dir, imag, sigimag, signal_ampl, res_freq[har]); /* Prepare the user interface */ vibratingwireui_clear_plot(); Fmt(msg, "%scam_coord[coord_index]; /* Measure the wire vibration amplitude */ vibwire_get_xdet_vxrms(&xdet_vxrms); vibwire_get_xdet_vyrms(&xdet_vyrms); vibwire_get_ydet_vxrms(&ydet_vxrms); vibwire_get_ydet_vyrms(&ydet_vyrms); /* Write the values to the data file */ vibratingwire_dat_meas(i+1, pos[i], xdet_vxrms, xdet_vyrms, ydet_vxrms, ydet_vyrms); /* Write the values to the plot file */ vibratingwire_plt_meas(move_dir, i+1, pos[i], imag, signal_ampl, res_freq[har], xdet_vxrms, xdet_vyrms, ydet_vxrms, ydet_vyrms); /* Plot the measurements on the screen */ vibratingwireui_update_meas(pos[i], xdet_vxrms, xdet_vyrms, ydet_vxrms, ydet_vyrms); /* Save the data for fitting */ if ((strcmp(move_dir, "x") == 0) || (strcmp(move_dir, "yaw") == 0)) vy_data[i] = xdet_vyrms; else vy_data[i] = ydet_vyrms; } /* Is Vy = 0 in the range of the measurements, 0 is no, 1 is yes. If no then try a remeasure */ inrange = 0; if ((vy_data[0] <= 0. && vy_data[num_pos-1] > 0.) || (vy_data[0] >= 0. && vy_data[num_pos-1] < 0.)) { inrange = 1; printf("Zero for Vy data is in range"); } else if(inrange == 0 && num_remeas < 1) { printf("Vy = 0 not in scan range, adjust range and try scan again"); num_remeas++; /* If Vy of first point is greater than last point Vy move scan range to start at num_pos-2 */ if(fabs(vy_data[0]) > fabs(vy_data[num_pos-1]) ) { for(i=0;inum_cams;i++) mv_param->cam_coord[i]=pos[num_pos-2]; printf("\nMoving the magnet to start scan at previous scans second to last point...\n"); } /* If Vy of first point is less than than last point Vy move scan range to start at first minus the last pos[0] - pos[num_pos-1] */ else { for(i=0;inum_cams;i++) mv_param->cam_coord[i]= pos[0] - pos[num_pos-1]; printf("\nMoving the magnet to scan over range that will end at the last scans starting range...\n"); } cam_move_go(cm_param, mv_param, 1); goto remeasure; } else if (inrange == 0) { /* Terminate the program if the operator desires */ if (MAIL_SEND_NOTIFICATION == 1) { static char cmd[80]; Fmt(cmd, "%s 0.) || (vy_data[i] >= 0. && vy_data[i+1] < 0.)) { index_zero = i; break; } } /* If v = 0 is not found, use the center measurement point for the center of the fit, extrapolate to make a best estimate */ if (index_zero == 0) { index_zero = (num_pos - 1) / 2; } /* Choose samples for fitting */ num_fit_each_side = (num_pos-1)/2; if (index_zero - num_fit_each_side < 0) index_zero = num_fit_each_side; if (index_zero + num_fit_each_side > num_pos - 1) index_zero = num_pos - 1 - num_fit_each_side; num_fit = 2 * num_fit_each_side + 1; for (i = 0; i < num_fit; i++) { fit_data[i] = vy_data[index_zero - num_fit_each_side + i]; fit_pos[i] = pos[index_zero - num_fit_each_side + i]; } /* Fit to find the magnet center position */ LinFit(fit_pos, fit_data, num_fit, z, &slope, &intercept, &mse); zero_pos = -intercept/slope; LinFit(fit_data, fit_pos, num_fit, z, &slope_error, &intercept_error, &mse_error); zero_rms = sqrt(mse_error); /* Plot the fit results */ vibratingwireui_plot_center_fit(num_fit, fit_pos, fit_data, zero_pos); /* Message */ printf("\nResult:\n"); printf("Magnet %s when centered on the wire = %8.6g +/- %8.6g %s \n", move_dir, zero_pos, zero_rms, units); //Move the cams to the zero position. Fix any drift in other coordinates //Save initial the coordinates before moving coord_init[coord_index]=zero_pos; for(i=0;inum_cams;i++) mv_param->cam_coord[i]=coord_init[i]; printf("\nMoving the magnet so it is centered on the wire...\n"); cam_move_go(cm_param, mv_param, 1); //The cam movers might not perform perfectly, due to imprefect potentiometer calibration //Check if the result is too bad. If so, move again move_ok=1; if(fabs(coord_init[X_CIND]-mv_param->cam_coord[X_CIND]) > VIBRATINGWIRE_X_CONV/2) move_ok = 0; if(fabs(coord_init[Y_CIND]-mv_param->cam_coord[Y_CIND]) > VIBRATINGWIRE_Y_CONV/2) move_ok = 0; if(fabs(coord_init[PITCH_CIND]-mv_param->cam_coord[PITCH_CIND]) > VIBRATINGWIRE_PITCH_CONV/2) move_ok = 0; if(fabs(coord_init[YAW_CIND]-mv_param->cam_coord[YAW_CIND]) > VIBRATINGWIRE_YAW_CONV/2) move_ok = 0; for(i=0;inum_cams;i++) mv_param->cam_coord[i]=coord_init[i]; if(move_ok != 1) { printf("Cam mover movement error. Readjusting...\n"); cam_move_go(cm_param, mv_param, 1); } zero_ok=0; while(zero_ok != 1) { zero_ok=1; /* Measure the wire vibration amplitude at the final position check and correct*/ vibwire_get_xdet_vyrms(&xdet_vyrms); vibwire_get_ydet_vyrms(&ydet_vyrms); /* Calculate the offset from the desired zero postion*/ vibratingwire_calc_dat_center_pos(move_dir, zero_pos, zero_rms, xdet_vyrms, ydet_vyrms, slope, &wire_calc_offset); //The cam movers might not set the zero position corectly. // If the actual position if out of tolerence to the desired zero position then correct /* Check offset to zero postion and correct if out of tolerence. */ if (strcmp(move_dir, "x") == 0) { if(fabs(wire_calc_offset) > VIBRATINGWIRE_X_CONV/12) zero_ok = 0; } else if (strcmp(move_dir, "y") == 0) { if(fabs(wire_calc_offset) > VIBRATINGWIRE_Y_CONV/12) zero_ok = 0; } else if (strcmp(move_dir, "yaw") == 0) { if(fabs(wire_calc_offset) > VIBRATINGWIRE_YAW_CONV/2 ) zero_ok = 0; } else if (strcmp(move_dir, "pitch") == 0) { if(fabs(wire_calc_offset) > VIBRATINGWIRE_PITCH_CONV/2 ) zero_ok = 0; } else { vibratingwire_error("vibratingwire_dat_meas_header: Unrecognized move direction."); } if(zero_ok != 1) { printf("Zero position movement error, Readjusting stages....\n"); vibratingwire_write_to_log("Zero position movement error, Readjusting stages. \n"); // coord_init[coord_index] = zero_pos + wire_calc_offset; // for(i=0;inum_cams;i++) mv_param->cam_coord[i]=coord_init[i]; cam_move_go(cm_param, mv_param, 1); /* Calculate the offset from the desired zero postion*/ vibratingwire_calc_dat_center_pos(move_dir, zero_pos, zero_rms, xdet_vyrms, ydet_vyrms, slope, &wire_calc_offset); zero_ok = 1; } } /* Write the result to the data file */ vibratingwire_write_dat_center_pos(move_dir, zero_pos, zero_rms, xdet_vyrms, ydet_vyrms, slope, &wire_offset); return; } /* ************************************************************** */ /* * vibratingwire_move_mag * This function moves the magnet in the specified direction. * * Michael Levashov * 07/24/07 */ void vibratingwire_move_mag(int index, double pos, struct move_param *mv_param, struct com_param *cm_param, int mode) { int i; /* Move the magnet */ if(mode == 0) { for(i=0; inum_cams;i++) mv_param->cam_coord[i]=0; } else mv_param->cam_coord[index]+=pos; cam_move_go(cm_param, mv_param, mode); return; } /* ************************************************************** */ /* * vibratingwire_dat_meas_header * This function writes a header for a vibrating wire measurement * to the data file. * * Input: * move_dir, move direction "x", "y", "yaw", or "pitch" * imag, magnet current (A) * sigimag, std of magnet current (A) * ampl, signal generator amplitude (V_0p) * freq, signal generator frequency (Hz) * * Zachary Wolf * 10/6/05 */ void vibratingwire_dat_meas_header(char move_dir[], double imag, double sigimag, double ampl, double freq) { /* Declare variables */ FILE* file_ptr; char title[80]; char units[20]; /* Open the dat file */ file_ptr = fopen(dat_file, "a"); if (file_ptr == NULL) { printf("vibratingwire_dat_meas: Unable to open vibrating wire dat file\n"); return; } /* Make a title and set the units */ if (strcmp(move_dir, "x") == 0) { strcpy(title, "Magnet X Scan"); strcpy(units, " (m) "); } else if (strcmp(move_dir, "y") == 0) { strcpy(title, "Magnet Y Scan"); strcpy(units, " (m) "); } else if (strcmp(move_dir, "yaw") == 0) { strcpy(title, "Magnet Yaw Scan"); strcpy(units, " (rad) "); } else if (strcmp(move_dir, "pitch") == 0) { strcpy(title, "Magnet Pitch Scan"); strcpy(units, " (rad) "); } else { vibratingwire_error("vibratingwire_dat_meas_header: Unrecognized move direction."); } /* Write a header when starting a new set of measurements */ fprintf(file_ptr, "\n"); fprintf(file_ptr, "\n"); fprintf(file_ptr, " %s\n", title); fprintf(file_ptr, "\n"); fprintf(file_ptr, "Magnet Current: %f +/- %f A\n", imag, sigimag); fprintf(file_ptr, "Signal Generator Amplitude: %f V\n", ampl); fprintf(file_ptr, "Signal Generator Frequency: %f Hz\n", freq); fprintf(file_ptr, "\n"); fprintf(file_ptr, " Pos Xdet_Vx Xdet_Vy Ydet_Vx Ydet_Vy \n"); fprintf(file_ptr, " # %s (Vrms) (Vrms) (Vrms) (Vrms) \n", units); fprintf(file_ptr, "----- ---------- ---------- ---------- ---------- ----------\n"); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * vibratingwire_dat_meas * This function writes the results of a vibrating wire measurement * to the data file. * * Input: * meas_num, measurement number * mag_pos, magnet position (m) or (rad) * xdet_vxrms, x detector, in phase voltage (Vrms) * xdet_vyrms, x detector, 90 deg out of phase voltage (Vrms) * ydet_vxrms, y detector, in phase voltage (Vrms) * ydet_vyrms, y detector, 90 deg out of phase voltage (Vrms) * * Zachary Wolf * 10/6/05 */ void vibratingwire_dat_meas(int meas_num, double mag_pos, double xdet_vxrms, double xdet_vyrms, double ydet_vxrms, double ydet_vyrms) { /* Declare variables */ FILE* file_ptr; /* Open the dat file */ file_ptr = fopen(dat_file, "a"); if (file_ptr == NULL) { printf("vibratingwire_dat_meas: Unable to open vibrating wire dat file\n"); return; } /* Write the data */ fprintf(file_ptr, "%5i %10.6f %10.6f %10.6f %10.6f %10.6f\n", meas_num, mag_pos, xdet_vxrms, xdet_vyrms, ydet_vxrms, ydet_vyrms); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * vibratingwire_calc_dat_center_pos * This function writes the result of a magnet center position measurement * to the data file. * * Input: * move_dir, move direction "x", "y", "yaw", or "pitch" * pos, position of the magnet when it is centered on the wire (m or rad) * rms value of position * * Output: * Offset, the physical offset of caluclated from the residual ydet_vyrms value. * * Zachary Wolf * 10/6/05 * * SDA - Added RMS value */ void vibratingwire_calc_dat_center_pos(char move_dir[], double pos, double rms, double xdet_vyrms, double ydet_vyrms, double vyrms_x_slope, double *offset) { /* Declare variables */ FILE* file_ptr; char title[80]; char units[20]; double final_det_volts; double final_offset, final_offset_old; char offset_units[20]; /* Open the log file */ file_ptr = fopen(log_file, "a"); if (file_ptr == NULL) { printf("vibratingwire_dat_meas: Unable to open vibrating wire dat file\n"); return; } /* Make a title and set the units */ if (strcmp(move_dir, "x") == 0) { strcpy(title, "Magnet X Position When Centered On Wire:"); strcpy(units, "m"); final_det_volts = xdet_vyrms; final_offset_old = xdet_vyrms/280.0; final_offset = xdet_vyrms/vyrms_x_slope; strcpy(offset_units, "m"); } else if (strcmp(move_dir, "y") == 0) { strcpy(title, "Magnet Y Position When Centered On Wire:"); strcpy(units, "m"); final_det_volts = ydet_vyrms; final_offset_old = ydet_vyrms/490.; final_offset = ydet_vyrms/vyrms_x_slope; strcpy(offset_units, "m"); } else if (strcmp(move_dir, "yaw") == 0) { strcpy(title, "Magnet Yaw When Centered On Wire:"); strcpy(units, "rad"); final_det_volts = xdet_vyrms; final_offset_old = xdet_vyrms/3.5; final_offset = xdet_vyrms/vyrms_x_slope; strcpy(offset_units, "rad"); } else if (strcmp(move_dir, "pitch") == 0) { strcpy(title, "Magnet Pitch When Centered On Wire:"); strcpy(units, "rad"); final_det_volts = ydet_vyrms; final_offset_old = ydet_vyrms/1.16; final_offset = ydet_vyrms/vyrms_x_slope; strcpy(offset_units, "rad"); } else { vibratingwire_error("vibratingwire_dat_meas_header: Unrecognized move direction."); } /* Write the amount of error given by the voltage signal at the centered position to log file. */ fprintf(file_ptr, "%s %s %10.7f +/- %10.7f %s\n",TimeStr(), title, pos, rms, units); fprintf(file_ptr, "%s Centered Detector Vy = %10.7f Vrms or offest = %10.7f %s \n", TimeStr(), final_det_volts, final_offset, offset_units); fprintf(file_ptr, "%s Old Offset Vy/x = %10.7f Calculated Offset = %10.7f \n", TimeStr(), final_offset_old, final_offset); *offset = final_offset; /* Close the log file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * vibratingwire_write_dat_center_pos * This function writes the result of a magnet center position measurement * to the data file. * * Input: * move_dir, move direction "x", "y", "yaw", or "pitch" * pos, position of the magnet when it is centered on the wire (m or rad) * rms value of position * * Output: * Offset, the physical offset of caluclated from the residual ydet_vyrms value. * * Zachary Wolf * 10/6/05 * * SDA - Added RMS value */ void vibratingwire_write_dat_center_pos(char move_dir[], double pos, double rms, double xdet_vyrms, double ydet_vyrms, double vyrms_x_slope, double *offset) { /* Declare variables */ FILE* file_ptr; char title[80]; char units[20]; double final_det_volts; double final_offset; char offset_units[20]; /* Open the dat file */ file_ptr = fopen(dat_file, "a"); if (file_ptr == NULL) { printf("vibratingwire_dat_meas: Unable to open vibrating wire dat file\n"); return; } /* Make a title and set the units */ if (strcmp(move_dir, "x") == 0) { strcpy(title, "Magnet X Position When Centered On Wire:"); strcpy(units, "m"); final_det_volts = xdet_vyrms; final_offset = (xdet_vyrms/vyrms_x_slope)*1e6; strcpy(offset_units, "microns"); } else if (strcmp(move_dir, "y") == 0) { strcpy(title, "Magnet Y Position When Centered On Wire:"); strcpy(units, "m"); final_det_volts = ydet_vyrms; final_offset = (ydet_vyrms/vyrms_x_slope)*1e6; strcpy(offset_units, "microns"); } else if (strcmp(move_dir, "yaw") == 0) { strcpy(title, "Magnet Yaw When Centered On Wire:"); strcpy(units, "rad"); final_det_volts = xdet_vyrms; final_offset = (xdet_vyrms/vyrms_x_slope)*1e3; strcpy(offset_units, "mrad"); } else if (strcmp(move_dir, "pitch") == 0) { strcpy(title, "Magnet Pitch When Centered On Wire:"); strcpy(units, "rad"); final_det_volts = ydet_vyrms; final_offset = (ydet_vyrms/vyrms_x_slope)*1e3; strcpy(offset_units, "mrad"); } else { vibratingwire_error("vibratingwire_dat_meas_header: Unrecognized move direction."); } /* Write the amount of error given by the voltage signal at the centered position. */ fprintf(file_ptr, "\n"); fprintf(file_ptr, "%s %10.7f +/- %10.7f %s\n", title, pos, rms, units); fprintf(file_ptr, "Centered Detector Vy = %10.7f Vrms or offest = %6.3f %s, Slope = % 7.4g %s / Volt \n", final_det_volts, final_offset, offset_units, 1.0/vyrms_x_slope, units); *offset = final_offset; /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * vibratingwire_dat_wire_pos * This function calculate the result of a wire position measurement * to the data file. * * Input: * det_num, wire position detector number (0, 1, ...) * pos, position of the wire measured by the detector (m) * * Zachary Wolf * 10/6/05 */ void vibratingwire_dat_wire_pos(int det_num, double pos) { /* Declare variables */ FILE* file_ptr; /* Open the dat file */ file_ptr = fopen(dat_file, "a"); if (file_ptr == NULL) { printf("vibratingwire_dat_wire_pos: Unable to open vibrating wire dat file\n"); return; } /* Write the wire position */ fprintf(file_ptr, "\n"); fprintf(file_ptr, "Wire Position: %s, Position = %11.8f m\n", WIRPOS_DET_INFO[det_num].name, pos); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * vibratingwire_dat_mag_move_summary * This function writes the result of a wire position measurement * to the data file. * * Input: * x_data, x movement data (m) * y_data, y movement data (m) * pitch_data, pitch movement data (rad) * yaw_data, yaw movement data (rad) * num_data_points, number of data points in each array * * Scott Anderson * 12/14/07 */ void vibratingwire_dat_mag_move_summary (double *x_data, double *y_data, double *pitch_data, double *yaw_data, int num_data_points) { /* Declare variables */ int i; FILE* file_ptr; /* Open the dat file */ file_ptr = fopen(dat_file, "a"); if (file_ptr == NULL) { printf("vibratingwire_dat_mag_move_summary: Unable to open vibrating wire dat file\n"); return; } fprintf(file_ptr, "\n\n"); fprintf(file_ptr, " Cam Move Summary \n"); fprintf(file_ptr, " Meas X Pos Y Pos Pitch Pos Yaw Pos \n"); fprintf(file_ptr, " # microns microns mrad mrad \n"); fprintf(file_ptr, "----- ---------- ---------- ---------- ----------- \n"); /* Write the magnet movement summary */ for(i=0; i <= num_data_points; i++) { fprintf(file_ptr, "%5i %10.4f %10.4f %10.4f %10.4f \n", i, x_data[i]*1e6, y_data[i]*1e6, pitch_data[i]*1e3, yaw_data[i]*1e3); } /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * vibratingwire_dat_mag_move_converge_check * This function writes the result of a wire position measurement * to the data file. * * Input: * msg - char array giving the header for convergence check * dx, x movement data (m) * dy, y movement data (m) * dpitch, pitch movement data (rad) * dyaw, yaw movement data (rad) * * Scott Anderson * 12/14/07 */ void vibratingwire_dat_mag_move_converge_check (char* msg, double dx, double dy, double dpitch, double dyaw) { /* Declare variables */ int i; FILE* file_ptr; /* Open the dat file */ file_ptr = fopen(dat_file, "a"); if (file_ptr == NULL) { printf("vibratingwire_log_mag_move_converge_check: Unable to open vibrating wire log file\n"); return; } fprintf(file_ptr, msg); fprintf(file_ptr, "\n\nX direction moved %.2f microns compared to the tolerence of %.2f \n",(dx)*1.e6, VIBRATINGWIRE_X_CONV*1.e6); fprintf(file_ptr, "Y direction moved %.2f microns compared to the tolerence of %.2f \n",(dy)*1.e6, VIBRATINGWIRE_X_CONV*1.e6); fprintf(file_ptr, "Pitch moved %.3f mrads compared to the tolerence of %.3f \n",(dpitch)*1.e3, VIBRATINGWIRE_PITCH_CONV*1.e3); fprintf(file_ptr, "Yaw moved %.3f mrads compared to the tolerence of %.3f \n\n",(dyaw)*1.e3, VIBRATINGWIRE_PITCH_CONV*1.e3); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * vibratingwire_plt_wire_header * This function writes the header of a wire detector measurement * plot file. * * Input: * * Scott Anderson * 1/31/08 */ void vibratingwire_plt_wire_header() { /* Declare variables */ FILE* file_ptr; /* Open the dat file */ file_ptr = fopen(wire_plt_file, "a"); if (file_ptr == NULL) { printf("vibratingwire_plot_wire_pos: Unable to open vibrating wire plot file\n"); return; } /* Write the wire position */ fprintf(file_ptr, "Detector# Position \n"); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * vibratingwire_plt_wire_pos * This function writes the result of a wire position measurement * to the plot file. * * Input: * det_num, wire position detector number (0, 1, ...) * pos, position of the wire measured by the detector (m) * * Scott Anderson * 1/31/08 */ void vibratingwire_plt_wire_pos(int det_num, double pos) { /* Declare variables */ FILE* file_ptr; /* Open the dat file */ file_ptr = fopen(wire_plt_file, "a"); if (file_ptr == NULL) { printf("vibratingwire_plot_wire_pos: Unable to open vibrating wire plot file\n"); return; } /* Write the wire position */ fprintf(file_ptr, " %i %11.8f \n", det_num, pos); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * vibratingwire_plt_meas_header * This function writes a header for a vibrating wire measurement * to the plot file. * * Input: * * Scott Anderson * 2/8/2008 */ void vibratingwire_plt_meas_header() { /* Declare variables */ FILE* file_ptr; /* Open the dat file */ file_ptr = fopen(plt_file, "a"); if (file_ptr == NULL) { printf("vibratingwire_plt_meas_header: Unable to open vibrating wire plt file\n"); return; } /* Write a header */ fprintf(file_ptr, "Time Meas Type Pos Pos Unit Imag Sig Ampl Sig Freq Xdet_Vx Xdet_Vy Ydet_Vx Ydet_Vy \n"); fprintf(file_ptr, " # (A) (V0-p) (Hz) (Vrms) (Vrms) (Vrms) (Vrms) \n"); fprintf(file_ptr, "-------- ----- ----------- ---------- ---------- ----------- ---------- ---------- ---------- ---------- ---------- ---------- \n"); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * vibratingwire_plt_mag_move_summary * This function writes the result of a wire position measurement * to the data file. * * Input: * x_data, x movement data (m) * y_data, y movement data (m) * pitch_data, pitch movement data (rad) * yaw_data, yaw movement data (rad) * num_data_points, number of data points in each array * * Scott Anderson * 12/14/07 */ void vibratingwire_plt_mag_move_summary (double *x_data, double *y_data, double *pitch_data, double *yaw_data, int num_data_points) { /* Declare variables */ int i; FILE* file_ptr; /* Open the dat file */ file_ptr = fopen(plt_file, "a"); if (file_ptr == NULL) { printf("vibratingwire_dat_mag_move_summary: Unable to open vibrating wire dat file\n"); return; } fprintf(file_ptr, "\n\n"); fprintf(file_ptr, " Cam Move Summary \n"); fprintf(file_ptr, " Meas X Pos Y Pos Pitch Pos Yaw Pos \n"); fprintf(file_ptr, " # microns microns mrad mrad \n"); fprintf(file_ptr, "----- ---------- ---------- ---------- ----------- \n"); /* Write the magnet movement summary */ for(i=0; i <= num_data_points; i++) { fprintf(file_ptr, "%5i %10.4f %10.4f %10.4f %10.4f \n", i, x_data[i]*1e6, y_data[i]*1e6, pitch_data[i]*1e3, yaw_data[i]*1e3); } /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ /* * vibratingwire_plt_meas * This function writes the results of a vibrating wire measurement * to the plot file. * * Input: * move_dir, move direction "x", "y", "yaw", or "pitch" * meas_num, measurement number * mag_pos, magnet position (m) or (rad) * imag, magnet current (A) * ampl, signal generator amplitude (V_0p) * freq, signal generator frequency (Hz) * xdet_vxrms, x detector, in phase voltage (Vrms) * xdet_vyrms, x detector, 90 deg out of phase voltage (Vrms) * ydet_vxrms, y detector, in phase voltage (Vrms) * ydet_vyrms, y detector, 90 deg out of phase voltage (Vrms) * * Zachary Wolf * 10/6/05 */ void vibratingwire_plt_meas(char move_dir[], int meas_num, double mag_pos, double imag, double ampl, double freq, double xdet_vxrms, double xdet_vyrms, double ydet_vxrms, double ydet_vyrms) { /* Declare variables */ FILE* file_ptr; char title[80]; char units[20]; /* Open the dat file */ file_ptr = fopen(plt_file, "a"); if (file_ptr == NULL) { printf("vibratingwire_plt_meas: Unable to open vibrating wire plt file\n"); return; } /* Make a title and set the units */ if (strcmp(move_dir, "x") == 0) { strcpy(title, "Mag X"); strcpy(units, " (m) "); } else if (strcmp(move_dir, "y") == 0) { strcpy(title, "Mag Y"); strcpy(units, " (m) "); } else if (strcmp(move_dir, "yaw") == 0) { strcpy(title, "Mag Yaw"); strcpy(units, " (rad) "); } else if (strcmp(move_dir, "pitch") == 0) { strcpy(title, "Mag Pitch"); strcpy(units, " (rad) "); } else { vibratingwire_error("vibratingwire_dat_meas_header: Unrecognized move direction."); } /* Write the data */ fprintf(file_ptr,"%s %5i %s %10.6f %s %10.6f %10.6f %10.6f %10.6f %10.6f %10.6f %10.6f\n", TimeStr(), meas_num, title, mag_pos, units, imag, ampl, freq, xdet_vxrms, xdet_vyrms, ydet_vxrms, ydet_vyrms); /* Close the dat file */ fclose(file_ptr); /* Done */ return; } /* ************************************************************** */ void vibratingwire_exit(void) { /* Declare variables */ char buf[80]; /* Exit the vibwire system */ vibwire_exit(); /* Exit the movemag system */ cam_move_exit(); /* Exit the magnet current system */ imag_exit(); /* Exit the wirepos system */ wirpos_exit(); /* Hold the screen for the operator */ printf("\nPress ENTER to terminate program.\n"); fgets(buf, 80, stdin); /* Done */ return; } /* ************************************************************** */ /* * vibratingwire_error * This function handles errors for the vibrating wire module. * * Input: * message, string to display in standard I/O * * Zachary Wolf * 10/11/98 */ void vibratingwire_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); } /* *************************************************************** */ /* * vibratingwire_adjust_step * This function adjusts the step size used for scanning. This allows the program to * zero in on the right position starting at a very wide range. * * Input: * dx,dy,dpitch,dyaw - how much each component was adjusted during the previous run * x_step,y_step,pitch_step,yaw_step - the step sizes used * * Output: * 0 - the magnet is not yet aligned on the wire. Moved significantly during the last step * 1 - magnet moved less than a certain threshold * * Michael Levashov * 07/24/07 */ int vibratingwire_adjust_step(double dx,double dy,double dpitch,double dyaw,double *x_step,double *y_step,double *pitch_step,double *yaw_step) { double errorx, errory, errorpitch, erroryaw; double x_width, y_width, pitch_width, yaw_width; x_width=(VIBRATINGWIRE_NUM_X_POS-1)*(*x_step); y_width=(VIBRATINGWIRE_NUM_Y_POS-1)*(*y_step); pitch_width=(VIBRATINGWIRE_NUM_PITCH_POS-1)*(*pitch_step); yaw_width=(VIBRATINGWIRE_NUM_YAW_POS-1)*(*yaw_step); //First, lets check that we are not done if((dx < VIBRATINGWIRE_X_CONV) && (dy < VIBRATINGWIRE_Y_CONV) && (dpitch < VIBRATINGWIRE_PITCH_CONV) && (dyaw < VIBRATINGWIRE_YAW_CONV)) return 1; else { //First, I determine if the fit was inside the original range and I can trust the calculated zero coordinates //Next, I account for how much it might have changed from changes in other coordinates //If the fit gave a value outside twice the fitting range, the range is not changed if(dx < x_width) //X { errorx=fabs(dx/2/(VIBRATINGWIRE_NUM_X_POS-1)) + fabs(dyaw*0.01); //assume 1 cm offset if(errorx < x_width/2) { *x_step=ceil(errorx/(VIBRATINGWIRE_NUM_X_POS-1)* 1.e6) * 1.e-6; if(*x_step