// $Id$ /*! * \file kat_read.c * \brief Input file reading routines. * * @section Copyright notice * * This file is part of the interferometer simulation Finesse * http://www.gwoptics.org/finesse * * Copyright (C) 1999 onwards Andreas Freise * with parts of the code written by Daniel Brown, Paul Cochrane * and Gerhard Heinzel. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, * Suite 330, Boston, MA 02111-1307 USA */ #define _GNU_SOURCE #include #include "kat.h" #include "kat_mem.h" #include "kat_config.h" #include "kat_read.h" #include "kat_optics.h" #include "kat_inline.c" #include "kat_io.h" #include "kat_aux.h" #include "kat_init.h" #include "kat_aa.h" #include "kat_check.h" #include "base64.h" #include "fmemopen.h" #include "uthash.h" extern transfer_func_t mtf_free_mass; extern double *f_s; //!< Frequency value list [frequency] extern complex_t ***a_s; //!< Amplitude list [field] [output] [frequeny] extern int *t_s; //!< Type_of_Signal list [frequency] int *transfer; //!< ??? extern bool bCygserverRunning; extern init_variables_t init; extern interferometer_t inter; extern options_t options; extern memory_t mem; extern local_var_t vlocal; extern char functokens[]; extern const int MAX_NEWTON_WEIGHT; int endcomp; //!< ??? int lastparam; //!< ??? extern char *__merged_kat_buffer; extern FILE *__merged_kat_file; bool check_for_include_kat(FILE **ptr_ifp){ assert(ptr_ifp != NULL); FILE *ifp = *ptr_ifp; rewind(ifp); int num_includes = 0; char tmp[LINE_LEN] = {0}; char include_command_str[MAX_INCLUDES][LINE_LEN] = {{0}}; char include_filenames[MAX_INCLUDES][LINE_LEN] = {{0}}; FILE* include_files[MAX_INCLUDES] = {0}; size_t include_filesize[MAX_INCLUDES] = {0}; int include_num_blocks[MAX_INCLUDES] = {0}; char include_blocklist[MAX_INCLUDES][LINE_LEN] = {{0}}; char include_blocks[MAX_INCLUDES][MAX_BLOCKS][LINE_LEN] = {{{0}}}; // include can only be used on the very first line while(fgets(tmp, LINE_LEN - 1, ifp) != NULL) { char *s = tmp + strspn(tmp, WHITESPACE); /* skip whitespace */ if(s[strlen(s) - 1] == '\n') s[strlen(s) - 1] = '\0'; if (strncasecmp(s, "!include ", 9) == 0){ if(num_includes >= MAX_INCLUDES){ gerror("Line `%s':\n Maximum number of includes has been reached\n", s); } strcpy(include_command_str[num_includes], s); num_includes++; } } if(!num_includes) return false; int k=0; size_t kat_size = 0, include_size = 0; // get the kat file size fseek(ifp, 0L, SEEK_END); kat_size = ftell(ifp); rewind(ifp); assert(kat_size > 0); for(k=0; k 0); include_size += include_filesize[k]; if(n == 3){ // if there are 3 inputs the the blocks string should contain space // delimited list of block names to include char *pch = strtok (include_blocklist[k], " "); while (pch != NULL) { strcpy(include_blocks[k][include_num_blocks[k]], pch); include_num_blocks[k]++; pch = strtok (NULL, " "); } } } assert(include_size > 0); // allocate memory to store the merged file, this is free'd at the // end of the main function. __merged_kat_buffer = (char*) malloc(sizeof(char) * (kat_size + include_size + num_includes + 1)); __merged_kat_file = fmemopen(__merged_kat_buffer, kat_size + include_size + num_includes + 1, "r+"); for(k=0; k 0){ warn("with %i blocks:", include_num_blocks[k]); int n; for(n=0; n -1) { if(strncasecmp(s, "%%% FTend", 9) == 0) { int n = 0; // search each block and make sure that we find the end // to the block we are in for(n=0; n -1 && strncasecmp(s, "%%%", 3) != 0){ fwrite(s, sizeof(char), strlen(s), __merged_kat_file); } } if(k>0){ // separate the included files with a line ending fprintf(__merged_kat_file, "\n"); } } } // Now read in the kat file that has been run fread(__merged_kat_buffer+ftell(__merged_kat_file), kat_size, 1, ifp); // rewind(__merged_kat_file); // char l[LINE_LEN]; // while (fgets(l, LINE_LEN - 1, __merged_kat_file) != NULL) { // message(l); // } // Now that we have merged everything, close the original file handle // and set the main file handle to that of our merged one. fclose(ifp); for(k=0; k 0){ read_mhd_out(s); } else if (strncasecmp(s, "sd ", 3) == 0 || strncasecmp(s, "sd* ", 4) == 0) { read_sd_out(s); } else if (strncasecmp(s, "ad ", 3) == 0) { read_amp_out(s); } else if (strncasecmp(s, "qd ", 3) == 0) { read_qd_out(s); } else if (strncasecmp(s, "xlink ", 6) == 0) { read_motion_link(s); } else if (strncasecmp(s, "xd ", 3) == 0) { read_motion_out(s); } else if (strncasecmp(s, "pgaind ", 7) == 0) { read_openloopTF_out(s); } else if (strncasecmp(s, "fd ", 3) == 0) { read_force_out(s); } else if (strncasecmp(s, "slink ", 6) == 0) { read_slink(s); } else if (strncasecmp(s, "vacuum ", 7) == 0) { read_vacuum(s, false); } else if (strncasecmp(s, "qnoised ", 8) == 0 || strncasecmp(s, "qnoisedS ", 9) == 0 || strncasecmp(s, "qnoisedN ", 9) == 0) { read_qnoised_cmd(s); } else if (strncasecmp(s, "bp ", 3) == 0) { read_beamparam_out(s); } #ifdef DEVELOP else if (strncasecmp(s, "conv ", 5) == 0) { read_convolution_out(s); } else if (strncasecmp(s, "mp ", 3) == 0) { read_mirror_phase_out(s); } #endif else if (strncasecmp(s, "gouy ", 5) == 0) { // if (!inter.beam.set) read_gouy_out(s); }else if (strncasecmp(s, "map ", 4) == 0) { read_maps(s); } else if (strncasecmp(s, "smotion ", 8) == 0) { read_surface_motion_map(s); } else if (strncasecmp(s, "beam ", 5) == 0) { read_beam(s); } else if (strncasecmp(s, "cav ", 4) == 0 || strncasecmp(s, "cavity ", 7) == 0) { read_cavity(s); } else if (strncasecmp(s, "gauss** ", 8) == 0) { read_gaussRc(s); } else if (strncasecmp(s, "gauss* ", 7) == 0) { read_gauss2(s); } else if (strncasecmp(s, "gauss ", 6) == 0) { read_gauss(s); } else if (strncasecmp(s, "tem ", 4) == 0) { read_ltem(s, false); } else if (strncasecmp(s, "tem* ", 5) == 0) { read_ltem(s, true); } else if (strncasecmp(s, "retrace ", 8) == 0) { read_retrace(s); } else if (strncasecmp(s, "conf ", 5) == 0) { read_conf(s); } else if (strncasecmp(s, "/*", 2) == 0) { read_init_dummy(fp, 1); } } rewind(fp); if (inter.debug & 512) { message("..3.."); fflush(stdout); } while (fgets(s0, LINE_LEN - 1, fp) != NULL) { s = s0 + strspn(s0, WHITESPACE); /* skip whitespace */ if (prepare_line(s, 1)) { continue; } insert_constants_values(s); if (strncasecmp(s, "set ", 4) == 0) { read_set_command(s); } else if (strncasecmp(s, "cp ", 3) == 0) { read_cavity_param_out(s); } else if (strncasecmp(s, "gnuplot", 7) == 0) { read_init_dummy(fp, 0); } else if (strncasecmp(s, "python", 6) == 0) { read_init_dummy(fp, 0); } else if (strncasecmp(s, "matlabplot", 10) == 0) { read_init_dummy(fp, 0); } else if (strncasecmp(s, "matlab", 6) == 0) { read_init_dummy(fp, 0); } else if (strncasecmp(s, "/*", 2) == 0) { read_init_dummy(fp, 1); } } rewind(fp); if (inter.debug & 512) { message("..(y).."); fflush(stdout); } while (fgets(s0, LINE_LEN - 1, fp) != NULL) { s = s0 + strspn(s0, WHITESPACE); /* skip whitespace */ if (prepare_line(s, 1)) { continue; } insert_constants_values(s); if (strncasecmp(s, "xaxis*", 6) == 0) { read_xaxis2(s); } else if (strncasecmp(s, "xaxis", 5) == 0) { read_xaxis(s); } else if (strncasecmp(s, "x3axis*", 7) == 0) { read_x3axis2(s); } else if (strncasecmp(s, "x3axis", 6) == 0) { read_x3axis(s); } else if (strncasecmp(s, "x2axis*", 7) == 0) { read_x2axis2(s); } else if (strncasecmp(s, "x2axis", 6) == 0) { read_x2axis(s); } else if (strncasecmp(s, "noxaxis ", 8) == 0) { inter.noxaxis = 1; } else if (strncasecmp(s, "gnuplot", 7) == 0) { read_init_dummy(fp, 0); } else if (strncasecmp(s, "python", 6) == 0) { read_init_dummy(fp, 0); } else if (strncasecmp(s, "matlabplot", 10) == 0) { read_init_dummy(fp, 0); } else if (strncasecmp(s, "matlab", 6) == 0) { read_init_dummy(fp, 0); } else if (strncasecmp(s, "/*", 2) == 0) { read_init_dummy(fp, 1); } } if (inter.x1.xtype == NO_FREQ && inter.noxaxis == 0) { gerror("missing 'xaxis' instruction\n"); } rewind(fp); while (fgets(s0, LINE_LEN - 1, fp) != NULL) { s = s0 + strspn(s0, WHITESPACE); /* skip whitespace */ if (prepare_line(s, 1)) { continue; } insert_constants_values(s); if (strncasecmp(s, "func ", 5) == 0) { read_func_command(s); } else if (strncasecmp(s, "showiterate ", 12) == 0) { read_showiterate(s); } else if (strncasecmp(s, "lock ", 5) == 0) { read_lock_command(s); } else if (strncasecmp(s, "lock* ", 6) == 0) { read_lock2(s); } else if (strncasecmp(s, "gnuplot", 7) == 0) { read_init_dummy(fp, 0); } else if (strncasecmp(s, "python", 6) == 0) { read_init_dummy(fp, 0); } else if (strncasecmp(s, "matlabplot", 10) == 0) { read_init_dummy(fp, 0); } else if (strncasecmp(s, "matlab", 6) == 0) { read_init_dummy(fp, 0); } else if (strncasecmp(s, "/*", 2) == 0) { read_init_dummy(fp, 1); } } rewind(fp); if (inter.debug & 512) { message("..(x).."); fflush(stdout); } int i; for(i=0; i 0) { read_put_command(inter.tmp_put_cmds[i]); } } while (fgets(s0, LINE_LEN - 1, fp) != NULL) { s = s0 + strspn(s0, WHITESPACE); /* skip whitespace */ if (prepare_line(s, 1)) { continue; } insert_constants_values(s); if (strncasecmp(s, "noplot ", 7) == 0) { read_noplot(s); } else if (strncasecmp(s, "put ", 4) == 0) { read_put_command(s); } if (strncasecmp(s, "put* ", 5) == 0) { read_put_star_command(s); } else if (strncasecmp(s, "color", 5) == 0) { read_color(s); } else if (strncasecmp(s, "mask ", 5) == 0) { read_mask(s); } else if (strncasecmp(s, "width", 5) == 0) { read_width(s); } else if (strncasecmp(s, "deriv_h", 7) == 0) { read_deriv_h(s); } else if (strncasecmp(s, "scale", 5) == 0) { read_scale(s); } else if (strncasecmp(s, "time", 4) == 0) { inter.time = 1; } else if (strncasecmp(s, "noscripts", 9) == 0) { inter.noscripts = 1; } else if (strncasecmp(s, "multi", 5) == 0) { inter.multi = true; } else if (strncasecmp(s, "subplot", 7) == 0) { inter.subplot = true; } else if (strncasecmp(s, "pause", 5) == 0) { inter.pause = 1; } else if (strncasecmp(s, "printnoises", 11) == 0) { inter.printqnoiseinputs = true; } else if (strncasecmp(s, "printmatrix", 11) == 0) { inter.printmatrix = 1; } else if (strncasecmp(s, "mismatches", 10) == 0) { read_mismatches_command(s); } else if (strncasecmp(s, "frequency", 9) == 0) { read_frequency_command(s); } else if (strncasecmp(s, "powers", 6) == 0) { read_powers(s); } else if (strncasecmp(s, "trace", 5) == 0) { read_trace(s); }// this should already have been done in pre_scan() //else if (strncasecmp(s, "noise", 5) == 0) { //read_noise(s); //} else if (strncasecmp(s, "phase ", 6) == 0) { read_phase(s); } else if (strncasecmp(s, "gnuterm", 7) == 0) { read_gnuterm(s); } else if (strncasecmp(s, "pyterm", 6) == 0) { read_pyterm(s); } else if (strncasecmp(s, "gnuplot", 7) == 0) { ri_gnuplot(fp); } else if (strncasecmp(s, "python", 6) == 0) { ri_python(fp); } else if (strncasecmp(s, "matlabplot", 10) == 0) { ri_matlabplot(fp); } else if (strncasecmp(s, "matlab", 6) == 0) { ri_matlab(fp); } else if (strncasecmp(s, "diff", 4) == 0) { read_deriv(s); } else if (strncasecmp(s, "yaxis", 5) == 0) { read_yaxis(s); } else if (strncasecmp(s, "video ", 5) == 0) { inter.video = 1; } else if (strncasecmp(s, "startnode ", 10) == 0) { read_startnode(s); } else if (strncasecmp(s, "pdtype ", 7) == 0) { read_pdtype(s); } else if (strncasecmp(s, "maximize ", 9) == 0 || strncasecmp(s, "minimize ", 9) == 0) { read_minimize(s); } else if (strncasecmp(s, "/*", 2) == 0) { read_init_dummy(fp, 1); } } if (inter.debug & 512) { message("..4.."); fflush(stdout); } rewind(fp); // TODO - is this actually needed this final check? check_all_commands(fp); if (inter.debug & 512) { message("..done!\n"); fflush(stdout); } assert(inter.num_blocks == mem.num_blocks); assert(inter.num_mirrors == mem.num_mirrors); assert(inter.num_spaces == mem.num_spaces); assert(inter.num_beamsplitters == mem.num_beamsplitters); assert(inter.num_modulators == mem.num_modulators); assert(inter.num_light_inputs == mem.num_light_inputs); assert(inter.num_sagnacs == mem.num_sagnacs); assert(inter.num_diodes == mem.num_diodes); assert(inter.num_variables == mem.num_variables); assert(inter.num_lenses == mem.num_lenses); assert(inter.num_gratings == mem.num_gratings); assert(inter.num_components == mem.num_components); assert(inter.num_convolution_outputs == mem.num_convolution_outputs); assert(inter.num_transfer_funcs == mem.num_transfer_funcs); assert(inter.num_quad_outputs == mem.num_quad_outputs); assert(inter.num_slinks == mem.num_feedbacks); assert(inter.num_dof == mem.num_dof); } void read_dof(const char* command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char dof_name[MAX_TOKEN_LEN] = {0}; char parameter[MAX_TOKEN_LEN] = {0}; char rest[MAX_TOKEN_LEN] = {0}; int n = sscanf(command_string, "%s %s %s %s", command_name, dof_name, parameter, rest); if(n != 4 && strlen(rest) == 0) gerror("Line `%s':\ndof usage is 'dof name parameter comp1 factor [comp2 factor [...]]'\n", command_string); dof_t *dof = &inter.dof_list[inter.num_dof]; check_name(command_string, dof_name); strcpy(dof->name, dof_name); char tmp[MAX_TOKEN_LEN] = {0}; do{ char comp_name[MAX_TOKEN_LEN] = {0}; char factor[MAX_TOKEN_LEN] = {0}; strcpy(tmp, rest); n = sscanf(tmp, "%s %s %s", comp_name, factor, rest); if(n==0){ break; // nothing to process } if(n != 2 || n != 3) { gerror("Line `%s':\nCould not process '%s' of the DOF inputs\n", command_string, tmp); } else { dof->component_idx[dof->num_components] = get_component_index_from_name(comp_name); dof->component_type[dof->num_components] = get_component_type_decriment_index(&(dof->component_idx[dof->num_components])); if(dof->component_type[dof->num_components] != MIRROR || dof->component_type[dof->num_components] != BEAMSPLITTER) { gerror("Line `%s':\nDOF only supports mirrors and beamsplitters currently\n", command_string); } if(atod(factor, &(dof->factors[dof->num_components]))) gerror("Line `%s':\ncould not factor '%s' as a number\n", command_string, factor); dof->num_components++; } }while(n > 2); dof->list_index = inter.num_dof; inter.num_dof++; } void read_slink(const char* command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char slink_name[MAX_TOKEN_LEN] = {0}; char output_name[MAX_TOKEN_LEN] = {0}; char input_name[MAX_TOKEN_LEN] = {0}; char input_motion[MAX_TOKEN_LEN] = {0}; char transfer[MAX_TOKEN_LEN] = {0}; char rest[MAX_TOKEN_LEN] = {0}; int n = sscanf(command_string, "%s %s %s %s %s %s %s", command_name, slink_name, output_name, input_name, input_motion, transfer, rest); if(n != 6 && n != 7) gerror("Line `%s':\nslink usage is 'slink name output input motion transfer_function'\n", command_string, output_name); int idx = inter.num_slinks; slink_t *fb = &inter.slink_list[idx]; fb->list_index = idx; strcpy(fb->name, slink_name); strcpy(fb->motion_name, input_motion); fb->comp_list_idx = get_component_index_from_name(input_name); if(fb->comp_list_idx == NOT_FOUND) gerror("Line `%s':\nCould not find input component '%s'\n", command_string, input_name); fb->comp_type = get_component_type_decriment_index(&fb->comp_list_idx); if(fb->comp_type == MIRROR){ mirror_t *m = &inter.mirror_list[fb->comp_list_idx]; fb->comp_motion_idx = motion_string_to_index(input_motion, m->mass, m->Ix, m->Iy, m->num_surface_motions); } else if(fb->comp_type == BEAMSPLITTER){ beamsplitter_t *bs = &inter.bs_list[fb->comp_list_idx]; fb->comp_motion_idx = motion_string_to_index(input_motion, bs->mass, bs->Ix, bs->Iy, 0); } else { gerror("Line `%s':\nInput component '%s' must be a mirror or beamsplitter\n", command_string, input_name); } if(fb->comp_motion_idx == NOT_FOUND) gerror("Line `%s':\nMotion '%s' is not available for component %s\n", command_string, input_motion, input_name); fb->output_list_idx = get_component_index_from_name(output_name); if(fb->output_list_idx == NOT_FOUND) gerror("Line `%s':\nCould not find output detector '%s'\n", command_string, output_name); int output_type = get_component_type_decriment_index(&(fb->output_list_idx)); if(output_type != OUT) gerror("Line `%s':\nslink output detector '%s' must be either a signal demodulated photodiode, a qnoised or a qshot detector\n", command_string, output_name); output_data_t *out = &inter.output_data_list[fb->output_list_idx]; if(out->detector_type != QNOISE && out->detector_type != QSHOT && out->detector_type != PD1) gerror("Line `%s':\nslink output detector '%s' must be either a signal demodulated photodiode, a qnoised or a qshot detector\n", command_string, output_name); int i; for(i=0; i< inter.num_transfer_funcs; i++){ if(strcmp(transfer, inter.tf_list[i].name) == 0){ fb->tf = &inter.tf_list[i]; break; } } inter.num_slinks++; } void read_force_out(const char* command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char det_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char motion_name[MAX_TOKEN_LEN] = {0}; char rest[MAX_TOKEN_LEN] = {0}; output_data_t *out = &inter.output_data_list[inter.num_outputs]; force_out_t *fd = &inter.force_out_list[inter.num_force_out]; int n = sscanf(command_string, "%s %s %s %s %[^\n]", command_name, det_name, component_name, motion_name, rest); if(n != 4) { gerror("Line `%s':\nfd usage is 'fd name component motion'\n", command_string); } else { check_name(command_string, det_name); strcpy(out->name, det_name); fd->comp_index = get_component_index_from_name(component_name); fd->comp_type = get_component_type_decriment_index(&(fd->comp_index)); if(fd->comp_type == NOT_FOUND){ gerror("Line `%s':\nComponent '%s' does not exist\n", command_string, component_name); } else if(fd->comp_type == MIRROR){ mirror_t *m = &inter.mirror_list[fd->comp_index]; fd->motion_index = motion_string_to_index(motion_name, m->mass, m->Ix, m->Iy, m->num_surface_motions); } else if(fd->comp_type == BEAMSPLITTER){ beamsplitter_t *bs = &inter.bs_list[fd->comp_index]; fd->motion_index = motion_string_to_index(motion_name, bs->mass, bs->Ix, bs->Iy, 0); } else gerror("Line `%s':\nfd can only be used on mirrors and beamsplitters\n", command_string); if(fd->motion_index == NOT_FOUND) gerror("Line `%s':\nmotion '%s' does not exist for component %s\n", command_string, motion_name, component_name); } out->detector_index = inter.num_force_out; out->detector_type = FORCERP; out->output_type = COMPLEX; inter.num_outputs++; inter.num_force_out++; } void read_openloopTF_out(const char* command_string){ char command_name[MAX_TOKEN_LEN] = {0}; char det_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char motion_name[MAX_TOKEN_LEN] = {0}; char rest[MAX_TOKEN_LEN] = {0}; output_data_t *out = &inter.output_data_list[inter.num_outputs]; openloopgain_out_t *olg = &inter.openloopgain_list[inter.num_openloopgains]; int n = sscanf(command_string, "%s %s %s %s %[^\n]", command_name, det_name, component_name, motion_name, rest); if(n != 4) { gerror("Line `%s':\npgaind usage is 'pgaind name component motion'\n", command_string); } else { check_name(command_string, det_name); strcpy(out->name, det_name); olg->comp_index = get_component_index_from_name(component_name); olg->comp_type = get_component_type_decriment_index(&(olg->comp_index)); if(olg->comp_type == NOT_FOUND){ gerror("Line `%s':\nComponent '%s' does not exist\n", command_string, component_name); } else if(olg->comp_type == MIRROR){ mirror_t *m = &inter.mirror_list[olg->comp_index]; olg->motion_index = motion_string_to_index(motion_name, m->mass, m->Ix, m->Iy, m->num_surface_motions); } else if(olg->comp_type == BEAMSPLITTER){ beamsplitter_t *bs = &inter.bs_list[olg->comp_index]; olg->motion_index = motion_string_to_index(motion_name, bs->mass, bs->Ix, bs->Iy, 0); } else gerror("Line `%s':\npgaind can only be used on mirrors and beamsplitters\n", command_string); if(olg->motion_index == NOT_FOUND) gerror("Line `%s':\nmotion '%s' does not exist for component %s\n", command_string, motion_name, component_name); } out->detector_index = inter.num_openloopgains; out->detector_type = RGAIN; out->output_type = REAL; inter.num_outputs++; inter.num_openloopgains++; } void read_block(const char* command_string){ char command_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char f_block[MAX_TOKEN_LEN] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char rest[MAX_TOKEN_LEN] = {0}; int n = sscanf(command_string, "%s %s %s %s %s %[^\n]", command_name, component_name, f_block, node1_name, node2_name, rest); if(n == 5){ block_t *block = &inter.block_list[inter.num_blocks]; check_name(command_string, component_name); strcpy(block->name, component_name); block->node1_index = update_node_index_for(node1_name, IN_OUT); block->node2_index = update_node_index_for(node2_name, OUT_IN); connect_component_to_node(block->node1_index, (void*)block, BLOCK); connect_component_to_node(block->node2_index, (void*)block, BLOCK); if(atod(f_block, &(block->f_block_hz))) gerror("Line `%s':\nCould not parse frequency into a number\n", command_string); inter.num_blocks++; inter.num_components++; } else gerror("Line `%s':\nblock usage is 'block name f n1 n2'\n", command_string); } void read_QF_mech_transfer_function(const char *command_string){ char command_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char gain[MAX_TOKEN_LEN] = {0}; char phase[MAX_TOKEN_LEN] = {0}; char rest[MAX_TOKEN_LEN] = {0}; int n = sscanf(command_string, "%s %s %s %s %[^\n]",command_name, component_name, gain, phase, rest); if(n != 4 && n != 5) gerror("Line `%s':\ntf usage is 'tf name factor phase [p/z f1 Q1 [p/z f2 Q2 [p/z f3 Q3 ...]]]'\n", command_string); transfer_func_t *mtf = &inter.tf_list[inter.num_transfer_funcs]; mtf->type = Q_F_TF; check_name(command_string, component_name); strcpy(mtf->name, component_name); char tmp[MAX_TOKEN_LEN] = {0}; char pz[MAX_TOKEN_LEN] = {0}; char Q_str[MAX_TOKEN_LEN] = {0}; char f_str[MAX_TOKEN_LEN] = {0}; if(atod(gain, &(mtf->gain))) gerror("Line `%s':\ncould not process gain value provided\n", command_string); if(atod(phase, &(mtf->phase))) gerror("Line `%s':\ncould not process phase value provided\n", command_string); if(n > 4){ do{ strcpy(tmp, rest); n = sscanf(tmp, "%s %s %s %[^\n]", pz, f_str, Q_str, rest); if(n==0){ break; // nothing to process } if(n == 1 || n == 2) { gerror("Line `%s':\nCould not process one of the pole/zero, Q, frequency triplet\n", command_string); } else { Q_freq_pair_t *Q_f = NULL; if(strcmp("p",pz) == 0){ if(mtf->num_poles >= MAX_POLES_ZEROS) gerror("Line `%s':\nExceeded maximum number of poles (%i)\n",command_string, MAX_POLES_ZEROS); Q_f = &(mtf->pole_Q_f[mtf->num_poles]); mtf->num_poles++; } else if(strcmp("z",pz) == 0){ if(mtf->num_poles >= MAX_POLES_ZEROS) gerror("Line `%s':\nExceeded maximum number of zeros (%i)\n", command_string,MAX_POLES_ZEROS); Q_f = &(mtf->zero_Q_f[mtf->num_zeros]); mtf->num_zeros++; } else gerror("Line `%s':\nyou must specify either `p` or `z` for a pole or zero\n", command_string); if(atod(Q_str, &(Q_f->Q))) gerror("Line `%s':\n`%s` as a Q value was not a valid Q factor\n", command_string, Q_str); if(Q_f->Q <= 0) gerror("Line `%s':\n Q factor must greater than 0 and positive\n", command_string, Q_f->f); if(atod(f_str, &(Q_f->f))) gerror("Line `%s':\n`%s' as a f value was not a valid frequency\n", command_string, f_str); if(Q_f->f <= 0) gerror("Line `%s':\n Frequencies must be greater than 0 and positive\n", command_string, Q_f->f); } }while(n > 3); } mtf->index = inter.num_transfer_funcs; inter.num_transfer_funcs++; } void read_mismatches_command(const char *command_string){ char command_name[MAX_TOKEN_LEN] = {0}; char limit[MAX_TOKEN_LEN] = {0}; char flag[MAX_TOKEN_LEN] = {0}; char rest[MAX_TOKEN_LEN] = {0}; int n = sscanf(command_string, "%s %s %s %[^\n]", command_name, limit, flag, rest); if(n > 1){ atod(limit, &inter.mismatches_lower); if (inter.mismatches_lower < 0 || inter.mismatches_lower > 1){ gerror("Line `%s':\nLimit must be between 0 and 1\n", command_string); } } if(n > 2){ inter.mismatches_options = atoi(flag); } inter.mismatches = 1; } void read_frequency_command(const char *command_string){ char command_name[MAX_TOKEN_LEN] = {0}; char flag[MAX_TOKEN_LEN] = {0}; char rest[MAX_TOKEN_LEN] = {0}; int n = sscanf(command_string, "%s %s %[^\n]", command_name, flag, rest); if(n > 1){ inter.frequency_flag = atoi(flag); } else inter.frequency_flag = 1; } void read_general_mech_transfer_function(const char *command_string){ char command_name[LINE_LEN] = {0}; char component_name[LINE_LEN] = {0}; char gain[LINE_LEN] = {0}; char phase[LINE_LEN] = {0}; char poles[LINE_LEN] = {0}; char zeros[LINE_LEN] = {0}; char rest[LINE_LEN] = {0}; int n = sscanf(command_string, "%s %s %s %s %s %s %[^\n]",command_name, component_name, gain, phase, poles, zeros, rest); //[%[^]]] if(n < 4 || n > 6){ gerror("Line `%s':\ntf2 usage is `tf2 name factor phase {p1,p2,...} {z1,z2,...}'\n" "\nFormat for each pole (p) or zero (z) must be a complex number `+-real+-imagi'\n" "no whitespace and both real and imag must be stated even if 0. Each complex number\n" "should be comma separated. Maximum number of poles and zeros per {} is %i\n" "e.g. tf2 pendulum 1 0 {1+100i,1-100i} {-3+10i,-3-10i}\n", command_string, MAX_POLES_ZEROS); } transfer_func_t *mtf = &inter.tf_list[inter.num_transfer_funcs]; mtf->type = GENERAL_TF; check_name(command_string, component_name); strcpy(mtf->name, component_name); // get inner poles and zeros char tmp[MAX_TOKEN_LEN]; char *a = NULL; if(atod(gain, &(mtf->gain))) gerror("Line `%s':\ncould not process gain value provided\n", command_string); if(atod(phase, &(mtf->phase))) gerror("Line `%s':\ncould not process phase value provided\n", command_string); n = sscanf(poles, "{%[^}]", tmp); if(n > 0){ a = strtok(tmp, ","); while(a != NULL){ if(mtf->num_poles >= MAX_POLES_ZEROS) { gerror("Line `%s' : Exceeded maximum number of poles (%i)\n", command_string, MAX_POLES_ZEROS); } n = sscanf(a, "%lf%lfi", &(mtf->poles[mtf->num_poles].re), &(mtf->poles[mtf->num_poles].im)); mtf->poles[mtf->num_poles+1].re = mtf->poles[mtf->num_poles].re; mtf->poles[mtf->num_poles+1].im = -mtf->poles[mtf->num_poles].im; if(n != 2) { gerror("Line `%s' : could not process pole value `%s'. Format must be `+-[real]+-[imag]i' no whitespace and both real and imag must be stated even if 0\n", command_string, a); } a = strtok(NULL, ","); mtf->num_poles += 2; } } n = sscanf(zeros, "{%[^}]", tmp); if(n > 0){ a = strtok(tmp, ","); while(a != NULL){ if(mtf->num_zeros >= MAX_POLES_ZEROS) { gerror("Line `%s': Exceeded maximum number of zeros (%i)\n", command_string, MAX_POLES_ZEROS); } n = sscanf(a, "%lf%lfi", &(mtf->zeros[mtf->num_zeros].re), &(mtf->zeros[mtf->num_zeros].im)); mtf->zeros[mtf->num_zeros+1].re = mtf->zeros[mtf->num_zeros].re; mtf->zeros[mtf->num_zeros+1].im = -mtf->zeros[mtf->num_zeros].im; if(n != 2) { gerror("Line `%s': could not process zeros value `%s`. Format must be `+-[real]+-[imag]i` no whitespace and both real and imag must be stated \n", command_string, a); } a = strtok(NULL, ","); mtf->num_zeros += 2; } } mtf->index = inter.num_transfer_funcs; inter.num_transfer_funcs++; } /** * Processes the command `mf` for manually adding frequencies into the * simulation. * * @param command_string input string from kat file */ void read_manual_frequency(const char *command_string, int mem_count){ char command_name[MAX_TOKEN_LEN] = {0}; char curr_f[MAX_TOKEN_LEN] = {0}; char tmp[MAX_TOKEN_LEN] = {0}; char rest_f[MAX_TOKEN_LEN] = {0}; int n = sscanf(command_string, "%s %[^\n]", command_name, rest_f); if(n == 1) gerror("Line `%s': No manual frequencies were defined\n", command_string); do{ strcpy(tmp, rest_f); n = sscanf(tmp, "%s %[^\n]", curr_f, rest_f); double f; if(atod(curr_f, &f)) gerror("Could not parse manual frequency `%s`\n", curr_f); if(mem_count) { mem.num_frequencies++; } else{ char fname[MAX_TOKEN_LEN] = {0}; sprintf(fname, "fadd_%s", curr_f); add_user_frequency(fname, f); } } while(n > 1); } //! Read a constant parameter (the 'const' command) /*! * \param command_string the input command string */ void read_const(const char *command_string) { char temp_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char constant_name[MAX_TOKEN_LEN] = {0}; char constant_value[LINE_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; lastparam = -1; // read the command string int num_vars_read = sscanf(command_string, "%s %s %s %80s", command_name, constant_name, constant_value, rest_string); int num_vars_expected = 3; // check that command string was read correctly if (num_vars_read < num_vars_expected) { gerror("line '%s':\nexpected 'const name value'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("line '%s':\ntext '%s' ignored\n", command_string, rest_string); } // check that we aren't exceeding the prescanned number of constants if (inter.num_constants >= mem.num_constants) { gerror("line '%s':\ntoo many constants\n", command_string); } // add a space at the end of the constant name strcpy(temp_name, constant_name); strcat(temp_name, " "); // look for the constant name in current list of constants, barf if is // already defined int i; for (i = 0; i < inter.num_constants; i++) { if (strcmp(temp_name, inter.constant_list[i].name + 1) == 0) { gerror("line '%s':\nconstant '%s' already used.\n", command_string, constant_name); } } // if the constant name contains a '$', barf char *dollar_search_1 = strchr(constant_name, '$'); char *dollar_search_2 = strchr(constant_value, '$'); if (dollar_search_1 != NULL || dollar_search_2 != NULL) { gerror("must not use '$' in name or value of a constant.\n", command_string); } // assign the parameters of the constant object's structure constant_t *constant; constant = &(inter.constant_list[inter.num_constants]); constant->name[0] = '$'; strcat(constant_name, " "); strcpy(constant->name + 1, constant_name); constant->name_len = strlen(constant_name); strcpy(constant->value, constant_value); constant->value_len = strlen(constant_value); ++inter.num_constants; } //! Read a mirror /*! * \param command_string the input command string * \param mode the mode with which to read the command string * * mode can be 0, 1 or 2 * - 0: format = m name R T phi node1 node2 * - 1: format = m name T L phi node1 node2 * - 2: format = m name R L phi node1 node2 * * \todo refactor routine for readability * * \todo TRANSMITTANCE_LOSS and REFLECTANCE_LOSS branches untested */ void read_mirror(const char *command_string, int mode) { debug_msg("read_mirror()\n"); // sanity check arguments assert(mode == REFLECTANCE_TRANSMITTANCE || mode == TRANSMITTANCE_LOSS || mode == REFLECTANCE_LOSS); // read the command string // format: m name R T phi node1 node2 char object_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char sval1[LINE_LEN] = {0}; char sval2[LINE_LEN] = {0}; char tuning_string[LINE_LEN] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char r_aperture[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %s %s %80s", command_name, object_name, sval1, sval2, tuning_string, node1_name, node2_name, r_aperture, rest_string); int num_vars_expected = 7; // validate command string double tuning_value; if (num_vars_read < num_vars_expected) { switch (mode) { case REFLECTANCE_TRANSMITTANCE: gerror("line '%s':\nexpected 'm name R T phi node1 node2'\n", command_string); break; case TRANSMITTANCE_LOSS: gerror("line '%s':\nexpected 'm1 name T L phi node1 node2'\n", command_string); break; case REFLECTANCE_LOSS: gerror("line '%s':\nexpected 'm2 name R L phi node1 node2'\n", command_string); break; default: bug_error("incorrect mode"); } } else if (num_vars_read > num_vars_expected ) { warn("line '%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_mirrors >= mem.num_mirrors) { gerror("line '%s':\ntoo many mirrors\n", command_string); } // assign the mirror attributes settable via the kat command mirror_t *mirror; mirror = &(inter.mirror_list[inter.num_mirrors]); check_name(command_string, object_name); strcpy(mirror->name, object_name); double reflectance; double transmittance; double loss; switch (mode) { case REFLECTANCE_TRANSMITTANCE: // read and validate the reflectance and transmittance values if (atod(sval1, &reflectance) != 0) { gerror("line '%s':\ncould not read reflectance value in input\n", command_string); } if (atod(sval2, &transmittance) != 0) { gerror("line '%s':\ncould not read transmittance value in input\n", command_string); } // set the transmissivity, reflectivity and loss of the mirror mirror->R = reflectance; mirror->T = transmittance; break; case TRANSMITTANCE_LOSS: // read and validate the transmittance and loss values if (atod(sval1, &transmittance) != 0) { gerror("line '%s':\ncould not read transmittance value in input\n", command_string); } if (atod(sval2, &loss) != 0) { gerror("line '%s':\ncould not read loss value in input\n", command_string); } // set the transmissivity, reflectivity and loss of the mirror mirror->T = transmittance; mirror->R = 1.0 - mirror->T - loss; assert(mirror->R >= 0.0); // check to make sure the reflectivity >= 0 // reset the reflectivity as is done in read_beamsplitter() if (mirror->R < 0.0) { mirror->R = 0.0; } break; case REFLECTANCE_LOSS: // read and validate the reflectance and loss values if (atod(sval1, &reflectance) != 0) { gerror("line '%s':\ncould not read reflectance value in input\n", command_string); } if (atod(sval2, &loss) != 0) { gerror("line '%s':\ncould not read loss value in input\n", command_string); } // set the transmissivity, reflectivity and loss of the mirror mirror->R = reflectance; mirror->T = 1.0 - mirror->R - loss; assert(mirror->T >= 0.0); // check to make sure the transmissivity >= 0 // reset the transmittance if is less than zero if (mirror->T < 0.0) { mirror->T = 0.0; } break; default: bug_error("incorrect mode"); } // set the tuning value of the mirror if (atod(tuning_string, &tuning_value) != 0) { gerror("line '%s':\ncould not read tuning (phi) value in input\n",command_string); } mirror->r_aperture = 0; mirror->phi = tuning_value; // assign the mirror attributes settable via the kat command // grab the node indices mirror->node1_index = update_node_index_for(node1_name, IN_OUT); mirror->node2_index = update_node_index_for(node2_name, OUT_IN); connect_component_to_node(mirror->node1_index, (void*)mirror, MIRROR); connect_component_to_node(mirror->node2_index, (void*)mirror, MIRROR); // calculate the reduced node indices from the node indices mirror->node1_reduced_index = get_reduced_index_for(mirror->node1_index); mirror->node2_reduced_index = get_reduced_index_for(mirror->node2_index); mirror->mass = 0; mirror->Rcx = 0; mirror->Rcy = 0; mirror->beta_x = 0; mirror->beta_y = 0; mirror->rebuild = 0; mirror->attribs = 0; mirror->num_maps = 0; // default setting for knm ordering mirror->knm_order[0] = DEFAULT_KNM_ORDER_FIRST; mirror->knm_order[1] = DEFAULT_KNM_ORDER_SECOND; mirror->knm_order[2] = DEFAULT_KNM_ORDER_THIRD; mirror->knm_order[3] = DEFAULT_KNM_ORDER_FOURTH; // default to changing n and q over the bayer-helms computation mirror->knm_change_q = DEFAULT_KNM_CHANGE_Q; mirror->knm_force_saved = 0; // default to integrating aperture until analytic version put in mirror->knm_flags |= INT_APERTURE; ++inter.num_mirrors; ++inter.num_components; check_mirror(mirror); } //! Another version of reading in a mirror /*! * Now redundant, will remain in the code for backwards * compatibility. * * \param command_string the input command string * * \todo refactor routine for readability */ void read_mirror2(const char *command_string) { warn("The m* and mirror* commands have been depreciated. Please use the other m/mirror command.\n"); char object_name[MAX_TOKEN_LEN] = {0}; char sval1[LINE_LEN] = {0}; char sval2[LINE_LEN] = {0}; char tuning_string[LINE_LEN] = {0}; double val1 = 0.0; double val2 = 0.0; char command_name[MAX_TOKEN_LEN] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %s %80s", command_name, object_name, sval1, sval2, tuning_string, node1_name, node2_name, rest_string); int num_vars_expected = 7; double tuning_value = 0.0; if (num_vars_read < num_vars_expected || atod(sval1, &val1) || atod(sval2, &val2) || atod(tuning_string, &tuning_value)) { gerror("line '%s':\nexpected 'm* name T Loss phi node1 node2'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("line '%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_mirrors >= mem.num_mirrors) { gerror("line '%s':\ntoo many mirrors\n", command_string); } // assign the various mirror parameters set in the m/mirror kat command mirror_t *mirror; mirror = &(inter.mirror_list[inter.num_mirrors]); check_name(command_string, object_name); strcpy(mirror->name, object_name); mirror->T = val1 * 1.0e-6; mirror->R = 1.0 - mirror->T - val2 * 1.0e-6; if (mirror->R < 0.0) { mirror->R = 0.0; } mirror->phi = tuning_value; // grab the node indices mirror->node1_index = update_node_index_for(node1_name, IN_OUT); mirror->node2_index = update_node_index_for(node2_name, OUT_IN); connect_component_to_node(mirror->node1_index, (void*)mirror, MIRROR); connect_component_to_node(mirror->node2_index, (void*)mirror, MIRROR); // calculate the reduced indices from the node indices mirror->node1_reduced_index = get_reduced_index_for(mirror->node1_index); mirror->node2_reduced_index = get_reduced_index_for(mirror->node2_index); // assign the mirror attributes not set via the m/mirror kat command mirror->mass = 0; mirror->Rcx = 0; mirror->Rcy = 0; mirror->beta_x = 0; mirror->beta_y = 0; mirror->rebuild = 0; mirror->attribs = 0; mirror->num_maps = 0; // default setting for knm ordering mirror->knm_order[0] = DEFAULT_KNM_ORDER_FIRST; mirror->knm_order[1] = DEFAULT_KNM_ORDER_SECOND; mirror->knm_order[2] = DEFAULT_KNM_ORDER_THIRD; mirror->knm_order[3] = DEFAULT_KNM_ORDER_FOURTH; mirror->x_off = 0.0; mirror->y_off = 0.0; // default to changing q over the bayer-helms computation mirror->knm_change_q = DEFAULT_KNM_CHANGE_Q; mirror->knm_force_saved = 0; // default to integrating aperture until analytic version put in mirror->knm_flags |= INT_APERTURE; ++inter.num_mirrors; ++inter.num_components; check_mirror(mirror); } //! Read a beam splitter /*! * \param command_string the input command string * \param mode the mode of the beam splitter command string * * mode can be 0, 1, or 2. * - 0: format = bs name R T phi alpha node1 node2 node3 node4 * - 1: format = bs name T L phi alpha node1 node2 node3 node4 * - 2: format = bs name R L phi alpha node1 node2 node3 node4 * * \todo refactor routine for readability * * \todo TRANSMITTANCE_LOSS and REFLECTANCE_LOSS branches untested */ void read_beamsplitter(const char *command_string, int mode) { char object_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char sval1[LINE_LEN] = {0}; char sval2[LINE_LEN] = {0}; //! \todo document sval1 values which change potentially char tuning_string[LINE_LEN] = {0}; char incidence_angle_string[LINE_LEN] = {0}; double val1 = 0.0; double val2 = 0.0; double incidence_angle = 0.0; double tuning_value = 0.0; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char node3_name[MAX_TOKEN_LEN] = {0}; char node4_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; // mode can be either 0, 1 or 2 assert(mode == REFLECTANCE_TRANSMITTANCE || mode == TRANSMITTANCE_LOSS || mode == REFLECTANCE_LOSS); // validate command string int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %s %s %s %s %80s", command_name, object_name, sval1, sval2, tuning_string, incidence_angle_string, node1_name, node2_name, node3_name, node4_name, rest_string); int num_vars_expected = 10; if (num_vars_read < num_vars_expected || atod(sval1, &val1) || atod(sval2, &val2) || atod(tuning_string, &tuning_value) || atod(incidence_angle_string, &incidence_angle)) { switch (mode) { case REFLECTANCE_TRANSMITTANCE: gerror("Line `%s':\n" "expected 'bs name R T phi alpha node1 node2 node3 node4'\n", command_string); case TRANSMITTANCE_LOSS: gerror("Line `%s':\n" "expected 'bs1 name T L phi alpha node1 node2 node3 node4'\n", command_string); case REFLECTANCE_LOSS: gerror("Line `%s':\n" "expected 'bs2 name R L phi alpha node1 node2 node3 node4'\n", command_string); default: bug_error("incorrect mode"); } } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_beamsplitters >= mem.num_beamsplitters) { gerror("Line `%s':\ntoo many beamsplitters\n", command_string); } // set attributes which are set by the bs/beamsplitter kat command beamsplitter_t *bs; bs = &(inter.bs_list[inter.num_beamsplitters]); check_name(command_string, object_name); strcpy(bs->name, object_name); switch (mode) { case REFLECTANCE_TRANSMITTANCE: bs->R = val1; bs->T = val2; break; case TRANSMITTANCE_LOSS: bs->T = val1; bs->R = 1.0 - bs->T - val2; break; case REFLECTANCE_LOSS: bs->R = val1; bs->T = 1.0 - bs->R - val2; break; default: bug_error("incorrect mode"); } bs->phi = tuning_value; bs->alpha_1 = incidence_angle; // angle of incidence // grab the node indices bs->node1_index = update_node_index_for(node1_name, IN_OUT); bs->node2_index = update_node_index_for(node2_name, IN_OUT); bs->node3_index = update_node_index_for(node3_name, IN_OUT); bs->node4_index = update_node_index_for(node4_name, IN_OUT); connect_component_to_node(bs->node1_index, (void*)bs, BEAMSPLITTER); connect_component_to_node(bs->node2_index, (void*)bs, BEAMSPLITTER); connect_component_to_node(bs->node3_index, (void*)bs, BEAMSPLITTER); connect_component_to_node(bs->node4_index, (void*)bs, BEAMSPLITTER); // calculate the reduced indices from the node indices bs->node1_reduced_index = get_reduced_index_for(bs->node1_index); bs->node2_reduced_index = get_reduced_index_for(bs->node2_index); bs->node3_reduced_index = get_reduced_index_for(bs->node3_index); bs->node4_reduced_index = get_reduced_index_for(bs->node4_index); // set attributes *not* set by the bs/beamsplitter kat command bs->mass = 0; bs->Rcx = 0; bs->Rcy = 0; bs->beta_x = 0; // misalignment angle bs->beta_y = 0; // misalignment angle bs->rebuild = 0; bs->attribs = 0; // default setting for knm ordering bs->knm_order[0] = DEFAULT_KNM_ORDER_FIRST; bs->knm_order[1] = DEFAULT_KNM_ORDER_SECOND; bs->knm_order[2] = DEFAULT_KNM_ORDER_THIRD; bs->knm_order[3] = DEFAULT_KNM_ORDER_FOURTH; bs->knm_change_q = DEFAULT_KNM_CHANGE_Q; // default to integrating aperture until analytic version put in bs->knm_flags |= INT_APERTURE; ++inter.num_beamsplitters; ++inter.num_components; check_beamsplitter(bs); } //! Another version of reading a beamsplitter (???) /*! * Now redundant, can be removed after some more testing of read_beamsplitter * * \param command_string the input command string */ void read_beamsplitter2(const char *command_string) { char object_name[MAX_TOKEN_LEN] = {0}; char transmittance_string[LINE_LEN] = {0}; char loss_string[LINE_LEN] = {0}; char tuning_string[LINE_LEN] = {0}; char incidence_angle_string[LINE_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char node3_name[MAX_TOKEN_LEN] = {0}; char node4_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; // validate command string int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %s %s %s %s %80s", command_name, object_name, transmittance_string, loss_string, tuning_string, incidence_angle_string, node1_name, node2_name, node3_name, node4_name, rest_string); int num_vars_expected = 10; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\n" "expected 'bs* name T Loss phi alpha node1 node2 node3 node4'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_beamsplitters >= mem.num_beamsplitters) { gerror("Line `%s':\ntoo many beamsplitters\n", command_string); } beamsplitter_t *bs; bs = &(inter.bs_list[inter.num_beamsplitters]); // set attributes which are set by the bs/beamsplitter kat command check_name(command_string, object_name); strcpy(bs->name, object_name); double transmittance; if (atod(transmittance_string, &transmittance)) { gerror("Line `%s':\nUnable to read transmittance\n"); } else { bs->T = transmittance * 1.0e-6; } double loss; if (atod(loss_string, &loss)) { gerror("Line `%s':\nUnable to read loss\n"); } else { bs->R = 1.0 - bs->T - loss * 1.0e-6; } if (bs->R < 0.0) { bs->R = 0.0; } double tuning; if (atod(tuning_string, &tuning)) { gerror("Line `%s':\nUnable to read tuning value\n"); } else { bs->phi = tuning; } double incidence_angle; if (atod(incidence_angle_string, &incidence_angle)) { gerror("Line `%s':\nUnable to read incidence angle\n"); } else { bs->alpha_1 = incidence_angle; } // grab the node indices bs->node1_index = update_node_index_for(node1_name, IN_OUT); bs->node2_index = update_node_index_for(node2_name, IN_OUT); bs->node3_index = update_node_index_for(node3_name, IN_OUT); bs->node4_index = update_node_index_for(node4_name, IN_OUT); connect_component_to_node(bs->node1_index, (void*)bs, BEAMSPLITTER); connect_component_to_node(bs->node2_index, (void*)bs, BEAMSPLITTER); connect_component_to_node(bs->node3_index, (void*)bs, BEAMSPLITTER); connect_component_to_node(bs->node4_index, (void*)bs, BEAMSPLITTER); // calculate the reduced indices from the node indices bs->node1_reduced_index = get_reduced_index_for(bs->node1_index); bs->node2_reduced_index = get_reduced_index_for(bs->node2_index); bs->node3_reduced_index = get_reduced_index_for(bs->node3_index); bs->node4_reduced_index = get_reduced_index_for(bs->node4_index); // set attributes *not* set by the bs/beamsplitter kat command bs->mass = 0; bs->Rcx = 0; bs->Rcy = 0; bs->beta_x = 0; bs->beta_y = 0; bs->rebuild = 0; bs->attribs = 0; bs->knm_order[0] = DEFAULT_KNM_ORDER_FIRST; bs->knm_order[1] = DEFAULT_KNM_ORDER_SECOND; bs->knm_order[2] = DEFAULT_KNM_ORDER_THIRD; bs->knm_order[3] = DEFAULT_KNM_ORDER_FOURTH; bs->knm_change_q = DEFAULT_KNM_CHANGE_Q; // default to integrating aperture until analytic version put in bs->knm_flags |= INT_APERTURE; ++inter.num_beamsplitters; ++inter.num_components; check_beamsplitter(bs); } //! Read in some free space /*! * \param command_string the input command string */ void read_sagnac(const char *command_string) { char object_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char dphi_string[LINE_LEN] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; sagnac_t *sagnac; debug_msg("read_sagnac()\n"); sagnac = &(inter.sagnac_list[inter.num_sagnacs]); int num_vars_read = sscanf(command_string, "%s %s %s %s %s %80s", command_name, object_name, dphi_string, node1_name, node2_name, rest_string); int num_vars_expected = 5; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'sagnac name dphi node1 node2'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_sagnacs >= mem.num_sagnacs) { gerror("Line `%s':\ntoo many sagnacs\n", command_string); } double dphi; if (atod(dphi_string, &dphi)) { gerror("Line `%s':\nunable to read refractive index\n", command_string); } else { sagnac->dphi = dphi; } check_name(command_string, object_name); strcpy(sagnac->name, object_name); // assign the node indices sagnac->node1_index = update_node_index_for(node1_name, IN_OUT); sagnac->node2_index = update_node_index_for(node2_name, OUT_IN); connect_component_to_node(sagnac->node1_index, (void*)sagnac, SAGNAC); connect_component_to_node(sagnac->node2_index, (void*)sagnac, SAGNAC); // calculate the reduced node indices from the node indices sagnac->node1_reduced_index = get_reduced_index_for(sagnac->node1_index); sagnac->node2_reduced_index = get_reduced_index_for(sagnac->node2_index); ++inter.num_sagnacs; ++inter.num_components; check_sagnac(sagnac); } //! Read in some free space /*! * \param command_string the input command string */ void read_space(const char *command_string) { char object_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char length_string[LINE_LEN] = {0}; char refractive_index_string[LINE_LEN] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; space_t *space; debug_msg("read_space()\n"); space = &(inter.space_list[inter.num_spaces]); space->n = init.n0; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %80s", command_name, object_name, length_string, refractive_index_string, node1_name, node2_name, rest_string); int num_vars_expected = 6; if (num_vars_read < num_vars_expected) { num_vars_read = sscanf(command_string, "%s %s %s %s %s %80s", command_name, object_name, length_string, node1_name, node2_name, rest_string); int num_vars_expected = 5; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 's name L [n] node1 node2'\n", command_string); } else { if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } } else { double refractive_index; if (atod(refractive_index_string, &refractive_index)) { gerror("Line `%s':\nunable to read refractive index\n", command_string); } else { space->n = refractive_index; } if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } if (inter.num_spaces >= mem.num_spaces) { gerror("Line `%s':\ntoo many spaces\n", command_string); } check_name(command_string, object_name); strcpy(space->name, object_name); // check the length is read correctly double length; if (atod(length_string, &length)) { gerror("Line `%s':\nunable to read length of space\n", command_string); } else { space->L = length; } // assign the node indices // set direction to be either or as a space can connect to out_in or in_out // nodes space->node1_index = update_node_index_for(node1_name, EITHER_DIR); space->node2_index = update_node_index_for(node2_name, EITHER_DIR); connect_component_to_node(space->node1_index, (void*)space, SPACE); connect_component_to_node(space->node2_index, (void*)space, SPACE); // calculate the reduced node indices from the node indices space->node1_reduced_index = get_reduced_index_for(space->node1_index); space->node2_reduced_index = get_reduced_index_for(space->node2_index); space->rebuild = 0; space->attribs = 0; space->gouy_x = 0.0; space->gouy_y = 0.0; ++inter.num_spaces; ++inter.num_components; check_space(space); } //! Read a cavity /*! * \param command_string the input command string */ void read_cavity(const char *command_string) { char object_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char component1[MAX_TOKEN_LEN] = {0}; char component2[MAX_TOKEN_LEN] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; cavity_t *cavity; endcomp = 1; lastparam = -1; cavity = &(inter.cavity_list[inter.num_cavities]); // read and process the command string int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %80s", command_name, object_name, component1, node1_name, component2, node2_name, rest_string); int num_vars_expected = 6; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\n" "expected 'cav name component1 node component2 node'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_cavities >= mem.num_cavities) { gerror("Line `%s':\ntoo many cavities\n", command_string); } // sanity check the cavity name, and set it to the object check_name(command_string, object_name); strcpy(cavity->name, object_name); // set the cavity's node indices cavity->node1_index = get_node_index_for(node1_name); if (cavity->node1_index == NODE_UNUSED) { gerror("Line `%s':\nfirst node does not exist\n", command_string); } node_t node1 = inter.node_list[cavity->node1_index]; if (node1.gnd_node) { gerror("Line `%s':\nfirst node is a dump\n", command_string); } cavity->node2_index = get_node_index_for(node2_name); if (cavity->node2_index == NODE_UNUSED) { gerror("Line `%s':\nsecond node does not exist\n", command_string); } node_t node2 = inter.node_list[cavity->node2_index]; if (node2.gnd_node) { gerror("Line `%s':\nsecond node is a dump\n", command_string); } // set the cavity's component indices cavity->component1_index = get_component_index_from_name(component1); if (cavity->component1_index == NOT_FOUND) { gerror("Line `%s':\nfirst component not found\n", command_string); } cavity->component2_index = get_component_index_from_name(component2); if (cavity->component2_index == NOT_FOUND) { gerror("Line `%s':\nsecond component not found\n", command_string); } cavity->stable = 0; ++inter.num_cavities; check_cavity(cavity); } //! Read a start node /*! * \param command_string the input command string */ void read_startnode(const char *command_string) { char node_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; //gauss_t *gauss; endcomp = 1; lastparam = -1; //gauss = &(inter.gauss_list[inter.num_gauss_cmds]); // read and process the command string int num_vars_read = sscanf(command_string, "%s %s %80s", command_name, node_name, rest_string); int num_vars_expected = 2; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'startnode node\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.startnode_set) { gerror("Line `%s':\nstartnode already defined, use a new one\n", command_string); } // check and set the start node inter.startnode = get_node_index_for(node_name); if (inter.startnode == NODE_UNUSED) { gerror("Line `%s':\nnode does not exist\n", command_string); } node_t node = inter.node_list[inter.startnode]; if (node.gnd_node) { gerror("Line `%s':\nnode is a dump\n", command_string); } inter.startnode_set = 1; } //! Read a Gaussian beam (???) (and why the '2'?) /*! * \param command_string the input command string * * \todo assigning only the x-axis params branch untested */ void read_gauss2(const char *command_string) { char object_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char component[MAX_TOKEN_LEN] = {0}; char z_x_string[LINE_LEN] = {0}; char z_R_x_string[LINE_LEN] = {0}; char z_y_string[LINE_LEN] = {0}; char z_R_y_string[LINE_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; endcomp = 1; lastparam = -1; bool y_is_set = false; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %s %s %80s", command_name, object_name, component, node_name, z_x_string, z_R_x_string, z_y_string, z_R_y_string, rest_string); int num_vars_expected = 8; if (num_vars_read < num_vars_expected) { num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %80s", command_name, object_name, component, node_name, z_x_string, z_R_x_string, rest_string); num_vars_expected = 6; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\n" "expected 'gauss* name component node q [qy]' with q as 'z z_R'\n", command_string); } else { if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } } else { y_is_set = true; if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } if (inter.num_gauss_cmds >= mem.num_gauss_cmds) { gerror("Line `%s':\ntoo many gauss paramters\n", command_string); } gauss_t *gauss; gauss = &(inter.gauss_list[inter.num_gauss_cmds]); check_name(command_string, object_name); strcpy(gauss->name, object_name); gauss->node_index = get_node_index_for(node_name); if (gauss->node_index == NODE_UNUSED) { gerror("Line `%s':\nnode does not exist\n", command_string); } node_t node = inter.node_list[gauss->node_index]; if (node.gnd_node) { gerror("Line `%s':\nnode is a dump\n", command_string); } double nr = init.n0; //nr=*(inter.node_list[gauss->node].n); probably easier and better but ... //##################################################################################### int component_index = get_component_index_from_name(component); gauss->component_index = component_index; if (component_index < 0) { gerror("Line `%s':\ncomponent does not exist\n", command_string); } int component_type = get_component_type_decriment_index(&component_index); if (component_type == SPACE) { nr = inter.space_list[component_index].n; } else { int component_index1, component_index2; which_components(gauss->node_index, &component_index1, &component_index2); /* the different component indices here are performing the same task. * I need to think more carefully about the logic of the enclosing * if/else as there are two (nested) checks as to whether or not the * component type is a space... Leaving the "second" component_index in * its own scope as a safety measure */ int component_index = 0; if (component_index1 == gauss->component_index) { component_index = component_index2; } else { component_index = component_index1; } component_type = get_component_type_decriment_index(&component_index); if (component_type == SPACE) { nr = inter.space_list[component_index].n; } } // read and set the z_x and z_R_x values complex_t qx = complex_0; complex_t qy = complex_0; double z_x = 0.0; double z_R_x = 0.0; if (atod(z_x_string, &z_x)) { gerror("Line `%s':\nUnable to read z_x value\n"); } else { qx.re = z_x; } if (atod(z_R_x_string, &z_R_x)) { gerror("Line `%s':\nUnable to read z_R_x value\n"); } else { qx.im = z_R_x; } gauss->wx0 = w0_size(qx, nr); gauss->qx = qx; // read and set the z_y and z_R_y values if (y_is_set) { double z_y = 0.0; double z_R_y = 0.0; if (atod(z_R_y_string, &z_R_y)) { gerror("Line `%s':\nUnable to read z_R_y value\n"); } else { qy.im = z_R_y; } if (atod(z_y_string, &z_y)) { gerror("Line `%s':\nUnable to read z_y value\n"); } else { qy.re = z_y; } } else { qy.re = z_x; qy.im = z_R_x; } if (qx.im <= 0 || qy.im <= 0) { gerror("Line `%s':\n Rayleigh range must be positive\n", command_string); } gauss->wy0 = w0_size(qy, nr); gauss->qy = qy; ++inter.num_gauss_cmds; check_gauss(gauss); } //! Read a gauss command /*! * \param command_string the input command string */ void read_gauss(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char component[MAX_TOKEN_LEN] = {0}; char w0_x_string[LINE_LEN] = {0}; char z_x_string[LINE_LEN] = {0}; char w0_y_string[LINE_LEN] = {0}; char z_y_string[LINE_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; endcomp = 1; lastparam = -1; bool y_is_set = false; // read and process the command string int num_vars_expected = 8; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %s %s %80s", command_name, object_name, component, node_name, w0_x_string, z_x_string, w0_y_string, z_y_string, rest_string); if (num_vars_read < num_vars_expected) { num_vars_expected = 6; num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %80s", command_name, object_name, component, node_name, w0_x_string, z_x_string, rest_string); if (num_vars_read < num_vars_expected) { gerror("Line `%s':\n" "expected 'gauss name component node w0 z [wy0 zy]'\n", command_string); } else { if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } } else { y_is_set = true; if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } if (inter.num_gauss_cmds >= mem.num_gauss_cmds) { gerror("Line `%s':\ntoo many gauss paramters\n", command_string); } gauss_t *gauss; gauss = &(inter.gauss_list[inter.num_gauss_cmds]); // check and assign the name of the gaussian beam object check_name(command_string, object_name); strcpy(gauss->name, object_name); // process w0x double w0x = 0.0; double w0_x = 0.0; if (atod(w0_x_string, &w0_x)) { gerror("Line `%s':\nunable to read w0 parameter\n", command_string); } else { w0x = w0_x; } // process zx double z_x = 0.0; double zx = 0.0; if (atod(z_x_string, &z_x)) { gerror("Line `%s':\nunable to read z parameter\n", command_string); } else { zx = z_x; } // check and assign the node for the gaussian beam gauss->node_index = get_node_index_for(node_name); if (gauss->node_index == NODE_UNUSED) { gerror("Line `%s':\nnode does not exist\n", command_string); } node_t node = inter.node_list[gauss->node_index]; if (node.gnd_node) { gerror("Line `%s':\nnode is a dump\n", command_string); } double nr = init.n0; int component_index = get_component_index_from_name(component); gauss->component_index = component_index; if (component_index < 0) { gerror("Line `%s':\ncomponent does not exist\n", command_string); } // determine the refractive index correctly int component_type = get_component_type_decriment_index(&component_index); if (component_type == SPACE) { nr = inter.space_list[component_index].n; } else { int component_index; int component_index1, component_index2; which_components(gauss->node_index, &component_index1, &component_index2); if (component_index1 == gauss->component_index) { component_index = component_index2; } else { component_index = component_index1; } component_type = get_component_type_decriment_index(&component_index); if (component_type == SPACE) { nr = inter.space_list[component_index].n; } } // assign the gaussian beam parameters gauss->wx0 = w0x; gauss->qx = q_w0z(w0x, zx, nr); double w0y = 0.0; double zy = 0.0; if (y_is_set) { double w0_y; double z_y; // process w0y if (atod(w0_y_string, &w0_y)) { gerror("Line `%s':\nunable to read w0y parameter\n", command_string); } else { w0y = w0_y; } // process zy if (atod(z_y_string, &z_y)) { gerror("Line `%s':\nunable to read zy parameter\n", command_string); } else { zy = z_y; } } else { w0y = w0_x; zy = z_x; } gauss->wy0 = w0y; gauss->qy = q_w0z(w0y, zy, nr); ++inter.num_gauss_cmds; check_gauss(gauss); } //! Read a gauss command using radius of curvature /*! * \param command_string the input command string */ void read_gaussRc(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char component[MAX_TOKEN_LEN] = {0}; char w_x_string[LINE_LEN] = {0}; char w_y_string[LINE_LEN] = {0}; char Rc_x_string[LINE_LEN] = {0}; char Rc_y_string[LINE_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; endcomp = 1; lastparam = -1; bool y_is_set = false; // read and process the command string int num_vars_expected = 8; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %s %s %80s", command_name, object_name, component, node_name, w_x_string, Rc_x_string, w_y_string, Rc_y_string, rest_string); if (num_vars_read < num_vars_expected) { num_vars_expected = 6; num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %80s", command_name, object_name, component, node_name, w_x_string, Rc_x_string, rest_string); if (num_vars_read < num_vars_expected) { gerror("Line `%s':\n" "expected 'gauss name component node w Rc [wy Rcy]'\n", command_string); } else { if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } } else { y_is_set = true; if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } if (inter.num_gauss_cmds >= mem.num_gauss_cmds) { gerror("Line `%s':\ntoo many gauss paramters\n", command_string); } gauss_t *gauss; gauss = &(inter.gauss_list[inter.num_gauss_cmds]); // check and assign the name of the gaussian beam object check_name(command_string, object_name); strcpy(gauss->name, object_name); // process w0x double wx = 0.0; double w_x = 0.0; if (atod(w_x_string, &w_x)) { gerror("Line `%s':\nunable to read w0 parameter\n", command_string); } else { wx = w_x; } if(wx == 0.0) gerror("Line `%s':\nBeamsize must not be 0\n", command_string); // process zx double Rc_x = 0.0; double Rcx = 0.0; if (atod(Rc_x_string, &Rc_x)) { gerror("Line `%s':\nunable to read Rc parameter\n", command_string); } else { Rcx = Rc_x; } if(Rcx == 0.0) gerror("Line `%s':\nRadius of curvature must not be 0\n", command_string); // check and assign the node for the gaussian beam gauss->node_index = get_node_index_for(node_name); if (gauss->node_index == NODE_UNUSED) { gerror("Line `%s':\nnode does not exist\n", command_string); } node_t node = inter.node_list[gauss->node_index]; if (node.gnd_node) { gerror("Line `%s':\nnode is a dump\n", command_string); } double nr = init.n0; int component_index = get_component_index_from_name(component); gauss->component_index = component_index; if (component_index < 0) { gerror("Line `%s':\ncomponent does not exist\n", command_string); } // determine the refractive index correctly int component_type = get_component_type_decriment_index(&component_index); if (component_type == SPACE) { nr = inter.space_list[component_index].n; } else { int component_index; int component_index1, component_index2; which_components(gauss->node_index, &component_index1, &component_index2); if (component_index1 == gauss->component_index) { component_index = component_index2; } else { component_index = component_index1; } component_type = get_component_type_decriment_index(&component_index); if (component_type == SPACE) { nr = inter.space_list[component_index].n; } } complex_t qinv = co(1/Rcx, -nr*init.lambda/(PI*wx*wx)); complex_t q = inv_complex(qinv); // assign the gaussian beam parameters gauss->wx0 = w0_size(q,nr); gauss->qx = q; double wy = 0.0; double Rcy = 0.0; if (y_is_set) { double w_y; double Rc_y; // process w0y if (atod(w_y_string, &w_y)) { gerror("Line `%s':\nunable to read w0y parameter\n", command_string); } else { wy = w_y; } if(wy == 0.0) gerror("Line `%s':\nBeamsize must not be 0\n", command_string); // process zy if (atod(Rc_y_string, &Rc_y)) { gerror("Line `%s':\nunable to read Rcy parameter\n", command_string); } else { Rcy = Rc_y; } if(Rcy == 0.0) gerror("Line `%s':\nRadius of curvature must not be 0\n", command_string); } else { wy = w_x; Rcy = Rc_x; } qinv = co(1/Rcy, -nr*init.lambda/(PI*wy*wy)); q = inv_complex(qinv); // assign the gaussian beam parameters gauss->wy0 = w0_size(q,nr); gauss->qy = q; ++inter.num_gauss_cmds; check_gauss(gauss); } //! Read a lens /*! * \param command_string the input command string */ void read_lens(const char *command_string, bool alternative) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char focal_power_string[LINE_LEN] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; debug_msg("read_lens()\n"); // process the command string int num_vars_read = sscanf(command_string, "%s %s %s %s %s %80s", command_name, object_name, focal_power_string, node1_name, node2_name, rest_string); int num_vars_expected = 5; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'lens name f node1 node2'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_lenses >= mem.num_lenses) { gerror("Line `%s':\ntoo many lenses\n", command_string); } lens_t *lens; lens = &(inter.lens_list[inter.num_lenses]); check_name(command_string, object_name); strcpy(lens->name, object_name); // read and set the focal_length value double f_or_D; if(alternative){ if (atod(focal_power_string, &f_or_D)) { gerror("Line `%s':\nUnable to read the optical power value\n", command_string); } else { lens->is_focal_length = false; lens->f_of_D = f_or_D; } } else { if (atod(focal_power_string, &f_or_D)) { gerror("Line `%s':\nUnable to read the focal length value\n", command_string); } else { lens->is_focal_length = true; lens->f_of_D = f_or_D; } } // grab the node indices lens->node1_index = update_node_index_for(node1_name, IN_OUT); lens->node2_index = update_node_index_for(node2_name, OUT_IN); connect_component_to_node(lens->node1_index, (void*)lens, LENS); connect_component_to_node(lens->node2_index, (void*)lens, LENS); // calculate the reduced node indices from the node indices lens->node1_reduced_index = get_reduced_index_for(lens->node1_index); lens->node2_reduced_index = get_reduced_index_for(lens->node2_index); lens->rebuild = 0; ++inter.num_lenses; ++inter.num_components; check_lens(lens); } //! Read a TEM mode ??? /*! * \param command_string the input command string */ void read_ltem(const char *command_string, bool inputLG) { char command_name[MAX_TOKEN_LEN] = {0}; char input_name[MAX_TOKEN_LEN] = {0}; char factor_string[LINE_LEN] = {0}; char phase_string[LINE_LEN] = {0}; int n, m; int p, l; char rest_string[REST_STRING_LEN] = {0}; lastparam = -1; // read and process the command string int num_vars_read = sscanf(command_string, "%s %s %d %d %s %s %80s", command_name, input_name, (inputLG) ? &p : &n, (inputLG) ? &l : &m, factor_string, phase_string, rest_string); int num_vars_expected = 6; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'tem input n m factor phase'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } // get and check the component index and the component type int component_index = get_component_index_from_name(input_name); if (component_index == NOT_FOUND) { gerror("Line `%s':\nno such input\n", command_string); } int type = get_component_type_decriment_index(&component_index); if (type != LIGHT_INPUT) { gerror("Line `%s':\ncomponent not an input\n", command_string); } // read and check the factor variable double factor; int error_flag = atod(factor_string, &factor); if (error_flag) { gerror("Line `%s':\nUnable to read factor value\n", command_string); } // read and check the phase variable double phase; error_flag = atod(phase_string, &phase); if (error_flag) { gerror("Line `%s':\nUnable to read phase value\n", command_string); } // if TEM command has been used previously... if(inter.light_in_list[component_index].isTEMSet){ if(inter.light_in_list[component_index].isHGModes && inputLG){ gerror("You cannot mix 'tem' (HG) and 'tem*' (LG) commands"); } } if (inputLG){ if (abs(l) + 2*p > inter.tem) { gerror("Line `%s':\n2p+|l| larger then maximum order for TEM modes\n", command_string); } }else{ if (n+m > inter.tem) { gerror("Line `%s':\nn+m larger then maximum order for TEM modes\n", command_string); } } int field_index; if(inputLG) field_index = get_field_index_from_tem_LG(p, l); else field_index = get_field_index_from_tem(n, m); // Rainer : sqrt 230402 inter.light_in_list[component_index].power_coeff_list[field_index] = z_by_ph(co(sqrt(factor), 0.0), phase); inter.light_in_list[component_index].isTEMSet = true; inter.light_in_list[component_index].isHGModes = !inputLG; } //! Read a detector mask ??? /*! * \param command_string the input command string */ void read_mask(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char detector_name[MAX_TOKEN_LEN] = {0}; char factor_string[LINE_LEN] = {0}; int n, m; char rest_string[REST_STRING_LEN] = {0}; lastparam = -1; int num_vars_read = sscanf(command_string, "%s %s %d %d %s %80s", command_name, detector_name, &n, &m, factor_string, rest_string); int num_vars_expected = 5; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'mask detector n m factor'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } int component_index = get_component_index_from_name(detector_name); if (component_index == NOT_FOUND) { gerror("Line `%s':\nno such detector\n", command_string); } int component_type = get_component_type_decriment_index(&component_index); if (component_type != OUT) { gerror("Line `%s':\ncomponent not a detector\n", command_string); } if (n + m > inter.tem) { gerror("Line `%s':\nn+m larger then maximum order for TEM modes\n", command_string); } int detector_type = inter.output_data_list[component_index].detector_type; if (detector_type != PD0 && detector_type != PD1 && detector_type != SHOT && detector_type != QSHOT && detector_type != BEAM ) { warn("Line `%s':\nmasking this type of detector makes no sense\n", command_string); } double factor; int double_read_failed = atod(factor_string, &factor); if (double_read_failed) { gerror("Line `%s':\nUnable to read detector masking factor\n", command_string); } if (factor < 0 || factor > 1) { gerror("Line `%s':\nfactor must be between 0 and 1\n", command_string); } // get internal mode number int field_index = get_field_index_from_tem(n, m); //if (!inter.light_out_list[i].beam_mask_is_set) // inter.light_out_list[i].c[0]=0.0; light_out_t *detector; detector = &inter.light_out_list[inter.output_data_list[component_index].detector_index]; detector->masking_factor[field_index] = factor; detector->beam_mask_is_set = true; } //! Read the input light beam /*! * \param command_string the input command string */ void read_light_in(const char *command_string) { char object_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char intensity_string[LINE_LEN] = {0}; char frequency_string[LINE_LEN] = {0}; char phase_string[LINE_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; light_in_t *light_in; if (inter.num_light_inputs >= mem.num_light_inputs) { gerror("Line `%s':\ntoo many inputs\n", command_string); } light_in = &(inter.light_in_list[inter.num_light_inputs]); light_in->phase = 0.0; // set the default vacuum noise level for the laser light_in->noise_value = UNIT_VACUUM; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %80s", command_name, object_name, intensity_string, frequency_string, phase_string, node_name, rest_string); int num_vars_expected = 6; if (num_vars_read < num_vars_expected) { num_vars_read = sscanf(command_string, "%s %s %s %s %s %80s", command_name, object_name, intensity_string, frequency_string, node_name, rest_string); num_vars_expected = 5; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'l name I f [phase] node'\n", command_string); } else { if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } } else { if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } double phase; if (atod(phase_string, &phase)) { gerror("Line `%s':\nUnable to read phase\n", command_string); } else { light_in->phase = phase; } } check_name(command_string, object_name); strcpy(light_in->name, object_name); double frequency; if (atod(frequency_string, &frequency)) { //gerror("Line `%s':\nUnable to read frequency\n", command_string); strcpy(light_in->__frequency_name, frequency_string); light_in->f = NULL; light_in->f_entangled_zero = NULL; } else { char fname[LINE_LEN+6] = {0}; sprintf(fname, "%s", light_in->name); add_carrier_frequency(fname, frequency, &light_in->f); } double intensity; if (atod(intensity_string, &intensity)) { gerror("Line `%s':\nUnable to read intensity\n", command_string); } else { light_in->I0 = intensity; } // false as no TEM command has been used to change the mode // content of the laser light_in->isTEMSet = false; // Assume by default modes stored are HG light_in->isHGModes = true; light_in->power_coeff_list[0] = complex_1; int field_index; for (field_index = 1; field_index < mem.num_fields; field_index++) { light_in->power_coeff_list[field_index] = complex_0; } // grab node index light_in->node_index = update_node_index_for(node_name, EITHER_DIR); // make sure the node index is in the correct range: assert(light_in->node_index >= 0); assert(light_in->node_index < inter.num_nodes); // calculate reduced node index from node index light_in->node_reduced_index = get_reduced_index_for(light_in->node_index); // make sure the reduced node index is in the correct range: assert(light_in->node_reduced_index >= 0); assert(light_in->node_reduced_index < inter.num_reduced_nodes); if (get_node_index_for(node_name) == NODE_UNUSED) { gerror("input %s not connected to interferometer.\n", object_name); } inter.node_list[light_in->node_index].io = inter.node_list[light_in->node_index].io | 2; light_in->attribs = 0; ++inter.num_frequencies; ++inter.num_light_inputs; ++inter.num_components; } //! Read the output light command /*! * \param command_string the input command string * * \todo refactor routine for readability */ void read_light_out(const char *command_string) { /*! * \todo num, iadd -> better names * \todo reformat if necessary * \todo read entire command name * \todo some comments in the code would be nice */ endcomp = 1; lastparam = -1; const char *input_cmd_string; input_cmd_string = command_string; int iadd = 0; light_out_t *light_out; light_out = &(inter.light_out_list[inter.num_light_outputs]); // test if the command was 'pd', 'pdS' or 'pdN' if (strncasecmp(command_string, "pdS", 3) == 0) { light_out->sensitivity = ON; iadd = 3; } else { if (strncasecmp(command_string, "pdN", 3) == 0) { light_out->sensitivity = NORM; iadd = 3; } else { light_out->sensitivity = OFF; iadd = 2; } } // get number of demodulations (num_demods) int num_demods = 0; char num_demods_char[2]; num_demods_char[0] = command_string[iadd]; num_demods_char[1] = '\0'; if (NOT isspace((int)(num_demods_char[0]))) { iadd++; if (NOT isdigit((int)(num_demods_char[0]))) { warn("Line `%s':\nignoring wrong keyword, using 0 demodulations\n", input_cmd_string); num_demods = 0; } else { if (my_atoi(num_demods_char, &num_demods)) { bug_error("failed char to integer conversion"); } if (num_demods > MAX_DEMOD) { gerror("Line `%s':\ntoo many demodulations (read %d)\n", input_cmd_string, num_demods); } } } char object_name[MAX_TOKEN_LEN] = {0}; int num_vars_read = sscanf(command_string + iadd, "%s", object_name); if (num_vars_read < 1) { gerror("Line `%s':\n" "expected 'pd[n] name [f1 phi1 [f2 phi2]] node[*]'\n", input_cmd_string); } command_string = strstr(command_string + iadd, object_name) + strlen(object_name) + 1; /* read demodulation frequency and phase (depending on previously determined number of demodulations). */ char frequency_string[LINE_LEN] = {0}; char phase_string[LINE_LEN] = {0}; double demod_frequency; double demod_phase; char rest_string[REST_STRING_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; output_data_t *output_data; output_data = &(inter.output_data_list[inter.num_outputs]); if (num_demods > 0) { int demod_index; for (demod_index = 1; demod_index < num_demods; demod_index++) { num_vars_read = sscanf(command_string, "%s %s", frequency_string, phase_string); if (num_vars_read < 2) { gerror("Line `%s':\n" "expected 'pd[n] name [f1 phi1 [f2 phi2]] node[*]'\n", input_cmd_string); } else { char var_name[LINE_LEN] = {0}; sprintf(var_name, "f%i", demod_index+1); if (parse_frequency_input(frequency_string, &demod_frequency, object_name, var_name)) { gerror("Line `%s':\n" "Unable to read demodulation frequency\n", input_cmd_string); } light_out->f[demod_index] = demod_frequency; if (strncasecmp(phase_string, "max", 3) == 0) { light_out->phi[demod_index] = 0; light_out->demod_phase_mode[demod_index] = MAX_PHASE; } else if (NOT atod(phase_string, &demod_phase)) { light_out->phi[demod_index] = demod_phase; light_out->demod_phase_mode[demod_index] = USER_PHASE; } else { gerror("Line `%s':\n" "Unable to read demodulation phase\n", input_cmd_string); } } command_string = strstr(strstr(command_string, frequency_string) + strlen(frequency_string) + 1, phase_string) + strlen(phase_string) + 1; } num_vars_read = sscanf(command_string, "%s %s %s %80s", frequency_string, phase_string, node_name, rest_string); if (num_vars_read < 3) { num_vars_read = sscanf(command_string, "%s %s %80s", frequency_string, node_name, rest_string); if (num_vars_read < 2) { gerror("Line `%s':\n" "expected 'pd[n] name [f1 phi1 [f2 phi2]] node[*]'\n", input_cmd_string); } else { char var_name[LINE_LEN] = {0}; sprintf(var_name, "f%i", num_demods); if (parse_frequency_input(frequency_string, &demod_frequency, object_name, var_name)) { gerror("Line `%s':\n" "Unable to read demodulation frequency\n", input_cmd_string); } light_out->f[num_demods] = demod_frequency; light_out->phi[num_demods] = 0; output_data->output_type = COMPLEX; light_out->demod_phase_mode[num_demods] = OFF; if (num_vars_read > 2) { warn("Line `%s':\ntext '%s' ignored\n", input_cmd_string, rest_string); } } } else { char var_name[LINE_LEN] = {0}; sprintf(var_name, "f%i", num_demods); if (parse_frequency_input(frequency_string, &demod_frequency, object_name, var_name)) { gerror("Line `%s':\n" "Unable to read demodulation frequency\n", input_cmd_string); } light_out->f[num_demods] = demod_frequency; output_data->output_type = REAL; if (strncasecmp(phase_string, "max", 3) == 0) { light_out->phi[num_demods] = 0; light_out->demod_phase_mode[num_demods] = MAX_PHASE; } else if (NOT atod(phase_string, &demod_phase)) { light_out->phi[num_demods] = demod_phase; light_out->demod_phase_mode[num_demods] = USER_PHASE; } else { gerror("Line `%s':\n" "Unable to read demodulation phase\n", input_cmd_string); } if (num_vars_read > 3) { warn("Line `%s':\ntext '%s' ignored\n", input_cmd_string, rest_string); } } } else if (num_demods == 0) { num_vars_read = sscanf(command_string, "%s %80s", node_name, rest_string); if (num_vars_read < 1) { gerror("Line `%s':\n" "expected 'pd[n] name [f1 phi1 [f2 phi2]] node[*]'\n", input_cmd_string); } else { light_out->f[num_demods] = 0; light_out->phi[num_demods] = 0; output_data->output_type = REAL; light_out->demod_phase_mode[num_demods] = OFF; output_data->detector_type = PD0; if (num_vars_read > 1) { warn("Line `%s':\ntext '%s' ignored\n", input_cmd_string, rest_string); } } } else { bug_error("wrong number of demodulations"); } if (output_data->output_type == COMPLEX && light_out->sensitivity != OFF) { gerror("Line `%s': use a demodulation phase for pdS or pdN\n", input_cmd_string); } // check that the demod frequencies aren't negative int demod_index; for (demod_index = 1; demod_index <= num_demods; demod_index++) { if (light_out->f[demod_index] < 0) { gerror("Line `%s':\nfrequency must not be negative\n", input_cmd_string); } } if (inter.num_light_outputs >= mem.num_light_outputs || inter.num_outputs >= mem.num_outputs) { gerror("Line `%s':\ntoo many detectors\n", input_cmd_string); } if (num_demods == 0) { output_data->detector_type = PD0; } else { output_data->detector_type = PD1; } light_out->num_demods = num_demods; check_name(command_string, object_name); strcpy(light_out->name, object_name); strcpy(output_data->name, object_name); int last_char_index = strlen(node_name) - 1; output_data->is_second_beam = 0; if (node_name[last_char_index] == '*') { output_data->is_second_beam = 1; node_name[last_char_index] = '\0'; } if (get_node_index_for(node_name) == NODE_UNUSED) { gerror("photodetector %s not connected to interferometer.\n", object_name); } int field_index; for (field_index = 0; field_index < mem.num_fields; field_index++) { light_out->masking_factor[field_index] = 1.0; } light_out->beam_mask_is_set = false; light_out->detector_type = -1; // grab the node index output_data->node_index = update_node_index_for(node_name, EITHER_DIR); // assert that the node index is in the correct range: assert(output_data->node_index >= 0); assert(output_data->node_index < inter.num_nodes); // calculate the reduced index from the node index output_data->node_reduced_index = get_reduced_index_for(output_data->node_index); // assert that the reduced node index is in the correct range: assert(output_data->node_reduced_index >= 0); assert(output_data->node_reduced_index < inter.num_reduced_nodes); node_t *detector_node; detector_node = &inter.node_list[output_data->node_index]; detector_node->io = detector_node->io | 1; output_data->qx = &(detector_node->qx); output_data->qy = &(detector_node->qy); output_data->detector_index = inter.num_light_outputs; light_out->output_idx = inter.num_outputs; output_data->noplot = false; ++inter.num_light_outputs; ++inter.num_outputs; } //! Read a grating /*! * \param command_string the input command string */ void read_grating(const char *command_string) { char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char node3_name[MAX_TOKEN_LEN] = {0}; char node4_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; grating_t *grating; debug_msg("read_grating()\n"); endcomp = 1; lastparam = -1; grating = &(inter.grating_list[inter.num_gratings]); // check for number of ports in grating command string and set appropriately int num_of_ports; char portnumber[2]; portnumber[0] = command_string[2]; portnumber[1] = '\0'; if (my_atoi(portnumber, &num_of_ports)) { bug_error("failed char to integer conversion"); } if (num_of_ports > 0) { if (num_of_ports < 2 || num_of_ports > 4) { gerror("Line `%s':\nnumber of ports must be 2, 3 or 4\n", command_string); } grating->num_of_ports = num_of_ports; } else { grating->num_of_ports = 2; } if (inter.grating) { message("Found %d port grating\n", grating->num_of_ports); } char object_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char grating_period_string[LINE_LEN] = {0}; double grating_period; int num_vars_read; switch (grating->num_of_ports) { case 2: num_vars_read = sscanf(command_string, "%s %s %s %s %s %80s", command_name, object_name, grating_period_string, node1_name, node2_name, rest_string); int num_vars_expected = 5; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'gr2 name d node1 node2'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } // grab the node indices grating->node1_index = update_node_index_for(node1_name, IN_OUT); grating->node2_index = update_node_index_for(node2_name, IN_OUT); grating->node3_index = NOT_FOUND; grating->node4_index = NOT_FOUND; connect_component_to_node(grating->node1_index, (void*)grating, GRATING); connect_component_to_node(grating->node2_index, (void*)grating, GRATING); // calculate the reduced node indices according to the node indices grating->node1_reduced_index = get_reduced_index_for(grating->node1_index); grating->node2_reduced_index = get_reduced_index_for(grating->node2_index); grating->node3_reduced_index = NOT_FOUND; grating->node4_reduced_index = NOT_FOUND; grating->dmin = 0.5; grating->dmax = 1.5; break; case 3: num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %80s", command_name, object_name, grating_period_string, node1_name, node2_name, node3_name, rest_string); num_vars_expected = 6; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'gr3 name d node1 node2 node3'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } // grab the node indices grating->node1_index = update_node_index_for(node1_name, IN_OUT); grating->node2_index = update_node_index_for(node2_name, IN_OUT); grating->node3_index = update_node_index_for(node3_name, IN_OUT); grating->node4_index = NOT_FOUND; connect_component_to_node(grating->node1_index, (void*)grating, GRATING); connect_component_to_node(grating->node2_index, (void*)grating, GRATING); connect_component_to_node(grating->node3_index, (void*)grating, GRATING); // calculate the reduced node indices according to the node indices grating->node1_reduced_index = get_reduced_index_for(grating->node1_index); grating->node2_reduced_index = get_reduced_index_for(grating->node2_index); grating->node3_reduced_index = get_reduced_index_for(grating->node3_index); grating->node4_reduced_index = NOT_FOUND; grating->dmin = 1; grating->dmax = 2; break; case 4: num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %s %80s", command_name, object_name, grating_period_string, node1_name, node2_name, node3_name, node4_name, rest_string); num_vars_expected = 7; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'gr4 name d node1 node2 node3 node4'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } // grab the node indices grating->node1_index = update_node_index_for(node1_name, IN_OUT); grating->node2_index = update_node_index_for(node2_name, IN_OUT); grating->node3_index = update_node_index_for(node3_name, IN_OUT); grating->node4_index = update_node_index_for(node4_name, IN_OUT); connect_component_to_node(grating->node1_index, (void*)grating, GRATING); connect_component_to_node(grating->node2_index, (void*)grating, GRATING); connect_component_to_node(grating->node3_index, (void*)grating, GRATING); connect_component_to_node(grating->node4_index, (void*)grating, GRATING); // calculate the reduced node indices according to the node indices grating->node1_reduced_index = get_reduced_index_for(grating->node1_index); grating->node2_reduced_index = get_reduced_index_for(grating->node2_index); grating->node3_reduced_index = get_reduced_index_for(grating->node3_index); grating->node4_reduced_index = get_reduced_index_for(grating->node4_index); grating->dmin = 0.5; grating->dmax = 1.5; break; default: gerror("Line `%s':\nexpected 'gr4 name d node1 node2 node3 node4'\n", command_string); break; } check_name(command_string, object_name); strcpy(grating->name, object_name); if (atod(grating_period_string, &grating_period)) { gerror("Line `%s':\nUnable to read grating period\n", command_string); } if (grating_period <= 0) { gerror("Line `%s':\ngrating period must be >0\n", command_string); } grating->d = grating_period; grating->Rcx = 0.0; grating->Rcy = 0.0; grating->rebuild = 0; check_grating(grating); ++inter.num_gratings; ++inter.num_components; } //! Read a squeezer /*! * \param command_string the input command string * * \todo untested */ void read_squeezer(const char *command_string) { debug_msg("read_squeezer()\n"); // read the command string // format: sq name factor angle node1 node2 char object_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char squeeze_factor_string[LINE_LEN] = {0}; char squeeze_angle_string[LINE_LEN] = {0}; char freq_string[LINE_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %80s", command_name, object_name, freq_string, squeeze_factor_string, squeeze_angle_string, node_name, rest_string); int num_vars_expected = 6; // validate command string if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'sq name frequency factor angle node'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_light_inputs >= mem.num_light_inputs) { gerror("Line `%s':\ntoo many light inputs\n", command_string); } // assign the squeezer attributes settable via the kat command light_in_t *squeezer; squeezer = &(inter.light_in_list[inter.num_light_inputs]); if (command_name[strlen(command_name) - 1] == '*') { squeezer->use_entangled_carriers = true; } check_name(command_string, object_name); strcpy(squeezer->name, object_name); double frequency; if (atod(freq_string, &frequency)) { //gerror("Line `%s':\nUnable to read frequency\n", command_string); strcpy(squeezer->__frequency_name, freq_string); squeezer->f = NULL; if(squeezer->use_entangled_carriers) { // If we are using the entangled carrier pair idea we need two // carriers: one at 0 Hz relative to default wavelength and another // at the frequency of the squeeze value. char fname2[LINE_LEN+11] = {0}; sprintf(fname2, "%s_zero", squeezer->name); // Always at default frequency add_carrier_frequency(fname2, 0, &squeezer->f_entangled_zero); } } else { char fname[LINE_LEN+6] = {0}; sprintf(fname, "%s", squeezer->name); if(squeezer->use_entangled_carriers) { // If we are using the entangled carrier pair idea we need two // carriers: one at 0 Hz relative to default wavelength and another // at the frequency of the squeeze value. char fname2[LINE_LEN+11] = {0}; sprintf(fname2, "%s_zero", squeezer->name); // Always at default frequency add_carrier_frequency(fname2, 0, &squeezer->f_entangled_zero); add_carrier_frequency(fname, frequency, &squeezer->f); } else { add_carrier_frequency(fname, frequency, &squeezer->f); } } double squeeze_factor = 0.0; // read and validate the squeeze factor and angle if (atod(squeeze_factor_string, &squeeze_factor) != 0) { gerror("Line `%s':\ncould not read squeeze factor value in input\n", command_string); } double squeeze_angle = 0.0; if (atod(squeeze_angle_string, &squeeze_angle) != 0) { gerror("Line `%s':\ncould not read squeeze angle value in input\n", command_string); } // set the squeeze factor and angle of the squeezer squeezer->squeeze_db = squeeze_factor; squeezer->squeeze_angle = squeeze_angle; // assign the squeezer attributes not settable via the kat command // grab the node indices //squeezer->node1_index = update_node_index_for(node1_name, 0); //squeezer->node2_index = update_node_index_for(node2_name, 0); squeezer->node_index = update_node_index_for(node_name, EITHER_DIR); // calculate the reduced node indices from the node indices squeezer->node_reduced_index = get_reduced_index_for(squeezer->node_index); squeezer->attribs = 0; squeezer->I0 = 0; squeezer->noise_value = UNIT_VACUUM; squeezer->isSqueezed = true; inter.node_list[squeezer->node_index].io = inter.node_list[squeezer->node_index].io | 2; // false as no TEM command has been used to change the mode // content of the laser squeezer->isTEMSet = false; // Assume by default modes stored are HG squeezer->isHGModes = true; squeezer->power_coeff_list[0] = complex_1; int field_index; for (field_index = 1; field_index < mem.num_fields; field_index++) { squeezer->power_coeff_list[field_index] = complex_0; } ++inter.num_light_inputs; ++inter.num_components; } //! Read an input noise /*! * \param command_string the input command string * * \todo untested */ void read_noise(const char *command_string) { int noise_mode; char rest_string[REST_STRING_LEN] = {0}; char command_name[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %d %80s", command_name, &noise_mode, rest_string); int num_vars_expected = 2; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'noise mode'\n", command_string); } else { if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (noise_mode < 0 || noise_mode > 2) { gerror("Line `%s':\npossible modes are 0, 1 or 2\n", command_string); } inter.shotnoise = floor(pow(2, noise_mode)); debug_msg("Set inter.shotnoise to %d\n", inter.shotnoise); } } //! Read input (Schottky) shot noise command /*! * \param command_string the input command string */ void read_shot(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; endcomp = 1; lastparam = -1; // read the command string and check it int num_vars_read = sscanf(command_string, "%s %s %s %80s", command_name, object_name, node_name, rest_string); int num_vars_expected = 3; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'shot name node[*]'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } // check number of outputs in interferometer set correctly if (inter.num_light_outputs >= mem.num_light_outputs || inter.num_light_outputs >= mem.num_outputs) { gerror("Line `%s':\ntoo many outputs\n", command_string); } // grab the output data objects light_out_t *shot; output_data_t *out; shot = &(inter.light_out_list[inter.num_light_outputs]); out = &(inter.output_data_list[inter.num_outputs]); // check and set the objects' names check_name(command_string, object_name); strcpy(shot->name, object_name); strcpy(out->name, object_name); // select "other beam direction" if set in command int last_elem_index = strlen(node_name) - 1; out->is_second_beam = 0; if (node_name[last_elem_index] == '*') { out->is_second_beam = 1; node_name[last_elem_index] = '\0'; } // check detector connectivity if (get_node_index_for(node_name) == NODE_UNUSED) { gerror("Schottky shotnoise detector %s not connected " "to interferometer.\n", object_name); } // initialise elements of detector structure int i; for (i = 0; i < mem.num_fields; i++) { shot->masking_factor[i] = 1.0; } shot->detector_type = -1; shot->beam_mask_is_set = false; shot->f[1] = shot->f[2] = 0; // grab the node index and check its validity out->node_index = update_node_index_for(node_name, EITHER_DIR); assert(out->node_index >= 0); assert(out->node_index < inter.num_nodes); // calculate the reduced node index and validate out->node_reduced_index = get_reduced_index_for(out->node_index); assert(out->node_reduced_index >= 0); assert(out->node_reduced_index < inter.num_reduced_nodes); // set detector types, Gaussian beam parameters and set i/o status out->detector_type = SHOT; out->output_type = REAL; node_t *output_node; output_node = &(inter.node_list[out->node_index]); out->qx = &(output_node->qx); out->qy = &(output_node->qy); shot->sensitivity = OFF; output_node->io = output_node->io | 1; out->detector_index = inter.num_light_outputs; shot->output_idx = inter.num_outputs; out->noplot = false; ++inter.num_light_outputs; ++inter.num_outputs; } //! Read input (quantum) shot noise command /*! * \param command_string the input command string */ void read_quantum_shot(const char *command_string) { char object_name[MAX_TOKEN_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char num_demods_string[LINE_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; endcomp = 1; lastparam = -1; //! \todo this form of the command should be deprecated... //! I've now removed reading node_name from the command string // read the simple form of the command // i.e. qshot name num_demod node int num_vars_read = sscanf(command_string, "%s %s %s %80s", command_name, object_name, num_demods_string, rest_string); int num_vars_expected = 3; // check that the command was read correctly if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nIncorrect number of arguments\n" "Expected: 'qshot name num_demod [f1 phase1 [f2 phase2]] node[*]'\n", command_string); } // now read the number of demodulations from the input string if (NOT isdigit((int)(num_demods_string[0]))) { gerror("Line `%s':\nnumber of demodulations doesn't look like a number\n", command_string); } int num_demods; num_demods_string[1] = '\0'; if (my_atoi(num_demods_string, &num_demods)) { bug_error("failed char to integer conversion"); } // make sure the number of demodulations isn't too high if (num_demods > MAX_DEMOD + 1) { gerror("Line `%s':\nNumber of demodulations too large!\n" "I found %d, but the maximum is %d\n", command_string, num_demods, MAX_DEMOD); } // make sure the light outputs have been set up correctly if (inter.num_light_outputs >= mem.num_light_outputs || inter.num_outputs >= mem.num_outputs) { gerror("Line `%s':\ntoo many outputs\n", command_string); } // grab the output objects and give them their name light_out_t *quantum_shot; quantum_shot = &(inter.light_out_list[inter.num_light_outputs]); // check to see if we're using the sensitivity option if (strncasecmp(command_name, "qshotS", 6) == 0) { quantum_shot->sensitivity = ON; } else if (strncasecmp(command_name, "qshotN", 6) == 0) { quantum_shot->sensitivity = NORM; } else { quantum_shot->sensitivity = OFF; } // read the command for an arbitrary number of demodulations // we need to work on a copy of the command string as it's a const char cmd_str_copy[LINE_LEN] = {0}; strcpy(cmd_str_copy, command_string); // split the command string into its tokens char *token_pointer; token_pointer = strtok(cmd_str_copy, " "); // get the first token (cmd name) // skip the next two tokens (the object name and the number of demods) int token_index; for (token_index = 0; token_index < 2; token_index++) { token_pointer = strtok(NULL, " "); if (token_pointer == NULL) { gerror("Line `%s':\n" "Found end of string while processing command line\n", command_string); } } bool usesMax = false; char* node_token = NULL; // now get the frequency and phase pairs for each demodulation int demod_index; for (demod_index = 0; demod_index < num_demods; demod_index++) { token_pointer = strtok(NULL, " "); // grab the frequency if (token_pointer != NULL) { double frequency; char var_name[LINE_LEN] = {0}; sprintf(var_name, "f%i", demod_index+1); if (parse_frequency_input(token_pointer, &frequency, object_name, var_name)) { gerror("Line `%s':\nUnable to read demodulation frequency\n", command_string); } else { quantum_shot->f[demod_index + 1] = frequency; } } else { gerror("Line `%s':\n" "Expected a demodulation frequency but found end of string instead\n", command_string); } // now grab the phase token_pointer = strtok(NULL, " "); if (token_pointer != NULL) { double phase; if (isalpha((int)(token_pointer[0]))) { if (NOT strncasecmp(token_pointer, "max", 3)) { usesMax = true; quantum_shot->phi[demod_index + 1] = 0.0; quantum_shot->demod_phase_mode[demod_index + 1] = MAX_PHASE; } else if(demod_index != num_demods-1){ gerror("Line `%s':\n" "Demodulation phase was unreadable\n", command_string); } else if(demod_index == num_demods-1){ quantum_shot->phi[demod_index + 1] = 0.0; if(quantum_shot->sensitivity == OFF) quantum_shot->demod_phase_mode[demod_index + 1] = USER_PHASE; else quantum_shot->demod_phase_mode[demod_index + 1] = MAX_PHASE; node_token = token_pointer; } } else if (atod(token_pointer, &phase)) { gerror("Line `%s':\nUnable to read demodulation phase\n", command_string); } else { quantum_shot->phi[demod_index + 1] = phase; quantum_shot->demod_phase_mode[demod_index + 1] = USER_PHASE; } } else { gerror("Line `%s':\n" "Expected a demodulation phase but found end of string instead\n", command_string); } } // there should now only be the node name remaining token_pointer = strtok(NULL, " "); if (token_pointer != NULL) { strcpy(node_name, token_pointer); } else if(node_token != NULL) { strcpy(node_name, node_token); } else { gerror("Line `%s':\n" "Expected node_name but found end of string instead\n", command_string); } // make sure that node_name is something sensible (i.e. its first // character should be alphabetic if (NOT isalpha((int)(node_name[0]))) { gerror("Line `%s':\n" "Node name '%s' doesn't look like a name\n", command_string, node_name); } // make sure we've not got any negative frequencies for (demod_index = 1; demod_index < num_demods + 1; demod_index++) { if (quantum_shot->f[demod_index] < 0) { gerror("Cannot have negative demodulation frequencies in qshot\n"); } } output_data_t *output_data; output_data = &(inter.output_data_list[inter.num_outputs]); check_name(command_string, object_name); strcpy(quantum_shot->name, object_name); strcpy(output_data->name, object_name); // check to see if the "other beam direction" has been asked for int last_elem_index = strlen(node_name) - 1; output_data->is_second_beam = 0; if (node_name[last_elem_index] == '*') { output_data->is_second_beam = 1; node_name[last_elem_index] = '\0'; } // check detector connectivity if (get_node_index_for(node_name) == NODE_UNUSED) { gerror("Quantum shotnoise detector %s not connected " "to interferometer.\n", object_name); } // initialise components in the output detector structure int field_index; for (field_index = 0; field_index < mem.num_fields; field_index++) { quantum_shot->masking_factor[field_index] = 1.0; } quantum_shot->detector_type = -1; quantum_shot->beam_mask_is_set = false; quantum_shot->num_demods = num_demods; quantum_shot->output_idx = inter.num_outputs; if(quantum_shot->sensitivity == OFF){ if(usesMax) { warn("Line `%s':\n" "'max' phase is only available in qnoiseS or qnoiseN\n" "State exact demodulation phase or 'max' default to 0.\n", command_string); } } // grab the node index output_data->node_index = update_node_index_for(node_name, EITHER_DIR); assert(output_data->node_index >= 0); assert(output_data->node_index < inter.num_nodes); // calculate the reduced node index output_data->node_reduced_index = get_reduced_index_for(output_data->node_index); // assert that the reduced index is in the correct range: assert(output_data->node_reduced_index >= 0); assert(output_data->node_reduced_index < inter.num_reduced_nodes); // set detector and output types output_data->detector_type = QSHOT; output_data->output_type = REAL; // set Gaussian beam parameters and other params node_t *output_node; output_node = &(inter.node_list[output_data->node_index]); output_data->qx = &(output_node->qx); output_data->qy = &(output_node->qy); output_node->io = output_node->io | 1; output_data->detector_index = inter.num_light_outputs; output_data->noplot = false; ++inter.num_light_outputs; ++inter.num_outputs; } //! Read a beam detector (ccd) /*! * \param command_string the input command string */ void read_beam(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char frequency_string[LINE_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; bool frequency_is_set = false; int num_vars_read = sscanf(command_string, "%s %s %s %s %80s", command_name, object_name, frequency_string, node_name, rest_string); int num_vars_expected = 4; if (num_vars_read < num_vars_expected) { num_vars_read = sscanf(command_string, "%s %s %s %80s", command_name, object_name, node_name, rest_string); num_vars_expected = 3; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'beam name [f] node[*]'\n", command_string); } if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } else { frequency_is_set = true; if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } // if (inter.beam.set) // gerror("Line `%s':\nonly one beam analyser possible\n", s); // if (inter.num_outputs >0) // { // warn("only one detector is possible when a beam analyser is used,\n other detectors will be ignored!\n"); // inter.num_light_outputs=0; // inter.num_outputs=0; // } light_out_t *beam_output; beam_output = &(inter.light_out_list[inter.num_light_outputs]); beam_output->freq_is_set = false; output_data_t *output_data; output_data = &(inter.output_data_list[inter.num_outputs]); output_data->output_type = REAL; if (frequency_is_set) { double frequency; if (atod(frequency_string, &frequency)) { gerror("Line `%s':\nUnable to read frequency\n", command_string); } else { beam_output->freq = frequency; } beam_output->freq_is_set = true; output_data->output_type = COMPLEX; } check_name(command_string, object_name); strcpy(beam_output->name, object_name); strcpy(output_data->name, object_name); int node_name_last_index = strlen(node_name) - 1; output_data->is_second_beam = 0; if (node_name[node_name_last_index] == '*') { output_data->is_second_beam = 1; node_name[node_name_last_index] = '\0'; } if (get_node_index_for(node_name) == NODE_UNUSED) { gerror("beam analyser %s not connected to interferometer.\n", object_name); } // grab the node index output_data->node_index = update_node_index_for(node_name, EITHER_DIR); assert(output_data->node_index >= 0); assert(output_data->node_index < inter.num_nodes); // calculate the reduced node index from the node index output_data->node_reduced_index = get_reduced_index_for(output_data->node_index); // assert that the reduced node index is in the correct range: assert(output_data->node_reduced_index >= 0); assert(output_data->node_reduced_index < inter.num_reduced_nodes); output_data->detector_type = BEAM; beam_output->sensitivity = OFF; beam_output->x = 0.0; beam_output->y = 0.0; output_data->qx = &(inter.node_list[output_data->node_index].qx); output_data->qy = &(inter.node_list[output_data->node_index].qy); inter.beam.set = true; int field_index; for (field_index = 0; field_index < mem.num_fields; field_index++) { beam_output->masking_factor[field_index] = 1.0; } beam_output->beam_mask_is_set = false; beam_output->detector_type = -1; inter.node_list[output_data->node_index].io = inter.node_list[output_data->node_index].io | 1; output_data->detector_index = inter.num_light_outputs; beam_output->output_idx = inter.num_outputs; output_data->noplot = false; ++inter.num_light_outputs; ++inter.num_outputs; } //! Read output Guoy phase (???) /*! * \param command_string the input command string * * \todo refactor routine for readability */ void read_gouy_out(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char direction_string[LINE_LEN] = {0}; char dummy_string[LINE_LEN] = {0}; beampar_out_t *output_beam_param; output_data_t *output_data; output_beam_param = &(inter.beampar_out_list[inter.num_beam_param_outputs]); output_data = &(inter.output_data_list[inter.num_outputs]); if (inter.num_beam_param_outputs >= mem.num_beam_param_outputs) { gerror("Line `%s':\ntoo many beam parameter detectors\n", command_string); } int num_vars_read = sscanf(command_string, "%s %s %2s %s", command_name, object_name, direction_string, dummy_string); int num_vars_expected = 4; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'gouy name x/y list-of-spaces'\n", command_string); } if (strncasecmp(direction_string, "x", 1) == 0) { output_beam_param->x = 1; } else if (strncasecmp(direction_string, "y", 1) == 0) { output_beam_param->x = 0; } else { gerror("Line `%s':\nexpected 'gouy name x/y list-of-spaces'\n", command_string); } int command_name_len = strlen(command_name); assert(command_name_len == 4); command_string = strstr(command_string + command_name_len, object_name) + strlen(object_name); command_string = strstr(command_string, direction_string) + strlen(direction_string); bool all_spaces_found = false; int space_list[LINE_LEN] = {0}; char current_space_string[MAX_TOKEN_LEN] = {0}; int num_spaces = 0; while (!all_spaces_found) { num_vars_read = sscanf(command_string, "%s", current_space_string); if (num_vars_read < 1) { all_spaces_found = true; } else { int component_index = get_component_index_from_name(current_space_string); if (component_index == NOT_FOUND) { gerror("Line `%s':\nspace '%s' not found.\n", command_string, current_space_string); } int component_type = get_component_type_decriment_index(&component_index); if (component_type != SPACE) { gerror("Line `%s':\ncomponent '%s' is not a space.\n", command_string, current_space_string); } space_list[num_spaces++] = component_index; command_string = strstr(command_string, current_space_string) + strlen(current_space_string); } } output_beam_param->space_list = (int *) calloc(num_spaces + 1, sizeof (int)); if (output_beam_param->space_list == NULL) { gerror("Memeory allocation error (gouy out)\n"); } output_beam_param->num_spaces = num_spaces; int space_index; for (space_index = 0; space_index < num_spaces; space_index++) { output_beam_param->space_list[space_index] = space_list[space_index]; } output_data->output_type = REAL; check_name(command_string, object_name); strcpy(output_beam_param->name, object_name); strcpy(output_data->name, object_name); output_data->beam_param_not_set = true; output_data->detector_type = PG; output_data->qx = NULL; output_data->qy = NULL; // bug 140605 //output_data->detector=inter.num_outputs; output_data->detector_index = inter.num_beam_param_outputs; output_beam_param->output_index = inter.num_outputs; output_data->noplot = false; ++inter.num_beam_param_outputs; ++inter.num_outputs; } //! Read beam parameter detector /*! * \param command_string the input command string * * \todo refactor routine for readability * * \todo BPW0, BPG, BPZR, BPZ, BPQ branches are untested */ void read_beamparam_out(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char x_y_string[LINE_LEN] = {0}; char parameter_string[LINE_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; if (inter.num_beam_param_outputs >= mem.num_beam_param_outputs) { gerror("Line `%s':\ntoo many beam parameter detectors\n", command_string); } int num_vars_read = sscanf(command_string, "%s %s %s %s %s %80s", command_name, object_name, x_y_string, parameter_string, node_name, rest_string); int num_vars_expected = 5; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'bp name x/y parameter node'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } beampar_out_t *beamparam_out; beamparam_out = &(inter.beampar_out_list[inter.num_beam_param_outputs]); if (strncasecmp(x_y_string, "x", 1) == 0) { beamparam_out->x = 1; } else if (strncasecmp(x_y_string, "y", 1) == 0) { beamparam_out->x = 0; } else { gerror("Line `%s':\nexpected 'bp name x/y parameter node'\n", command_string); } output_data_t *output_data; output_data = &(inter.output_data_list[inter.num_outputs]); output_data->output_type = REAL; if (strncasecmp(parameter_string, "w0", 2) == 0) { beamparam_out->action = BPW0; } else if (strncasecmp(parameter_string, "w", 1) == 0) { beamparam_out->action = BPW; } else if (strncasecmp(parameter_string, "g", 1) == 0) { beamparam_out->action = BPG; } else if (strncasecmp(parameter_string, "zr", 2) == 0) { beamparam_out->action = BPZR; } else if (strncasecmp(parameter_string, "z", 1) == 0) { beamparam_out->action = BPZ; } else if (strncasecmp(parameter_string, "r", 1) == 0) { beamparam_out->action = BPRC; } else if (strncasecmp(parameter_string, "q", 1) == 0) { beamparam_out->action = BPQ; output_data->output_type = COMPLEX; } else { gerror("Line `%s':\npossible paramters are w/w0/g/z/zr/r/q'\n", command_string); } check_name(command_string, object_name); strcpy(beamparam_out->name, object_name); strcpy(output_data->name, object_name); int last_char_index = strlen(node_name) - 1; output_data->is_second_beam = 0; if (node_name[last_char_index] == '*') { output_data->is_second_beam = 1; node_name[last_char_index] = '\0'; } if (get_node_index_for(node_name) == NODE_UNUSED) { gerror("beam parameter detector %s not connected to interferometer.\n", object_name); } // grab the node index output_data->node_index = update_node_index_for(node_name, EITHER_DIR); // assert that the node index is in the correct range: assert(output_data->node_index >= 0); assert(output_data->node_index < inter.num_nodes); // calculate the reduced node index from the node index output_data->node_reduced_index = get_reduced_index_for(output_data->node_index); // assert that the reduced node index is in the correct range: assert(output_data->node_reduced_index >= 0); assert(output_data->node_reduced_index < inter.num_reduced_nodes); output_data->detector_type = BP; output_data->qx = &inter.node_list[output_data->node_index].qx; output_data->qy = &inter.node_list[output_data->node_index].qy; inter.node_list[output_data->node_index].io = inter.node_list[output_data->node_index].io | 1; // bug 140605 //out->detector=inter.num_outputs; //bpout->output=inter.num_light_outputs; output_data->detector_index = inter.num_beam_param_outputs; beamparam_out->output_index = inter.num_outputs; beamparam_out->num_spaces = 0; beamparam_out->space_list = NULL; output_data->noplot = false; ++inter.num_beam_param_outputs; ++inter.num_outputs; } //! Read cavity parameter detector /*! * \param command_string the input command string * */ void read_cavity_param_out(const char *command_string) { char name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char x_y_string[LINE_LEN] = {0}; char parameter_string[LINE_LEN] = {0}; // char node_name[MAX_TOKEN_LEN] = { 0 }; char rest_string[REST_STRING_LEN] = {0}; if (inter.num_cavity_param_outputs >= mem.num_cavity_param_outputs) { gerror("Line `%s':\ntoo many cavity parameter detectors\n", command_string); } int num_vars_read = sscanf(command_string, "%s %s %s %s %s %80s", command_name, name, object_name, x_y_string, parameter_string, rest_string); int num_vars_expected = 5; if (num_vars_read < num_vars_expected) { num_vars_read = sscanf(command_string, "%s %s %s %s %80s", command_name, object_name, x_y_string, parameter_string, rest_string); if(num_vars_read == 4) { warn("Line `%s':\n", command_string); warn("cp detector with no name has been depreciated as of version 2.1, please use new format.\n"); } else { gerror("Line `%s':\nexpected 'cp name cavity_name x/y parameter'\n", command_string); } } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } cavity_par_out_t *cavity_param_out; cavity_param_out = &(inter.cavity_par_out_list[inter.num_cavity_param_outputs]); strcpy(cavity_param_out->name, name); int i; int found = 0; for (i = 0; i < inter.num_cavities; i++) { if (strcasecmp(object_name, inter.cavity_list[i].name) == 0) { if (found) { gerror("Line `%s':\nfound two cavities with the given name'\n", command_string); } found = 1; cavity_param_out->cavity = i; } } if (NOT found) { gerror("Line `%s':\n did not find cavity with the given name'\n", command_string); } if (strncasecmp(x_y_string, "x", 1) == 0) { cavity_param_out->x = 1; } else if (strncasecmp(x_y_string, "y", 1) == 0) { cavity_param_out->x = 0; } else { gerror("Line `%s':\nexpected 'cp cavity_name x/y parameter'\n", command_string); } output_data_t *output_data = &(inter.output_data_list[inter.num_outputs]); output_data->output_type = REAL; if (strncasecmp(parameter_string, "w0", 2) == 0) { cavity_param_out->action = CPW0; } else if (strncasecmp(parameter_string, "w", 1) == 0) { cavity_param_out->action = CPW; } else if (strncasecmp(parameter_string, "zr", 2) == 0) { cavity_param_out->action = CPZR; } else if (strncasecmp(parameter_string, "z", 1) == 0) { cavity_param_out->action = CPZ; } else if (strncasecmp(parameter_string, "r", 1) == 0) { cavity_param_out->action = CPRC; } else if (strncasecmp(parameter_string, "q", 1) == 0) { cavity_param_out->action = CPQ; output_data->output_type = COMPLEX; } else if (strncasecmp(parameter_string, "finesse", 7) == 0) { cavity_param_out->action = CPF; } else if (strncasecmp(parameter_string, "m", 1) == 0 || strncasecmp(parameter_string, "stability", 9) == 0) { cavity_param_out->action = CPS; } else if (strncasecmp(parameter_string, "loss", 4) == 0) { cavity_param_out->action = CPL; } else if (strncasecmp(parameter_string, "length", 6) == 0) { cavity_param_out->action = CPOL; } else if (strncasecmp(parameter_string, "fsr", 3) == 0) { cavity_param_out->action = CPFSR; } else if (strncasecmp(parameter_string, "fwhm", 4) == 0) { cavity_param_out->action = CPFWHM; } else if (strncasecmp(parameter_string, "pole", 4) == 0) { cavity_param_out->action = CPPOLE; } else if (strncasecmp(parameter_string, "gouy", 4) == 0) { cavity_param_out->action = CPGOUY; } else if (strncasecmp(parameter_string, "fsep", 4) == 0) { cavity_param_out->action = CPFSEP; } else if (strncasecmp(parameter_string, "A", 1) == 0) { cavity_param_out->action = CPA; } else if (strncasecmp(parameter_string, "B", 1) == 0) { cavity_param_out->action = CPB; } else if (strncasecmp(parameter_string, "C", 1) == 0) { cavity_param_out->action = CPC; } else if (strncasecmp(parameter_string, "D", 1) == 0) { cavity_param_out->action = CPD; } else { gerror("Line `%s':\npossible paramters are w/w0/z/r/q/finesse/loss/length/FSR/FWHM/pole/stability/gouy/fsep/A/B/C/D'\n", command_string); } strcpy(cavity_param_out->cavity_name, object_name); // determine whether we are using the old cp format as of version 2.1 if (num_vars_read == 4) { sprintf(output_data->name, "%s_%s_%s", object_name, x_y_string, parameter_string); } else { check_name(command_string, name); strcpy(output_data->name, name); } strcpy(cavity_param_out->name, output_data->name); output_data->detector_type = CP; output_data->detector_index = inter.num_cavity_param_outputs; cavity_param_out->output_index = inter.num_outputs; output_data->noplot = false; ++inter.num_cavity_param_outputs; ++inter.num_outputs; } //========================================================================= //! Read `mirror phase' detector /*! * \param command_string the input command string * */ void read_mirror_phase_out(const char *command_string) { gerror("read_mirror_phase_out not implemented in code. Command: %s", command_string); } //! Read `convolution' detector /*! * \param command_string the input command string * */ void read_convolution_out(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char freq_string[LINE_LEN] = {0}; char modetype_string[LINE_LEN] = {0}; char w0x_string[LINE_LEN] = {0}; char z0x_string[LINE_LEN] = {0}; char w0y_string[LINE_LEN] = {0}; char z0y_string[LINE_LEN] = {0}; char xsize_string[LINE_LEN] = {0}; char ysize_string[LINE_LEN] = {0}; int n, m; char node_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; char rest_command_string[REST_STRING_LEN] = {0}; if (inter.num_convolution_outputs >= mem.num_convolution_outputs) { gerror("Line `%s':\ntoo many beam convolution detectors\n", command_string); } convolution_out_t *convolution_out; output_data_t *output_data; convolution_out = &(inter.convolution_out_list[inter.num_convolution_outputs]); output_data = &(inter.output_data_list[inter.num_outputs]); // trying to read: conv name [f] HG/LG n m xsize ysize [w0x z0x [w0y z0y]] // first try to guess whether a frequency has been given bool freq_is_set = false; double freq = 0; output_data->output_type = REAL; int num_vars_read = sscanf(command_string, "%s %s %s %s %d %d %s", command_name, object_name, freq_string, modetype_string, &n, &m, rest_command_string); if (num_vars_read < 7) { // probably frequency not given num_vars_read = sscanf(command_string, "%s %s %s %d %d %s", command_name, object_name, modetype_string, &n, &m, rest_command_string); if (num_vars_read != 6) { gerror("Line `%s':\nexpected 'conv name [f] HG/LG n m xsize ysize [w0x z0x [w0y z0y]] node'\n", command_string); } } else { freq_is_set = true; if (atod(freq_string, &freq)) { gerror("Line `%s':\nUnable to read frequency\n", command_string); } else { convolution_out->freq = freq; output_data->output_type = COMPLEX; } } convolution_out->freq_is_set = freq_is_set; // Now reading the remianing parameters bool x_is_set = false; bool y_is_set = false; num_vars_read = sscanf(rest_command_string, "%s %s %s %s %s %s %s %80s", xsize_string, ysize_string, w0x_string, z0x_string, w0y_string, z0y_string, node_name, rest_string); int num_vars_expected = 8; if (num_vars_read < num_vars_expected) { num_vars_read = sscanf(rest_command_string, "%s %s %s %s %s %80s", xsize_string, ysize_string, w0x_string, z0x_string, node_name, rest_string); num_vars_expected = 6; if (num_vars_read < num_vars_expected) { num_vars_read = sscanf(rest_command_string, "%s %s %s %80s", xsize_string, ysize_string, node_name, rest_string); num_vars_expected = 4; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'conv name [f] HG/LG n m xsize ysize [w0x z0x [w0y z0y]] node'\n", command_string); } else { if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } } else { x_is_set = true; if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } } else { x_is_set = true; y_is_set = true; if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } if (x_is_set) { double w0x; double z0x; if (atod(w0x_string, &w0x)) { gerror("Line `%s':\nUnable to read w0x\n"); } if (atod(z0x_string, &z0x)) { gerror("Line `%s':\nUnable to read z0x\n"); } convolution_out->w0x = w0x; convolution_out->z0x = z0x; convolution_out->x_is_set = x_is_set; } else { convolution_out->w0x = 0.0; convolution_out->z0x = 0.0; } if (y_is_set) { double w0y; double z0y; if (atod(w0y_string, &w0y)) { gerror("Line `%s':\nUnable to read w0y\n"); } if (atod(z0y_string, &z0y)) { gerror("Line `%s':\nUnable to read z0y\n"); } convolution_out->w0y = w0y; convolution_out->z0y = z0y; convolution_out->y_is_set = y_is_set; } else { convolution_out->w0y = 0.0; convolution_out->z0y = 0.0; } double xsize; if (atod(xsize_string, &xsize)) { gerror("Line `%s':\nUnable to read xsize\n"); } else { convolution_out->xsize = xsize; } double ysize; if (atod(ysize_string, &ysize)) { gerror("Line `%s':\nUnable to read ysize\n"); } else { convolution_out->ysize = ysize; } check_name(command_string, object_name); strcpy(convolution_out->name, object_name); strcpy(output_data->name, object_name); int last_char_index = strlen(node_name) - 1; output_data->is_second_beam = 0; if (node_name[last_char_index] == '*') { output_data->is_second_beam = 1; node_name[last_char_index] = '\0'; } if (get_node_index_for(node_name) == NODE_UNUSED) { gerror("beam convolution detector %s not connected to interferometer.\n", object_name); } // grab the node index output_data->node_index = update_node_index_for(node_name, EITHER_DIR); assert(output_data->node_index >= 0); assert(output_data->node_index < inter.num_nodes); // calculate the reduced node index from the node index output_data->node_reduced_index = get_reduced_index_for(output_data->node_index); // assert that the reduced node index is in the correct range: assert(output_data->node_reduced_index >= 0); assert(output_data->node_reduced_index < inter.num_reduced_nodes); output_data->detector_type = CONV; if (strncasecmp(modetype_string, "HG", 1) == 0) { convolution_out->HGLG = 1; } else if (strncasecmp(modetype_string, "LG", 1) == 0) { convolution_out->HGLG = 0; } else { gerror("Line `%s':\nexpected 'conv name HG/LG n m xsize ysize node'\n", command_string); } if ((n + m) > inter.tem) { gerror("Line `%s':\nn+m larger than max order of TEM (%s)\n", command_string, int_form(inter.tem)); } if (convolution_out->HGLG == 0) { if (n < 0 || abs(m) < n) { gerror("Line `%s':\nLG mode indices must be 0<= n <= |m|\n", command_string); } } else { if (n < 0 || m < 0) { gerror("Line `%s':\nHG mode indices must be positive\n", command_string); } } convolution_out->n = n; convolution_out->m = m; output_data->qx = &(inter.node_list[output_data->node_index].qx); output_data->qy = &(inter.node_list[output_data->node_index].qy); // TODO: is this still needed? inter.beam.set = true; // TODO: this is masking code copied from read_beam. Shall we use masking here?? //bout->c[0]=1.0; int field_index; for (field_index = 0; field_index < mem.num_fields; field_index++) { convolution_out->masking_factor[field_index] = 1.0; } convolution_out->beam_mask_is_set = false; convolution_out->detector_type = -1; inter.node_list[output_data->node_index].io = inter.node_list[output_data->node_index].io | 1; output_data->detector_index = inter.num_convolution_outputs; convolution_out->output_index = inter.num_outputs; output_data->noplot = false; ++inter.num_convolution_outputs; ++inter.num_outputs; } //=============================================================================== void read_qd_out(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char detector_name[MAX_TOKEN_LEN] = {0}; char homangle[MAX_TOKEN_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char carrier_frequency[MAX_TOKEN_LEN] = {0}; int _n, _m; char rest_string[REST_STRING_LEN] = {0}; assert(inter.num_light_outputs < mem.num_light_outputs); assert(inter.num_outputs < mem.num_outputs); light_out_t *quad_detector = &(inter.light_out_list[inter.num_light_outputs]); output_data_t *output_data = &(inter.output_data_list[inter.num_outputs]); int n = sscanf(command_string, "%s %s %s %d %d %s %s %s", command_name, detector_name, carrier_frequency, &_n, &_m, homangle, node_name, rest_string); if(n != 7) { _n = _m = 0; quad_detector->field_is_set = false; quad_detector->field = 0; n = sscanf(command_string, "%s %s %s %s %s %s", command_name, detector_name, carrier_frequency, homangle, node_name, rest_string); if (n != 5){ gerror("Line `%s':\n" "expected 'qd name carrier_frequency [n m] phase node[*]'\n", command_string); } } check_name(command_string, detector_name); strcpy(quad_detector->name, detector_name); strcpy(output_data->name, detector_name); if(atod(homangle, &(quad_detector->homodyne_angle))) gerror("Line `%s':\nquadrature detector phase could not be parsed\n", command_string); if(atod(carrier_frequency, &(quad_detector->freq))) gerror("Line `%s':\ncould not convert carrier frequency into a number\n", command_string); if(node_name[strlen(node_name)-1] == '*'){ output_data->is_second_beam = 1; node_name[strlen(node_name)-1] = '\0'; } else { output_data->is_second_beam = 0; } if(n==7){ if(_n+_m > inter.tem){ gerror("Line `%s':\nMode order greater than maxtem\n", command_string); } quad_detector->field_is_set = true; quad_detector->field = get_field_index_from_tem(_n, _m); } int nidx = get_node_index_from_name(node_name); if(nidx == NOT_FOUND) { gerror("Line `%s':\nnode `%s` could not be found\n", command_string, node_name); } else { output_data->node_index = nidx; } output_data->detector_type = QD; output_data->output_type = REAL; output_data->detector_index = inter.num_light_outputs++; quad_detector->output_idx = inter.num_outputs++; output_data->noplot = false; } void read_quadrature_out(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char detector_name[MAX_TOKEN_LEN] = {0}; char phase[MAX_TOKEN_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char carrier_frequency[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; assert(inter.num_quad_outputs < mem.num_quad_outputs); assert(inter.num_outputs < mem.num_outputs); quadrature_out_t *quad_detector = &(inter.quad_out_list[inter.num_quad_outputs]); output_data_t *output_data = &(inter.output_data_list[inter.num_outputs]); int n = sscanf(command_string, "%s %s %s %s %s %s", command_name, detector_name, carrier_frequency, phase, node_name, rest_string); if(n != 5){ gerror("Line `%s':\nexpected 'qd name carrier_frequency phase node'\n", command_string); } check_name(command_string, detector_name); strcpy(quad_detector->name, detector_name); strcpy(output_data->name, detector_name); if(atod(phase, &quad_detector->phase)) gerror("Line `%s':\nquadrature detector phase could not be parsed\n", command_string); if(atod(carrier_frequency, &quad_detector->carrier_freq)) gerror("Line `%s':\ncould not convert carrier frequency into a number\n", command_string); int nidx = get_node_index_from_name(node_name); if(nidx == NOT_FOUND){ gerror("Line `%s':\nnode `%s` could not be found\n", command_string, node_name); } else { quad_detector->node_index = nidx; output_data->node_index = nidx; } if(node_name[strlen(node_name)-1] == '*'){ output_data->is_second_beam = 1; } else { output_data->is_second_beam = 0; } output_data->detector_type = QD; output_data->output_type = COMPLEX; output_data->detector_index = inter.num_quad_outputs++; quad_detector->output_index = inter.num_outputs++; output_data->noplot = false; } void read_motion_link(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char component_1[MAX_TOKEN_LEN] = {0}; char component_2[MAX_TOKEN_LEN] = {0}; char motion_1[MAX_TOKEN_LEN] = {0}; char motion_2[MAX_TOKEN_LEN] = {0}; char tf_12[MAX_TOKEN_LEN] = {0}; char tf_21[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %s %s", command_name, component_1, motion_1, component_2, motion_2, tf_12, tf_21, rest_string); if(num_vars_read != 7){ gerror("Line `%s':\nexpected 'xlink component_in motion_in component_out motion_out transfer_function_in2out transfer_function_out2in'\n", command_string); } int comp_1_idx = get_component_index_from_name(component_1); int comp_2_idx = get_component_index_from_name(component_2); if(comp_1_idx == NOT_FOUND) gerror("Line `%s':\nCouldn't find component %s\n", command_string, component_1); if(comp_2_idx == NOT_FOUND) gerror("Line `%s':\nCouldn't find component %s\n", command_string, component_2); int comp_1_type = get_component_type_decriment_index(&comp_1_idx); int comp_2_type = get_component_type_decriment_index(&comp_2_idx); if(!((comp_1_type != MIRROR || comp_1_type != BEAMSPLITTER) && ( comp_2_type != MIRROR || comp_2_type != BEAMSPLITTER))) gerror("Line `%s':\nCan only link mirror and beamsplitter components\n", command_string); motion_link_t link1 = {0}; // linking from component 1 to 2 motion_link_t link2 = {0}; // linking from component 2 to 1 int i; if(strlen(tf_12) > 0){ for(i=0; i< inter.num_transfer_funcs; i++){ if(strcmp(tf_12, inter.tf_list[i].name) == 0){ link1.f_f = &inter.tf_list[i]; break; } } } if(strlen(tf_21) > 0){ for(i=0; i< inter.num_transfer_funcs; i++){ if(strcmp(tf_21, inter.tf_list[i].name) == 0){ link2.f_f = &inter.tf_list[i]; break; } } } link1.from_list_idx = comp_1_idx; link1.to_list_idx = comp_2_idx; link1.from_type = comp_1_type; link1.to_type = comp_2_type; link2.from_list_idx = comp_2_idx; link2.to_list_idx = comp_1_idx; link2.from_type = comp_2_type; link2.to_type = comp_1_type; UT_array **motion_links[2] = {NULL}; mirror_t *m = NULL; beamsplitter_t *bs = NULL; switch(comp_1_type) { case MIRROR: m = &(inter.mirror_list[link1.from_list_idx]); link1.from_motion = motion_string_to_index(motion_1, m->mass, m->Ix, m->Iy, m->num_surface_motions); link2.to_motion = link1.from_motion; motion_links[0] = &(m->motion_links); motion_string_to_mirror_tf(motion_1, m, &link1.f_x_from); break; case BEAMSPLITTER: bs = &(inter.bs_list[link1.from_list_idx]); link1.from_motion = motion_string_to_index(motion_1, bs->mass, bs->Ix, bs->Iy, 0); link2.to_motion = link1.from_motion; motion_links[0] = &(bs->motion_links); motion_string_to_bs_tf(motion_1, bs, &link1.f_x_from); break; default: bug_error("not handled"); } if(link1.from_motion == NOT_FOUND) gerror("Line `%s':\nMotion '%s' was not found at the component %s\n", command_string, motion_1, component_1); switch(comp_2_type){ case MIRROR: m = &(inter.mirror_list[link2.from_list_idx]); link2.from_motion = motion_string_to_index(motion_2, m->mass, m->Ix, m->Iy, m->num_surface_motions); link1.to_motion = link2.from_motion; motion_links[1] = &(m->motion_links); motion_string_to_mirror_tf(motion_2, m, &link2.f_x_from); break; case BEAMSPLITTER: bs = &(inter.bs_list[link2.from_list_idx]); link2.from_motion = motion_string_to_index(motion_2, bs->mass, bs->Ix, bs->Iy, 0); link1.to_motion = link2.from_motion; motion_links[1] = &(bs->motion_links); motion_string_to_bs_tf(motion_2, bs, &link2.f_x_from); break; default: bug_error("not handled"); } if(link2.from_motion == NOT_FOUND) gerror("Line `%s':\nMotion '%s' was not found at the component %s\n", command_string, motion_2, component_2); if(link1.from_list_idx == link1.to_list_idx && link1.to_motion == link1.from_motion) gerror("Line `%s':\nCannot link the same motion to itself\n", command_string, motion_2); link2.f_x_to = link1.f_x_from; link1.f_x_to = link2.f_x_from; if(*motion_links[0] == NULL){ // create a new array if one doesn't exist... utarray_new((*motion_links[0]), &motion_link_icd); } if(*motion_links[1] == NULL){ // create a new array if one doesn't exist... utarray_new((*motion_links[1]), &motion_link_icd); } utarray_push_back((*motion_links[0]), &link1); utarray_push_back((*motion_links[1]), &link2); } /** * Reads command for an amplitude motion output * * @param command_string */ void read_motion_out(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char detector_name[MAX_TOKEN_LEN] = {0}; char comp_name[MAX_TOKEN_LEN] = {0}; char motion_string[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; motion_out_t *motion_detector; output_data_t *output_data; motion_detector = &(inter.motion_out_list[inter.num_motion_outputs]); output_data = &(inter.output_data_list[inter.num_outputs]); int num_vars_read = sscanf(command_string, "%s %s %s %s %80s", command_name, detector_name, comp_name, motion_string, rest_string); int num_vars_expected = 4; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'xd name component motion'\n", command_string); } if (inter.num_motion_outputs >= mem.num_motion_outputs || inter.num_outputs >= mem.num_outputs) { gerror("Line `%s':\ntoo many motion detectors\n", command_string); } check_name(command_string, detector_name); strcpy(motion_detector->name, detector_name); strcpy(output_data->name, detector_name); int cidx = get_component_index_from_name(comp_name); if (cidx == NOT_FOUND) { gerror("Line `%s':\nCould not find component with name %s\n",command_string, comp_name); } motion_detector->component_type = get_component_type_decriment_index(&cidx); motion_detector->component_index = cidx; strcpy(motion_detector->motion_name, motion_string); switch(motion_detector->component_type){ case MIRROR: case BEAMSPLITTER: break; default: gerror("Line `%s':\nMotion detector is not compatible with this type of component\n",command_string); } output_data->is_second_beam = 0; // motion detector is linked to a component not a node output_data->node_index = -1; output_data->detector_type = XD; output_data->output_type = COMPLEX; output_data->detector_index = inter.num_motion_outputs; motion_detector->output_index = inter.num_outputs; output_data->noplot = false; ++inter.num_motion_outputs; ++inter.num_outputs; } void read_hd_out(const char *command_string){ char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char phase[MAX_TOKEN_LEN] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; homodyne_t *hd = &inter.homodyne_list[inter.num_homodynes]; output_data_t *output_data = &inter.output_data_list[inter.num_outputs]; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %80s", command_name, object_name, phase, node1_name, node2_name, rest_string); int num_vars_expected = 5; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'hd name phase node1[*] node2[*]'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_homodynes >= mem.num_homodynes || inter.num_outputs >= mem.num_outputs) { gerror("Line `%s':\ntoo many homodyne detectors\n", command_string); } if(command_name[3] == 'N') hd->sensitivity = NORM; else if(command_name[3] == 'S') hd->sensitivity = ON; else hd->sensitivity = OFF; if(hd->sensitivity || command_name[0] == 'q') hd->is_quantum = true; else hd->is_quantum = false; if (atod(phase, &(hd->phase))) gerror("Line `%s':\nUnable to read phase %s \n", command_string, phase); check_name(command_string, object_name); strcpy(output_data->name, object_name); int last_char_index = strlen(node1_name) - 1; hd->is_second_beam1 = 0; if (node1_name[last_char_index] == '*') { hd->is_second_beam1 = 1; node1_name[last_char_index] = '\0'; } if (get_node_index_for(node1_name) == NODE_UNUSED) { gerror("Homodyne detector %s not connected to interferometer.\n", object_name); } last_char_index = strlen(node2_name) - 1; hd->is_second_beam2 = 0; if (node2_name[last_char_index] == '*') { hd->is_second_beam2 = 1; node2_name[last_char_index] = '\0'; } if (get_node_index_for(node2_name) == NODE_UNUSED) { gerror("Homodyne detector %s not connected to interferometer.\n", object_name); } // grab the node index hd->node1_index = update_node_index_for(node1_name, EITHER_DIR); hd->node2_index = update_node_index_for(node2_name, EITHER_DIR); // storing first node rather than NOT_FOUND as it causes problems later output_data->node_index = update_node_index_for(node1_name, EITHER_DIR); output_data->node_reduced_index = NOT_FOUND; // assert that the node index is in the correct range: assert(hd->node1_index >= 0); assert(hd->node1_index < inter.num_nodes); assert(hd->node2_index >= 0); assert(hd->node2_index < inter.num_nodes); output_data->detector_type = HOMODYNE; output_data->output_type = REAL; inter.node_list[hd->node1_index].io |= 1; inter.node_list[hd->node2_index].io |= 1; output_data->detector_index = inter.num_homodynes; hd->output_index = inter.num_outputs; output_data->noplot = false; int field_index; hd->light_out_1 = inter.num_light_outputs++; light_out_t *light_out1 = &inter.light_out_list[hd->light_out_1]; light_out1->f[1] = inter.fsig; light_out1->phi[1] = 0; for (field_index = 0; field_index < mem.num_fields; field_index++) { light_out1->masking_factor[field_index] = 1.0; } light_out1->beam_mask_is_set = false; light_out1->detector_type = -1; light_out1->output_idx = inter.num_outputs; hd->light_out_2 = inter.num_light_outputs++; light_out_t *light_out2 = &inter.light_out_list[hd->light_out_2]; light_out2->f[1] = inter.fsig; light_out2->phi[1] = 0; for (field_index = 0; field_index < mem.num_fields; field_index++) { light_out2->masking_factor[field_index] = 1.0; } light_out2->beam_mask_is_set = false; light_out2->detector_type = -1; light_out2->output_idx = inter.num_outputs; // if we are computing a TF with just a 'hd' command we have complex outputs if(!hd->sensitivity && !hd->is_quantum){ light_out1->demod_phase_mode[1] = OFF; light_out2->demod_phase_mode[1] = OFF; output_data->output_type = COMPLEX; } else { light_out1->demod_phase_mode[1] = OFF; light_out2->demod_phase_mode[1] = OFF; output_data->output_type = REAL; } output_data->detector_index = inter.num_homodynes; ++inter.num_homodynes; ++inter.num_outputs; } void read_mhd_out(const char *command_string){ char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char rest_string[LINE_LEN] = {0}; char buffer[LINE_LEN] = {0}; sscanf(command_string, "%s %s %1024[^\n]s", command_name, object_name, rest_string); mhomodyne_t *hd = &inter.mhomodyne_list[inter.num_mhomodynes]; output_data_t *output_data = &inter.output_data_list[inter.num_outputs]; hd->num_node_pairs = check_mhomodyne(command_name); assert(hd->num_node_pairs > 0); check_name(command_string, object_name); strcpy(output_data->name, object_name); int i; for(i=0; inum_node_pairs; i++) { memcpy(buffer, rest_string, sizeof(char) * LINE_LEN); rest_string[0] = '\0'; char func_name[MAX_TOKEN_LEN] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; int num_vars_read = sscanf(buffer, "%s %s %s %1024[^\n]s", func_name, node1_name, node2_name, rest_string); if(num_vars_read < 3){ gerror("Line `%s':\nCould not read node pair %i\n", command_string, i); } strcpy(hd->pairs[i].func_name, func_name); int last_char_index = strlen(node1_name) - 1; hd->pairs[i].is_second_beam1 = 0; if (node1_name[last_char_index] == '*') { hd->pairs[i].is_second_beam1 = 1; node1_name[last_char_index] = '\0'; } if (get_node_index_for(node1_name) == NODE_UNUSED) { gerror("Homodyne detector %s not connected to interferometer.\n", object_name); } last_char_index = strlen(node2_name) - 1; hd->pairs[i].is_second_beam2 = 0; if (node2_name[last_char_index] == '*') { hd->pairs[i].is_second_beam2 = 1; node2_name[last_char_index] = '\0'; } if (get_node_index_for(node2_name) == NODE_UNUSED) { gerror("Homodyne detector %s not connected to interferometer.\n", object_name); } // grab the node index hd->pairs[i].node1_index = update_node_index_for(node1_name, EITHER_DIR); hd->pairs[i].node2_index = update_node_index_for(node2_name, EITHER_DIR); // storing first node rather than NOT_FOUND as it causes problems later output_data->node_index = update_node_index_for(node1_name, EITHER_DIR); output_data->node_reduced_index = NOT_FOUND; // assert that the node index is in the correct range: assert(hd->pairs[i].node1_index >= 0); assert(hd->pairs[i].node1_index < inter.num_nodes); assert(hd->pairs[i].node2_index >= 0); assert(hd->pairs[i].node2_index < inter.num_nodes); inter.node_list[hd->pairs[i].node1_index].io |= 1; inter.node_list[hd->pairs[i].node2_index].io |= 1; int field_index; hd->pairs[i].light_out_1 = inter.num_light_outputs++; light_out_t *light_out1 = &inter.light_out_list[hd->pairs[i].light_out_1]; light_out1->f[1] = inter.fsig; light_out1->phi[1] = 0; for (field_index = 0; field_index < mem.num_fields; field_index++) { light_out1->masking_factor[field_index] = 1.0; } light_out1->beam_mask_is_set = false; light_out1->detector_type = -1; light_out1->output_idx = inter.num_outputs; hd->pairs[i].light_out_2 = inter.num_light_outputs++; light_out_t *light_out2 = &inter.light_out_list[hd->pairs[i].light_out_2]; light_out2->f[1] = inter.fsig; light_out2->phi[1] = 0; for (field_index = 0; field_index < mem.num_fields; field_index++) { light_out2->masking_factor[field_index] = 1.0; } light_out2->beam_mask_is_set = false; light_out2->detector_type = -1; light_out2->output_idx = inter.num_outputs; // if we are computing a TF with just a 'hd' command we have complex outputs if(!hd->sensitivity && !hd->is_quantum){ light_out1->demod_phase_mode[1] = OFF; light_out2->demod_phase_mode[1] = OFF; } else { light_out1->demod_phase_mode[1] = OFF; light_out2->demod_phase_mode[1] = OFF; } } output_data->detector_type = MHOMODYNE; output_data->output_type = REAL; output_data->noplot = false; output_data->detector_index = inter.num_homodynes; hd->is_quantum = true; hd->output_index = inter.num_outputs; // if we are computing a TF with just a 'hd' command we have complex outputs if(!hd->sensitivity && !hd->is_quantum){ output_data->output_type = COMPLEX; } else { output_data->output_type = REAL; } output_data->detector_index = inter.num_mhomodynes; ++inter.num_outputs; ++inter.num_mhomodynes; } void read_sd_out(const char *command_string){ int n, m; char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char frequency_string[LINE_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; light_out_t *sqz_detector; output_data_t *output_data; sqz_detector = &(inter.light_out_list[inter.num_light_outputs]); output_data = &(inter.output_data_list[inter.num_outputs]); int num_vars_read = sscanf(command_string, "%s %s %s %d %d %s %80s", command_name, object_name, frequency_string, &n, &m, node_name, rest_string); int num_vars_expected = 6; if (num_vars_read < num_vars_expected) { num_vars_read = sscanf(command_string, "%s %s %s %s %80s", command_name, object_name, frequency_string, node_name, rest_string); num_vars_expected = 4; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'sd name [n m] f node[*]'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } n = m = 0; sqz_detector->field = 0; sqz_detector->field_is_set = false; } else { if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if ((n + m) > inter.tem && inter.tem_is_set) { gerror("Line `%s':\nn+m larger than max order of TEM (%s)\n", command_string, int_form(inter.tem)); } sqz_detector->field = get_field_index_from_tem(n, m); sqz_detector->field_is_set = true; // get_field_from_tem only works if maxtem is already set, so we need to double check: if (!inter.tem_is_set){ if (n+m==0) { sqz_detector->field = 0; } else{ sqz_detector->field = 1; warn("Line `%s':\n detector ignored because maxtem is off and n,m>0\n", command_string); } } } if (inter.num_light_outputs >= mem.num_light_outputs || inter.num_outputs >= mem.num_outputs) { gerror("Line `%s':\ntoo many amplitude detectors\n", command_string); } check_name(command_string, object_name); strcpy(sqz_detector->name, object_name); strcpy(output_data->name, object_name); if (inter.tem_is_set && !sqz_detector->field_is_set) { warn("Squeezing detector '%s' specified without mode indicees,\n Computing for TEM00.\n",object_name); } int last_char_index = strlen(node_name) - 1; output_data->is_second_beam = 0; if (node_name[last_char_index] == '*') { output_data->is_second_beam = 1; node_name[last_char_index] = '\0'; } if (get_node_index_for(node_name) == NODE_UNUSED) { gerror("Squeezing detector %s not connected to interferometer.\n", object_name); } double frequency; if (parse_frequency_input(frequency_string, &frequency, object_name, "f")) { gerror("Line `%s':\nUnable to read frequency\n", command_string); } else { sqz_detector->f[1] = frequency; } // grab the node index output_data->node_index = update_node_index_for(node_name, EITHER_DIR); // assert that the node index is in the correct range: assert(output_data->node_index >= 0); assert(output_data->node_index < inter.num_nodes); // calculate the reduced node index from the node index output_data->node_reduced_index = get_reduced_index_for(output_data->node_index); // assert that the reduced node index is in the correct range: assert(output_data->node_reduced_index >= 0); assert(output_data->node_reduced_index < inter.num_reduced_nodes); if (command_name[strlen(command_name)-1] != '*') output_data->detector_type = SD; else output_data->detector_type = SD2; output_data->output_type = COMPLEX; sqz_detector->sensitivity = OFF; sqz_detector->num_demods = 1; sqz_detector->beam_mask_is_set = false; inter.node_list[output_data->node_index].io = inter.node_list[output_data->node_index].io | 1; output_data->detector_index = inter.num_light_outputs; sqz_detector->output_idx = inter.num_outputs; output_data->noplot = false; ++inter.num_light_outputs; ++inter.num_outputs; } //! Read output amplitude detector command /*! * \param command_string the input command string * * \todo refactor routine for readability */ void read_amp_out(const char *command_string) { int n, m; char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char frequency_string[LINE_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; light_out_t *amplitude_detector; output_data_t *output_data; amplitude_detector = &(inter.light_out_list[inter.num_light_outputs]); output_data = &(inter.output_data_list[inter.num_outputs]); int num_vars_read = sscanf(command_string, "%s %s %d %d %s %s %80s", command_name, object_name, &n, &m, frequency_string, node_name, rest_string); int num_vars_expected = 6; if (num_vars_read < num_vars_expected) { num_vars_read = sscanf(command_string, "%s %s %s %s %80s", command_name, object_name, frequency_string, node_name, rest_string); num_vars_expected = 4; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'ad name [n m] f node[*]'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } n = m = 0; amplitude_detector->field = 0; amplitude_detector->field_is_set = false; } else { if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if ((n + m) > inter.tem && inter.tem_is_set) { gerror("Line `%s':\nn+m larger than max order of TEM (%s)\n", command_string, int_form(inter.tem)); } amplitude_detector->field = get_field_index_from_tem(n, m); amplitude_detector->field_is_set = true; // get_field_from_tem only works if maxtem is already set, so we need to double check: if (!inter.tem_is_set){ if (n+m==0) { amplitude_detector->field = 0; } else{ amplitude_detector->field = 1; warn("Line `%s':\n detector ignored because maxtem is off and n,m>0\n", command_string); } } } if (inter.num_light_outputs >= mem.num_light_outputs || inter.num_outputs >= mem.num_outputs) { gerror("Line `%s':\ntoo many amplitude detectors\n", command_string); } check_name(command_string, object_name); strcpy(amplitude_detector->name, object_name); strcpy(output_data->name, object_name); if (inter.tem_is_set && !amplitude_detector->field_is_set) { warn("Amplitude detector '%s' specified without mode indices, computing average amplitude (and dummy phase) over all modes.\n",object_name); } int last_char_index = strlen(node_name) - 1; output_data->is_second_beam = 0; if (node_name[last_char_index] == '*') { output_data->is_second_beam = 1; node_name[last_char_index] = '\0'; } if (get_node_index_for(node_name) == NODE_UNUSED) { gerror("amplitude detector %s not connected to interferometer.\n", object_name); } double frequency; if (parse_frequency_input(frequency_string, &frequency, object_name, "f")) { gerror("Line `%s':\nUnable to read frequency\n", command_string); } else { amplitude_detector->f[1] = frequency; } // grab the node index output_data->node_index = update_node_index_for(node_name, EITHER_DIR); // assert that the node index is in the correct range: assert(output_data->node_index >= 0); assert(output_data->node_index < inter.num_nodes); // calculate the reduced node index from the node index output_data->node_reduced_index = get_reduced_index_for(output_data->node_index); // assert that the reduced node index is in the correct range: assert(output_data->node_reduced_index >= 0); assert(output_data->node_reduced_index < inter.num_reduced_nodes); output_data->detector_type = AD; output_data->output_type = COMPLEX; output_data->qx = &(inter.node_list[output_data->node_index].qx); output_data->qy = &(inter.node_list[output_data->node_index].qy); amplitude_detector->sensitivity = OFF; amplitude_detector->num_demods = 1; // aout->c[0]=0; int field_index; for (field_index = 0; field_index < mem.num_fields; field_index++) { amplitude_detector->masking_factor[field_index] = 1.0; } amplitude_detector->beam_mask_is_set = false; inter.node_list[output_data->node_index].io = inter.node_list[output_data->node_index].io | 1; output_data->detector_index = inter.num_light_outputs; amplitude_detector->output_idx = inter.num_outputs; output_data->noplot = false; ++inter.num_light_outputs; ++inter.num_outputs; } /** * Parses a command string for the vacuum command which sets the listed nodes * as quantum inputs. * * \param count true if should count memory needed */ void read_vacuum(const char *command_string, bool counting){ char command_name[MAX_TOKEN_LEN] = {0}; char comp_name[MAX_TOKEN_LEN] = {0}; char rest_string[MAX_TOKEN_LEN] = {0}; char tmp[MAX_TOKEN_LEN] = {0}; // if a vacuum command is specified switch all components off inter.all_quantum_components = false; int n = sscanf(command_string, "%s %[^\n]", command_name, rest_string); if(n <= 1) gerror("Line `%s':\n" "expected 'vacuum node_name_1 [node_name_2 [node_name_3 [...]]]'\n", command_string); do { // read next component if there is one strcpy(tmp, rest_string); n = sscanf(tmp, "%s %[^\n]", comp_name, rest_string); // if user is setting all quantum noise inputs on... if(strcasecmp("all", comp_name)==0){ inter.all_quantum_components = true; // as we are potentially using all inputs // we need to set the memory later once // all components have been counted if(counting) mem.num_quantum_components = 0; return; } if(counting){ mem.num_quantum_components++; } else { int cidx = get_component_index_from_name(comp_name); if(cidx == NOT_FOUND){ gerror("Line `%s':\n Could not find component `%s`'\n",command_string, comp_name); } else { int i; bool not_found = true; // check if already added, if so warn and continue... for(i=0; i 1); } //! Read output quantum noise detector command /*! * \param command_string the input command string * * \todo refactor routine for readability * * \todo QN_AND_RP_OFF, QN_AND_RP, RP_ONLY branches are untested * \todo multiple demodulations branch untested */ void read_qnoised_cmd(const char *command_string) { char object_name[MAX_TOKEN_LEN] = {0}; char num_demods_string[LINE_LEN] = {0}; char node_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; // initially, try to read the command with qnoise_type included // if it's not there, then try to read the command without int num_vars_read = sscanf(command_string, "%s %s %s %[^\n]", command_name, object_name, num_demods_string, rest_string); int num_vars_expected = 4; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\n" "expected 'qnoised name num_demods f1 phase1 [f2 phase2 [...]] node[*]'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_light_outputs >= mem.num_light_outputs || inter.num_outputs >= mem.num_outputs) { gerror("Line `%s':\ntoo many quantum noise detectors\n", command_string); } // read the number of demodulations int num_demods = 0; // make sure that it is a digit if (NOT isdigit((int)(num_demods_string[0]))) { gerror("Line `%s':\n" "Number of demodulations is not a digit\n", command_string); } else { num_demods_string[1] = '\0'; if (my_atoi(num_demods_string, &num_demods)) { bug_error("failed char to integer conversion"); } } // if the number of demodulations is too large, then set it to zero if (num_demods > MAX_DEMOD) { gerror("Line `%s':\n" "Number of demodulations too large\n", command_string); } // now we just need to read the remainder of the command string, and // assign the frequencies and phases appropriately // set up the detector and output data objects light_out_t *quantum_noise_detector; quantum_noise_detector = &(inter.light_out_list[inter.num_light_outputs]); // check to see if we're using the sensitivity option if (strncasecmp(command_name, "qnoisedS", 8) == 0) { quantum_noise_detector->sensitivity = ON; } else if (strncasecmp(command_name, "qnoisedN", 8) == 0) { quantum_noise_detector->sensitivity = NORM; } else { quantum_noise_detector->sensitivity = OFF; } /*! * \todo copy and pasted code from qshot reading routine!!! This can be * refactored!!! */ // read the command for an arbitrary number of demodulations // we need to work on a copy of the command string as it's a const char cmd_str_copy[LINE_LEN] = {0}; strcpy(cmd_str_copy, command_string); // split the command string into its tokens char *token_pointer; token_pointer = strtok(cmd_str_copy, " "); // get the first token (cmd name) // skip the next three tokens: // (the object name, the quantum noise type and the number of demods) int token_index; for (token_index = 0; token_index < 2; token_index++) { token_pointer = strtok(NULL, " "); if (token_pointer == NULL) { gerror("Line `%s':\n" "Found end of string while processing command line\n", command_string); } } char * node_token = NULL; bool usesMax = false; // now get the frequency and phase pairs for each demodulation int demod_index; for (demod_index = 0; demod_index < num_demods; demod_index++) { token_pointer = strtok(NULL, " "); // grab the frequency if (token_pointer != NULL) { double frequency; char var_name[LINE_LEN] = {0}; sprintf(var_name, "f%i", demod_index+1); if (parse_frequency_input(token_pointer, &frequency, object_name, var_name)) { gerror("Line `%s':\nUnable to read demodulation frequency\n", command_string); } else { quantum_noise_detector->f[demod_index + 1] = frequency; } } else { gerror("Line `%s':\n" "Expected a demodulation frequency but found end of string instead\n", command_string); } // now grab the phase token_pointer = strtok(NULL, " "); if (token_pointer != NULL) { double phase; if (isalpha((int)(token_pointer[0]))) { if (NOT strncasecmp(token_pointer, "max", 3)) { usesMax = true; quantum_noise_detector->phi[demod_index + 1] = 0.0; quantum_noise_detector->demod_phase_mode[demod_index + 1] = MAX_PHASE; } else if(demod_index != num_demods-1){ gerror("Line `%s':\n" "Demodulation phase looks like a character but was unreadable\n", command_string); } else if(demod_index == num_demods-1){ quantum_noise_detector->phi[demod_index + 1] = 0.0; if(quantum_noise_detector->sensitivity == OFF) quantum_noise_detector->demod_phase_mode[demod_index + 1] = USER_PHASE; else quantum_noise_detector->demod_phase_mode[demod_index + 1] = MAX_PHASE; node_token = token_pointer; } } else if (atod(token_pointer, &phase)) { gerror("Line `%s':\nUnable to read demodulation phase\n", command_string); } else { quantum_noise_detector->phi[demod_index + 1] = phase; quantum_noise_detector->demod_phase_mode[demod_index + 1] = USER_PHASE; } } else { gerror("Line `%s':\n" "Expected a demodulation phase but found end of string instead\n", command_string); } } // there should now only be the node name remaining token_pointer = strtok(NULL, " "); if (token_pointer != NULL) { strcpy(node_name, token_pointer); } else if(node_token != NULL) { strcpy(node_name, node_token); } else { gerror("Line `%s':\n" "Expected node_name but found end of string instead\n", command_string); } // make sure that node_name is something sensible (i.e. its first // character should be alphabetic if (NOT isalpha((int)(node_name[0]))) { gerror("Line `%s':\n" "Node name '%s' doesn't look like a name\n", command_string, node_name); } // make sure we've not got any negative frequencies for (demod_index = 1; demod_index < num_demods + 1; demod_index++) { if (quantum_noise_detector->f[demod_index] < 0) { gerror("Cannot have negative demodulation frequencies in qnoised\n"); } } if(quantum_noise_detector->sensitivity == OFF){ if(usesMax) { warn("Line `%s':\n" "'max' phase is only available in qnoiseS or qnoiseN\n" "State exact demodulation phase or 'max' default to 0.\n", command_string); } } output_data_t *output_data; output_data = &(inter.output_data_list[inter.num_outputs]); check_name(command_string, object_name); strcpy(quantum_noise_detector->name, object_name); strcpy(output_data->name, object_name); // check if the beam is actually in the other direction... int last_char_index = strlen(node_name) - 1; output_data->is_second_beam = 0; if (node_name[last_char_index] == '*') { output_data->is_second_beam = 1; node_name[last_char_index] = '\0'; } if (get_node_index_for(node_name) == NODE_UNUSED) { gerror("quantum noise detector %s not connected to interferometer.\n", object_name); } // grab the node index output_data->node_index = update_node_index_for(node_name, EITHER_DIR); // assert that the node index is in the correct range assert(output_data->node_index >= 0); assert(output_data->node_index < inter.num_nodes); // calculate the reduced node index from the node index output_data->node_reduced_index = get_reduced_index_for(output_data->node_index); // assert that the reduced node index is in the correct range assert(output_data->node_reduced_index >= 0); assert(output_data->node_reduced_index < inter.num_reduced_nodes); output_data->detector_type = QNOISE; output_data->output_type = COMPLEX; output_data->qx = &(inter.node_list[output_data->node_index].qx); output_data->qy = &(inter.node_list[output_data->node_index].qy); num_demods = 0; num_demods_string[1] = '\0'; if (my_atoi(num_demods_string, &num_demods)) { gerror("Line `%s':\nUnable to read number of demodulations\n", command_string); } else { quantum_noise_detector->num_demods = num_demods; } //!< \todo TODO put setting of related things in the same location!!! // quantum_noise_detector->c[0]=0; int field_index; for (field_index = 0; field_index < mem.num_fields; field_index++) { quantum_noise_detector->masking_factor[field_index] = 1.0; } quantum_noise_detector->beam_mask_is_set = false; quantum_noise_detector->detector_type = -1; inter.node_list[output_data->node_index].io = inter.node_list[output_data->node_index].io | 1; output_data->detector_index = inter.num_light_outputs; quantum_noise_detector->output_idx = inter.num_outputs; output_data->noplot = false; ++inter.num_light_outputs; ++inter.num_outputs; } int get_dither_order(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char frequency_string[LINE_LEN] = {0}; char modulation_string[LINE_LEN] = {0}; int modulation_order; char phase_string[LINE_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %s %s %s %d %s %80s", command_name, object_name, frequency_string, modulation_string, &modulation_order, phase_string, rest_string); if (num_vars_read == 7) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); num_vars_read--; } if (num_vars_read !=6) gerror("Line `%s':\n" "expected 'dither component f midx order phase\n", command_string); return 2 * modulation_order; } void read_dither(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char frequency_string[LINE_LEN] = {0}; char modulation_string[LINE_LEN] = {0}; int modulation_order; char phase_string[LINE_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %s %s %s %d %s %80s", command_name, object_name, frequency_string, modulation_string, &modulation_order, phase_string, rest_string); if (num_vars_read == 7) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); num_vars_read--; } if (num_vars_read !=6) gerror("Line `%s':\n" "expected 'dither component f midx order phase\n", command_string); double f, phase, modulation_index; if (atod(frequency_string, &f)) { gerror("Line `%s':\nUnable to read frequency value\n", command_string); } if (atod(modulation_string, &modulation_index)) { gerror("Line `%s':\nUnable to read modulation index value\n", command_string); } if (eq(f, 0.0)) { gerror("Line `%s':\nfrequency must not be zero\n", command_string); } if (atod(phase_string, &phase)) { gerror("Line `%s':\nUnable to read phase\n", command_string); } int idx = get_component_index_from_name(object_name); if (idx == NOT_FOUND){ gerror("Line `%s':\nComponent '%s' was not found\n", command_string, object_name); } else { int component_type = get_component_type_decriment_index(&idx); if(component_type == MIRROR){ mirror_t *m = &inter.mirror_list[idx]; m->dither_f = f; m->dither_m = modulation_index; m->dither_order = modulation_order; m->dither_phase = phase; m->dither_list_index = inter.num_mirror_dithers; inter.mirror_dither_list[inter.num_mirror_dithers] = m; inter.num_mirror_dithers++; } else if(component_type == BEAMSPLITTER){ beamsplitter_t *bs = &inter.bs_list[idx]; bs->dither_f = f; bs->dither_m = modulation_index; bs->dither_order = modulation_order; bs->dither_phase = phase; bs->dither_list_index = inter.num_bs_dithers; inter.bs_dither_list[inter.num_bs_dithers] = bs; inter.num_bs_dithers++; } else { gerror("Line `%s':\nOnly mirror and beamsplitter components can be dithered\n", command_string); } } } //! Read EOM (electro-optic modulator) /*! * \param command_string the input command string * * \todo almost all modulator input permutations are untested */ void read_modulator(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char mod_type[MAX_TOKEN_LEN] = {0}; char frequency_string[LINE_LEN] = {0}; char modulation_index_string[LINE_LEN] = {0}; char phase_string[LINE_LEN] = {0}; char single_sideband_mode_string[4] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; debug_msg("read_modulator()\n"); if (inter.num_light_inputs == 0) { gerror("Line `%s':\nSpecify input before any modulators\n", command_string); } if (inter.num_signals) { gerror("Line `%s':\n" "Specify modulators before any signal frequencies\n", command_string); } int modulation_order; int num_vars_read = sscanf(command_string, "%s %s %s %s %d %5s %s %s %s %80s", command_name, object_name, frequency_string, modulation_index_string, &modulation_order, mod_type, phase_string, node1_name, node2_name, rest_string); if (num_vars_read < 9) { num_vars_read = sscanf(command_string, "%s %s %s %s %d %5s %s %s %80s", command_name, object_name, frequency_string, modulation_index_string, &modulation_order, mod_type, node1_name, node2_name, rest_string); if (num_vars_read < 8) { num_vars_read = sscanf(command_string, "%s %s %s %s %1s %5s %s %s %s %80s", command_name, object_name, frequency_string, modulation_index_string, single_sideband_mode_string, mod_type, phase_string, node1_name, node2_name, rest_string); if (num_vars_read < 9 || strncasecmp(single_sideband_mode_string, "s", 1)) { num_vars_read = sscanf(command_string, "%s %s %s %s %1s %5s %s %s %80s", command_name, object_name, frequency_string, modulation_index_string, single_sideband_mode_string, mod_type, node1_name, node2_name, rest_string); if (num_vars_read < 8 || strncasecmp(single_sideband_mode_string, "s", 1)) { gerror("Line `%s':\n" "expected 'mod name f midex order am/pm/yaw/pitch " "[phase] node1 node2'\n", command_string); } else { if (num_vars_read > 8) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } } else { if (num_vars_read > 9) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } } else { if (num_vars_read > 8) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } } else { if (num_vars_read > 9) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } if (inter.num_modulators >= mem.num_modulators) { gerror("Line `%s':\ntoo many modulators\n", command_string); } modulator_t *modulator; modulator = &(inter.modulator_list[inter.num_modulators]); modulator->numerical_f_couple = 1; if (strncasecmp(single_sideband_mode_string, "s", 1) == 0) { modulation_order = 1; modulator->single_sideband_mode = ON; // single-sideband (SSB) mode } else { modulator->single_sideband_mode = OFF; } if (strncasecmp(mod_type, "am", 2) == 0) { modulator->type = MODTYPE_AM; } else if (strncasecmp(mod_type, "pm", 2) == 0) { modulator->type = MODTYPE_PM; } else if (strncasecmp(mod_type, "yaw", 3) == 0) { modulator->type = MODTYPE_YAW; } else if (strncasecmp(mod_type, "pitch", 5) == 0) { modulator->type = MODTYPE_PITCH; } else { gerror("Line `%s':\n" "expected 'mod name f midex order am/pm/yaw/pitch node1 node2'\n", command_string); } if ((modulation_order < 1) || (modulation_order >= MAX_ORDER)) { gerror("Line `%s':\norder must between 1 and %s'\n", command_string, long_form(MAX_ORDER - 1, 0)); } // read modulation index double modulation_index; if (atod(modulation_index_string, &modulation_index)) { gerror("Line `%s':\nUnable to read modulation index\n", command_string); } if (modulator->type == MODTYPE_AM) { if (modulation_order > 1) { warn("Line `%s':\nusing order=1 for amplitude modulation.\n", command_string); modulation_order = 1; } if (modulation_index > 1) { warn("Line `%s':\n" "using midx=1 as max. modulation index for amplitude modulation.\n", command_string); modulation_index = 1; } } modulator->modulation_index = modulation_index; modulator->order = modulation_order; check_name(command_string, object_name); strcpy(modulator->name, object_name); // grab the node indices modulator->node1_index = update_node_index_for(node1_name, IN_OUT); modulator->node2_index = update_node_index_for(node2_name, OUT_IN); connect_component_to_node(modulator->node1_index, (void*)modulator, MODULATOR); connect_component_to_node(modulator->node2_index, (void*)modulator, MODULATOR); // calculate the reduced node indices from the node indices modulator->node1_reduced_index = get_reduced_index_for(modulator->node1_index); modulator->node2_reduced_index = get_reduced_index_for(modulator->node2_index); double f; if (atod(frequency_string, &f)) { gerror("Line `%s':\nUnable to read frequency value\n", command_string); } else { modulator->f_mod = f; } if (eq(f, 0.0)) { gerror("Line `%s':\nfrequency must not be zero\n", command_string); } if (num_vars_read == 9) { double phase; if (atod(phase_string, &phase)) { gerror("Line `%s':\nUnable to read phase\n", command_string); } else { modulator->phase = phase; } } else { modulator->phase = 0.0; } ++inter.num_modulators; ++inter.num_components; check_modulator(modulator); } //! Preread a modulator and get its modulation order /*! * \param command_string the input command string * * \return the modulation order * * \todo all but one command syntax path untested */ int get_modulation_order(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char ampm[MAX_TOKEN_LEN] = {0}; char frequency_string[LINE_LEN] = {0}; char modulation_index_string[LINE_LEN] = {0}; char phase_string[LINE_LEN] = {0}; char single_sideband_mode[4] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; int modulation_order; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %s %s %s %d %5s %s %s %s %80s", command_name, object_name, frequency_string, modulation_index_string, &modulation_order, ampm, phase_string, node1_name, node2_name, rest_string); if (num_vars_read < 8) { num_vars_read = sscanf(command_string, "%s %s %s %s %d %5s %s %s %80s", command_name, object_name, frequency_string, modulation_index_string, &modulation_order, ampm, node1_name, node2_name, rest_string); if (num_vars_read < 7) { num_vars_read = sscanf(command_string, "%s %s %s %s %1s %5s %s %s %s %80s", command_name, object_name, frequency_string, modulation_index_string, single_sideband_mode, ampm, phase_string, node1_name, node2_name, rest_string); if (num_vars_read < 8 || strncasecmp(single_sideband_mode, "s", 1)) { num_vars_read = sscanf(command_string, "%s %s %s %s %1s %5s %s %s %80s", command_name, object_name, frequency_string, modulation_index_string, single_sideband_mode, ampm, node1_name, node2_name, rest_string); if (num_vars_read < 7 || strncasecmp(single_sideband_mode, "s", 1)) { gerror("Line `%s':\n" "expected 'mod name f midex order am/pm/yaw/pitch [phase] " "node1 node2'\n", command_string); } } } } // many of the variables are set but never used, this is ok, however as we // are only interested in getting the modulation order. We can used these // "unused" variables to make sure that the command line was processed // properly double f; if (atod(frequency_string, &f)) { gerror("Line `%s':\nUnable to read frequency\n", command_string); } double modulation_index; if (atod(modulation_index_string, &modulation_index)) { gerror("Line `%s':\nUnable to read modulation index\n"); } if (num_vars_read == 7) { double phase; if (atod(phase_string, &phase)) { gerror("Line `%s':\nUnable to read phase\n"); } } bool single_sideband_mode_is_set; if (strncasecmp(single_sideband_mode, "s", 1) == 0) { modulation_order = 1; single_sideband_mode_is_set = true; // single-sideband (SSB) mode } else { single_sideband_mode_is_set = false; } int modulation_type = -1; if (strncasecmp(ampm, "am", 2) == 0) { modulation_type = MODTYPE_AM; } else if (strncasecmp(ampm, "pm", 2) == 0) { modulation_type = MODTYPE_PM; } else if (strncasecmp(ampm, "yaw", 3) == 0) { modulation_type = MODTYPE_YAW; } else if (strncasecmp(ampm, "pitch", 5) == 0) { modulation_type = MODTYPE_PITCH; } else { gerror("Line `%s':\n" "expected 'mod name f midex order am/pm/yaw/pitch node1 node2'\n", command_string); } if ((modulation_order < 1) || (modulation_order >= MAX_ORDER)) { gerror("Line `%s':\norder must between 1 and %s'\n", command_string, long_form(MAX_ORDER - 1, 0)); } if (modulation_type == MODTYPE_AM) { if (modulation_order > 1) { warn("Line `%s':\nusing order=1 for amplitude modulation.\n", command_string); modulation_order = 1; } if (modulation_index > 1) { warn("Line `%s':\n" "using midx=1 as max. modulation index for " "amplitude modulation.\n", command_string); modulation_index = 1; } } if (single_sideband_mode_is_set) { return (modulation_order); } else { return (2 * modulation_order); } } //! Read the signal frequency /*! * \param command_string the input command string */ void read_fsig(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char frequency_string[LINE_LEN] = {0}; char phase_string[LINE_LEN] = {0}; char amplitude_string[LINE_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char type[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; double f; signal_t *signal = &(inter.signal_list[inter.num_signals]); if (inter.num_signals >= mem.num_signal_inputs) { gerror("Line `%s':\ntoo many signal frequencies (fsig).\n", command_string); } if (inter.num_light_inputs == 0) { gerror("Line `%s':\nSpecify input before any signal frequencies\n", command_string); } bool type_is_set = false; endcomp = 1; lastparam = -1; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %s %80s", command_name, object_name, component_name, type, frequency_string, phase_string, amplitude_string, rest_string); bool frequency_read_failed = atod(frequency_string, &f); if (num_vars_read < 7 || frequency_read_failed) { num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %80s", command_name, object_name, component_name, frequency_string, phase_string, amplitude_string, rest_string); frequency_read_failed = atod(frequency_string, &f); if (num_vars_read < 6 || frequency_read_failed) { num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %80s", command_name, object_name, component_name, type, frequency_string, phase_string, rest_string); frequency_read_failed = atod(frequency_string, &f); if (num_vars_read < 6 || frequency_read_failed) { num_vars_read = sscanf(command_string, "%s %s %s %s %s %80s", command_name, object_name, component_name, frequency_string, phase_string, rest_string); frequency_read_failed = atod(frequency_string, &f); if (num_vars_read < 3 || (num_vars_read > 4 && frequency_read_failed)) { gerror("Line `%s':\n" "expected 'fsig name component [type] f phase [amp]'\n" " or 'fsig name f'\n", command_string); } else if (num_vars_read > 5) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } else { type_is_set = true; if (num_vars_read > 6) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } } else if (num_vars_read > 6) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } else { type_is_set = true; if (num_vars_read > 7) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } } bool using_none_signal = false; int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { if(atod(component_name, &f)) { gerror("Line `%s':\ncomponent name '%s' not found.\n", command_string, component_name); } else { using_none_signal = true; } } if(using_none_signal) { check_name(command_string, object_name); strcpy(signal->name, object_name); signal->type = NOSIGNAL; if (f <= 0.0) { gerror("Line `%s':\nSignal frequency must be positive and greater than 0Hz\n", command_string); } if (inter.fsig != 0.0) { if (inter.fsig != f) { warn("Line `%s':\n" "only one signal frequency possible,\n using first frequency.\n", command_string); } } else { inter.fsig = f; inter.mfsig = -f; } inter.num_signals++; } else { if (type_is_set) { if ((signal->type = get_signal_type(type)) == NOT_FOUND) { // check type input gerror("Line `%s':\ninvalid signal type\n", command_string); } } int component_type = get_component_type_decriment_index(&component_index); signal->component_index = component_index; signal->component_type = component_type; switch (component_type) { case BEAMSPLITTER: init_beamsplitter_signal(signal, component_index, type_is_set, command_string); break; case MIRROR: init_mirror_signal(signal, component_index, type_is_set, type, command_string); break; case SPACE: init_space_signal(signal, component_index, type_is_set, command_string); break; case LIGHT_INPUT: init_light_input_signal(signal, component_index, type_is_set, command_string); break; case MODULATOR: init_modulator_signal(signal, component_index, type_is_set, command_string); break; default: gerror("Line `%s':\ninvalid component\n", command_string); } if (f <= 0.0) { gerror("Line `%s':\nSignal frequency must be positive and greater than 0Hz\n", command_string); } check_name(command_string, object_name); strcpy(signal->name, object_name); if (inter.fsig != 0.0) { if (inter.fsig != f) { warn("Line `%s':\n" "only one signal frequency possible,\n using first frequency.\n", command_string); } } else { inter.fsig = f; inter.mfsig = -f; } if (atod(phase_string, &(signal->phase))) { int i; signal->tf = NULL; for(i=0; itf = &(inter.tf_list[i]); } } if(signal->tf == NULL) gerror("Line `%s':\nUnable to read phase\n", command_string); } double signal_amplitude = 0.0; if ((num_vars_read == 6 && NOT type_is_set) || (num_vars_read == 7 && type_is_set)) { if (atod(amplitude_string, &signal_amplitude)) { gerror("Line `%s':\nUnable to read signal amplitude\n", command_string); } signal->amplitude = signal_amplitude; } else { signal->amplitude = 1.0; } inter.num_signals++; } } //! Initialises the signal field attributes at a beam splitter /*! * \param signal the signal object to initialise * \param component_index index of the current component * \param type_is_set whether or not the type has been set by the user * \param command_string the command string entered in the .kat file */ void init_beamsplitter_signal( signal_t *signal, int component_index, bool type_is_set, const char *command_string) { beamsplitter_t *beamsplitter; beamsplitter = &inter.bs_list[component_index]; // set the node indices signal->node1_index = &beamsplitter->node1_index; signal->node2_index = &beamsplitter->node2_index; signal->node3_index = &beamsplitter->node3_index; signal->node4_index = &beamsplitter->node4_index; // check that the node indices are set correctly assert(*(signal->node1_index) >= 0); assert(*(signal->node2_index) >= 0); assert(*(signal->node3_index) >= 0); assert(*(signal->node4_index) >= 0); assert(*(signal->node1_index) < inter.num_nodes); assert(*(signal->node2_index) < inter.num_nodes); assert(*(signal->node3_index) < inter.num_nodes); assert(*(signal->node4_index) < inter.num_nodes); // set the reduced node indice)s signal->node1_reduced_index = get_reduced_index_for(*(signal->node1_index)); signal->node2_reduced_index = get_reduced_index_for(*(signal->node2_index)); signal->node3_reduced_index = get_reduced_index_for(*(signal->node3_index)); signal->node4_reduced_index = get_reduced_index_for(*(signal->node4_index)); // check that the reduced node indices are set correctly assert(signal->node1_reduced_index >= 0); assert(signal->node2_reduced_index >= 0); assert(signal->node3_reduced_index >= 0); assert(signal->node4_reduced_index >= 0); assert(signal->node1_reduced_index < inter.num_reduced_nodes); assert(signal->node2_reduced_index < inter.num_reduced_nodes); assert(signal->node3_reduced_index < inter.num_reduced_nodes); assert(signal->node4_reduced_index < inter.num_reduced_nodes); if (type_is_set) { if (signal->type != SIG_AMP && signal->type != SIG_PHS && signal->type != SIG_X && signal->type != SIG_Y && signal->type != SIG_Z && signal->type != SIG_FZ && signal->type != SIG_FRY && signal->type != SIG_FRX) { gerror("Line `%s':\ninvalid signal type for a beam splitter\n", command_string); } } else { signal->type = SIG_PHS; // setting default signal type = phase modulation } } //! Initialises the signal field attributes at a mirror /*! * \param signal the signal object to initialise * \param component_index index of the current component * \param type_is_set whether or not the type has been set by the user * \param command_string the command string entered in the .kat file */ void init_mirror_signal( signal_t *signal, int component_index, bool type_is_set, const char *signal_type_string, const char *command_string) { mirror_t *mirror; mirror = &inter.mirror_list[component_index]; // set the node indices signal->node1_index = &(mirror->node1_index); signal->node2_index = &(mirror->node2_index); // check that the node indices are set correctly assert(*(signal->node1_index) >= 0); assert(*(signal->node2_index) >= 0); assert(*(signal->node1_index) < inter.num_nodes); assert(*(signal->node2_index) < inter.num_nodes); // set the reduced node indices signal->node1_reduced_index = get_reduced_index_for(*(signal->node1_index)); signal->node2_reduced_index = get_reduced_index_for(*(signal->node2_index)); // check that the reduced node indices are set correctly assert(signal->node1_reduced_index >= 0); assert(signal->node2_reduced_index >= 0); assert(signal->node1_reduced_index < inter.num_reduced_nodes); assert(signal->node2_reduced_index < inter.num_reduced_nodes); if (type_is_set) { if (signal->type == SIG_SURF) { int num = sscanf(signal_type_string, "s%i", &(signal->surface_mode_index)); if(num != 1 || signal->surface_mode_index < 0) { gerror("Line `%s':\ninvalid signal type for a mirror\n", command_string); } } else if (signal->type == SIG_FSURF) { int num = sscanf(signal_type_string, "Fs%i", &(signal->surface_mode_index)); if(num != 1 || signal->surface_mode_index < 0) { gerror("Line `%s':\ninvalid signal type for a mirror\n", command_string); } } else if (signal->type != SIG_AMP && signal->type != SIG_PHS && signal->type != SIG_X && signal->type != SIG_Y && signal->type != SIG_Z && signal->type != SIG_FZ && signal->type != SIG_FRY && signal->type != SIG_FRX) { gerror("Line `%s':\ninvalid signal type for a mirror\n", command_string); } } else { signal->type = SIG_PHS; // setting default signal type = phase modulation } } //! Initialises the signal field attributes at a space /*! * \param signal the signal object to initialise * \param component_index index of the current component * \param type_is_set whether or not the type has been set by the user * \param command_string the command string entered in the .kat file */ void init_space_signal( signal_t *signal, int component_index, bool type_is_set, const char *command_string) { space_t *space; space = &inter.space_list[component_index]; // set the node indices signal->node1_index = &(space->node1_index); signal->node2_index = &(space->node2_index); // check that the node indices are set correctly assert(*(signal->node1_index) >= 0); assert(*(signal->node2_index) >= 0); assert(*(signal->node1_index) < inter.num_nodes); assert(*(signal->node2_index) < inter.num_nodes); // set the reduced node indices signal->node1_reduced_index = get_reduced_index_for(*(signal->node1_index)); signal->node2_reduced_index = get_reduced_index_for(*(signal->node2_index)); // check that the reduced node indices are set correctly // they should lie in the range: assert(signal->node1_reduced_index >= 0); assert(signal->node2_reduced_index >= 0); assert(signal->node1_reduced_index < inter.num_reduced_nodes); assert(signal->node2_reduced_index < inter.num_reduced_nodes); if (type_is_set) { if (signal->type != SIG_AMP && signal->type != SIG_PHS && signal->type != SIG_SAGNAC) { gerror("Line `%s':\ninvalid signal type for a space\n", command_string); } } else { signal->type = SIG_PHS; // setting default signal type = phase modulation } //! \todo need a return here one day!!! } //! Initialises the signal field attributes at a light input /*! * \param signal the signal object to initialise * \param component_index index of the current component * \param type_is_set whether or not the type has been set by the user * \param command_string the command string entered in the .kat file */ void init_light_input_signal( signal_t *signal, int component_index, bool type_is_set, const char *command_string) { light_in_t *laser; laser = &inter.light_in_list[component_index]; if(laser->modulation_signal != NULL) gerror("The fsig %s has already been applied to laser %s, could not add %s.", laser->modulation_signal->name, laser->name, signal->name); laser->modulation_signal = signal; // set the node index signal->node1_index = &(laser->node_index); // check that the node index is set correctly assert(*(signal->node1_index) >= 0); assert(*(signal->node1_index) < inter.num_nodes); // set the reduced node index signal->node1_reduced_index = get_reduced_index_for(*(signal->node1_index)); // check that the reduced node index is set correctly assert(signal->node1_reduced_index >= 0); assert(signal->node1_reduced_index < inter.num_reduced_nodes); if (type_is_set) { if (signal->type != SIG_AMP && signal->type != SIG_PHS && signal->type != SIG_FRQ) { gerror("Line `%s':\ninvalid signal type for an input\n", command_string); } } else { signal->type = SIG_FRQ; // setting default signal type = frequency modulation } //! \todo need a return here one day!!! } //! Initialises the signal field attributes at a modulator /*! * \param signal the signal object to initialise * \param component_index index of the current component * \param type_is_set whether or not the type has been set by the user * \param command_string the command string entered in the .kat file * * \todo untested */ void init_modulator_signal( signal_t *signal, int component_index, bool type_is_set, const char *command_string) { modulator_t *modulator; modulator = &inter.modulator_list[component_index]; // set the node indices signal->node1_index = &(modulator->node1_index); signal->node2_index = &(modulator->node2_index); // check that the node indices are set correctly assert(*(signal->node1_index) >= 0); assert(*(signal->node2_index) >= 0); assert(*(signal->node1_index) < inter.num_nodes); assert(*(signal->node2_index) < inter.num_nodes); // set the reduced node indices signal->node1_reduced_index = get_reduced_index_for(*(signal->node1_index)); signal->node2_reduced_index = get_reduced_index_for(*(signal->node2_index)); // check that the reduced node indices are set correctly assert(signal->node1_reduced_index >= 0); assert(signal->node2_reduced_index >= 0); assert(signal->node1_reduced_index < inter.num_reduced_nodes); assert(signal->node2_reduced_index < inter.num_reduced_nodes); if (type_is_set) { if (signal->type != SIG_AMP && signal->type != SIG_PHS) { gerror("Line `%s':\ninvalid signal type for a modulator\n", command_string); } } else { signal->type = SIG_PHS; // setting default signal type = phase modulation } //! \todo need a return here one day!!! } //! Read phase/amplitude function for synthetic map /*! * This function creates a synthetic map from polynomial coefficients. * Code needs cleaning and updating! * * \param command_string the input command string */ void read_and_set_map_function(const char *command_string) { // silence compiler warning char tmp[LINE_LEN]; strcpy(tmp, command_string); } //! Read attribute command /*! * This command is used to set various attributes of components without the * value having to be explicitly given with the component specification. * * \param command_string the input command string * * \todo last two else branches when parsing input string are untested */ void read_attribute(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char parameter_value_string[LINE_LEN] = {0}; char parameter_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; char tmp[LINE_LEN] = {0}; int n = sscanf(command_string, "%s %s %[^\n]", command_name, component_name, rest_string); if(n <= 2) gerror("Line `%s':\nCould not parse line\n", command_string); else if(n != 3) gerror("Line `%s':\nNo parameter/value pairs were input\n", command_string); do{ strcpy(tmp, rest_string); n = sscanf(tmp, "%s %s %[^\n]", parameter_name, parameter_value_string, rest_string); if(n==0){ break; // nothing to process } if(n == 1) { gerror("Line `%s':\nNo value was provided for parameter %s\n\n", command_string, parameter_name); } else { check_and_set_attribute(parameter_name, parameter_value_string, command_string, component_name); } } while(n > 2); } void read_conf(const char *command_string) { #define CHECK_STR(S) if(strcmp(config_setting, S)==0) gerror("Line: '%s'\nDid not expect a string value '%s'\n", command_string, config_setting); #define GET_INT if(my_atoi(config_setting,&ival)) gerror("Line: '%s'\nCould not read an integer from '%s'\n", command_string, config_setting); #define WARNDEBUG if(!inter.debug) warn("For Line `%s' to work you must also specify the debug command\n",command_string); char command_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char config_name[LINE_LEN] = {0}; char config_setting[LINE_LEN] = {0}; char rest_string[LINE_LEN] = {0}; int ival; int num_vars_read = sscanf(command_string, "%s %s %s %s %1024[^\n]s", command_name, component_name, config_name, config_setting, rest_string); if (num_vars_read < 4) gerror("Line `%s':\nexpected 'conf component setting value'\n", command_string); //if (num_vars_read == 5) // warn("Line `%s':\nignoring text '%s'\n", command_string, rest_string); int cidx = get_component_index_from_name(component_name); if (cidx == NOT_FOUND) gerror("Line `%s':\nCould not find a component with name\n", command_string, component_name); int type = get_component_type(cidx); if (type == NOT_FOUND) bug_error("Could not find a type for the component %s", component_name); int idx = get_component_index(cidx); mirror_t *mirror; beamsplitter_t *bs; modulator_t * mod; switch (type) { case MODULATOR: mod = &inter.modulator_list[idx]; if (strcmp(config_name, "numerical_f_couple") == 0) { GET_INT if (ival < 0 || ival > 1) gerror("numerical_f_couple can only be 1 or 0\n"); mod->numerical_f_couple = ival; } else if (strcmp(config_name, "print_f_coupling") == 0) { GET_INT if (ival < 0 || ival > 1) gerror("print_f_coupling can only be 1 or 0\n"); mod->print_f_coupling = ival; } break; case BEAMSPLITTER: bs = &(inter.bs_list[idx]); if (strcmp(config_name, "interpolation_method") == 0) { GET_INT bs->map_merged.interpolation_method = ival; if (ival < 1 || ival > 4) gerror("Interpolation method is not a valid input, either:" " %i nearest neighbour, %i linear, %i - spline\n", NEAREST,LINEAR,SPLINE); } else if (strcmp(config_name, "interpolation_size") == 0) { GET_INT bs->map_merged.interpolation_size = ival; if (ival < 3) gerror("Interpolation size cannot be less than 3\n"); if (ival % 2 == 0) gerror("Interpolation size must be an odd integer\n"); } else if (strcmp(config_name, "integration_method") == 0) { GET_INT bs->map_merged.integration_method = ival; if (ival < 0 || ival > 4) gerror("Integration method must be: 1 - Riemann, 2 - Cuba serial, 3 - Cuba parallel, 4 - ROMHOM\n"); } else if (strcmp(config_name, "save_interp_file") == 0) { GET_INT bs->map_merged.save_interp_file = (bool) ival; if(ival != 1 && ival != 0) gerror("save_interp_file must be either 1 or 0 for true or false\n"); } else if (strcmp(config_name, "save_integration_points") == 0) { GET_INT bs->map_merged.save_integration_points = (bool) ival; if(ival != 1 && ival != 0) gerror("save_integration_points must be either 1 or 0 for true or false\n"); }else if (strcmp(config_name, "save_knm") == 0) { GET_INT bs->map_merged.save_to_file = (bool) ival; if (ival != 1 && ival != 0) gerror("save_knm must be either 1 " "or 0 for true or false\n"); } else if (strcmp(config_name, "show_knm_neval") == 0) { GET_INT WARNDEBUG; bs->map_merged.show_knm_neval = (bool) ival; if (ival != 1 && ival != 0) gerror("show_knm_neval must be either 1 or 0 for true or false\n"); } else if (strcmp(config_name, "save_knm_matrices") == 0) { GET_INT bs->map_merged.save_knm_matrices = (bool) ival; if (ival != 1 && ival != 0) gerror("save_knm_matrices must be either 1 or 0 for true or false\n"); } else if (strcmp(config_name, "save_knm_binary") == 0) { GET_INT bs->map_merged.knm_save_binary = (bool) ival; if (ival != 1 && ival != 0) gerror("knm_save_binary must be either 1 or 0 for true or false\n"); } else if (strcmp(config_name, "knm_flags") == 0) { GET_INT bs->knm_flags = (unsigned int) ival; if (ival < 0) gerror("knm_flags must be a positive integer\n"); } else if (strcmp(config_name, "knm_order") == 0) { int j; if( strlen(config_setting) != NUM_KNM_TYPES) gerror("knm_order must be 2 digits long, including only the numbers 1 or 2."); for(j=0; jknm_order[j] = i; } } else if (strcmp(config_name, "knm_change_q") == 0) { GET_INT if (ival < 1 || ival > 2) gerror("knm_change_q must be either 1 or 2\n"); bs->knm_change_q = ival; } else if (strcmp(config_name, "knm_force_saved") == 0) { GET_INT if (ival != 1 && ival != 0) gerror("knm_force_saved must be either 1 or 0 for true or false\n"); bs->knm_force_saved = (bool) ival; } else if (strcmp(config_name, "fRT") == 0) { char R[MAX_TOKEN_LEN], T[MAX_TOKEN_LEN]; int num_vars_read = sscanf(rest_string, "%s %s", R,T); if (num_vars_read != 2) gerror("fRTL must be in form `f_name R T`.\n"); fRT_t *kv = NULL; int id = strhash(config_setting); HASH_FIND_STR(bs->fRT, config_setting, kv); if (kv == NULL){ kv = malloc(sizeof(fRT_t)); kv->id = id; strcpy(kv->name, config_setting); if(atod(R, &kv->R)) gerror("Line: '%s'\nCould not read R from '%s'\n", command_string, config_setting); if(atod(T, &kv->T)) gerror("Line: '%s'\nCould not read T from '%s'\n", command_string, config_setting); HASH_ADD_STR(bs->fRT, name, kv); } else { gerror("Line: '%s'\nR,T already added for this frequency.\n", command_string); } } else gerror("Could not understand %s config setting for a mirror(%s)\n", config_name, bs->name); break; case MIRROR: mirror = &(inter.mirror_list[idx]); if (strcmp(config_name, "interpolation_method") == 0) { GET_INT mirror->map_merged.interpolation_method = ival; if (ival < 1 || ival > 4) gerror("Interpolation method is not a valid input, either:" " %i nearest neighbour, %i linear, %i - spline\n", NEAREST,LINEAR,SPLINE); } else if (strcmp(config_name, "integration_NC_order") == 0) { GET_INT mirror->map_merged.integration_NC_order = ival; if (ival < 0 || ival > MAX_NEWTON_WEIGHT) { gerror("integration NC order '%s' is not a valid input, either:" " 0 <= NC order <= %i\n", config_setting, MAX_NEWTON_WEIGHT); } } else if (strcmp(config_name, "interpolation_size") == 0) { GET_INT mirror->map_merged.interpolation_size = ival; if (ival < 3) gerror("Interpolation size cannot be less than 3\n"); if (ival % 2 == 0) gerror("Interpolation size must be an odd integer\n"); } else if (strcmp(config_name, "integration_method") == 0) { GET_INT if (ival < 0 || ival > 4) gerror("Integration method must be: 1 - Riemann, 2 - Cuba serial, 3 - Cuba parallel, 4 - ROMHOM\n"); #if __CYGWIN__ if (bCygserverRunning){ mirror->map_merged.integration_method = ival; } else if(ival != RIEMANN_SUM_NEW) { warn(CYGSERVER_WARNING); mirror->map_merged.integration_method = RIEMANN_SUM_NEW; } #else mirror->map_merged.integration_method = ival; #endif } else if (strcmp(config_name, "save_interp_file") == 0) { GET_INT mirror->map_merged.save_interp_file = (bool) ival; if(ival != 1 && ival != 0) gerror("save_interp_file must be either 1 or 0 for true or false\n"); } else if (strcmp(config_name, "save_integration_points") == 0) { GET_INT mirror->map_merged.save_integration_points = (bool) ival; if(ival != 1 && ival != 0) gerror("save_integration_points must be either 1 or 0 for true or false\n"); } else if (strcmp(config_name, "save_knm") == 0) { GET_INT mirror->map_merged.save_to_file = (bool) ival; if (ival != 1 && ival != 0) gerror("save_knm must be either 1 " "or 0 for true or false\n"); } else if (strcmp(config_name, "show_knm_neval") == 0) { GET_INT WARNDEBUG; mirror->map_merged.show_knm_neval = (bool) ival; if (ival != 1 && ival != 0) gerror("show_knm_neval must be either 1 or 0 for true or false\n"); } else if (strcmp(config_name, "save_knm_matrices") == 0) { GET_INT mirror->map_merged.save_knm_matrices = (bool) ival; if (ival != 1 && ival != 0) gerror("save_knm_matrices must be either 1 or 0 for true or false\n"); } else if (strcmp(config_name, "save_knm_binary") == 0) { GET_INT mirror->map_merged.knm_save_binary = (bool) ival; if (ival != 1 && ival != 0) gerror("knm_save_binary must be either 1 or 0 for true or false\n"); } else if (strcmp(config_name, "knm_flags") == 0) { GET_INT mirror->knm_flags = (unsigned int) ival; if (ival < 0) gerror("knm_flags must be a positive integer\n"); } else if (strcmp(config_name, "knm_order") == 0) { int j; if( strlen(config_setting) != NUM_KNM_TYPES) gerror("knm_order must be 4 digits long, including only the numbers 1, 2, 3 and 4."); for(j=0; jknm_order[j] = i; } } else if (strcmp(config_name, "knm_change_q") == 0) { GET_INT if (ival < 1 || ival > 2) gerror("knm_change_q must be either 1 (Merged map) or 2 (Bayer-Helms)\n"); mirror->knm_change_q = ival; } else if (strcmp(config_name, "knm_force_saved") == 0) { GET_INT if (ival != 1 && ival != 0) gerror("knm_force_saved must be either 1 or 0 for true or false\n"); mirror->knm_force_saved = (bool) ival; } else if (strcmp(config_name, "square_aperture") == 0) { GET_INT if (ival != 1 && ival != 0) gerror("square_aperture must be either 1 or 0 for true or false\n"); if (ival == 0) mirror->aperture_type = CIRCULAR; else mirror->aperture_type = SQUARE; } else if (strcmp(config_name, "knm_cuba_cores") == 0) { GET_INT if (ival < 0) gerror("knm_cuba_cores must be > 0\n"); mirror->knm_cuba_cores = ival; } else if (strcmp(config_name, "knm_cuba_rel_err") == 0) { double err = 0; if(atod(config_setting, &err)) gerror("Line: '%s'\nCould not read error from '%s'\n", command_string, config_setting); if(err < 0) gerror("Line: '%s'\nError must be >= 0 '%s'\n", command_string, config_setting); mirror->knm_cuba_rel_err = err; } else if (strcmp(config_name, "knm_cuba_abs_err") == 0) { double err = 0; if(atod(config_setting, &err)) gerror("Line: '%s'\nCould not read error from '%s'\n", command_string, config_setting); if(err < 0) gerror("Line: '%s'\nError must be >= 0 '%s'\n", command_string, config_setting); mirror->knm_cuba_abs_err = err; } else gerror("Could not understand %s config setting for a mirror(%s)\n", config_name, mirror->name); break; default: gerror("Line `%s':\n conf command does not work with the component %s\n", command_string, command_name); } } void read_surface_motion_map(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char map_filename[LINE_LEN] = {0}; char transfer_func[LINE_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %s %s %s %80s", command_name, component_name, map_filename, transfer_func, rest_string); if (num_vars_read < 4) { gerror("Line `%s':\nexpected 'smotion component map_file transfer_function'\n", command_string); } else if (num_vars_read == 5) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } const char *dot = strrchr(map_filename, '.'); bool isROMMap = false; if(dot != NULL && dot != map_filename){ if(strncasecmp(dot, ".rom", 4) == 0) { isROMMap = true; } } if(isROMMap) { rom_map_t *rom = &inter.rom_maps[inter.num_ROM_maps]; strcpy(rom->filename, map_filename); read_rom_map(rom); if(!rom->roq11.enabled || !rom->roq22.enabled) gerror("Line `%s':\n" "ROM file '%s' doesn't have either the 11 or 22 reflection weights.\n", command_string, map_filename); } else { surface_map_t *map = &inter.surface_motion_map_list[inter.num_surface_motion_maps]; strcpy(map->filename, map_filename); read_surface_map(map); if(map->type != PHASE_MAP) gerror("Line `%s':\nSurface motion map file '%s' was not a phase map\n", command_string, map_filename); } int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { gerror("Line `%s':\nNo such component '%s'\n", command_string, component_name); } int component_type = get_component_type_decriment_index(&component_index); if (component_type != MIRROR) gerror("Line `%s':\nSurface motions cannot be applied to component '%s'\n", command_string, component_name); if(component_type == MIRROR){ mirror_t *m = &inter.mirror_list[component_index]; if(m->num_surface_motions >= MAX_MAPS) gerror("Line `%s':\nMaximum number of surface motions reached for '%s'\n", command_string, component_name); m->surface_motions_isROM[m->num_surface_motions] = isROMMap; if(isROMMap){ m->surface_motions[m->num_surface_motions] = inter.num_ROM_maps; } else { m->surface_motions[m->num_surface_motions] = inter.num_surface_motion_maps; } if(strlen(transfer_func) > 0){ int i; for(i=0; i< inter.num_transfer_funcs; i++){ if(strcmp(transfer_func, inter.tf_list[i].name) == 0){ m->surface_motions_tf[m->num_surface_motions] = &inter.tf_list[i]; break; } } } m->num_surface_motions++; } else bug_error("unhandled"); if(isROMMap) inter.num_ROM_maps++; else inter.num_surface_motion_maps++; } /*! * This command is used to associate discrete phase or amplitude maps with * a mirror or beamsplitter * * \param command_string the input command string * * */ void read_maps(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char parameter_filename[LINE_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; bool isROMMap = false; int num_vars_read = sscanf(command_string, "%s %s %s %80s", command_name, component_name, parameter_filename, rest_string); if (num_vars_read < 3) { gerror("Line `%s':\nexpected 'map component filename'\n", command_string); } else if (num_vars_read == 4) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { gerror("Line `%s':\nno such component '%s'\n", command_string, component_name); } int component_type = get_component_type_decriment_index(&component_index); if (component_type != MIRROR && component_type != BEAMSPLITTER) gerror("Line `%s':\nmaps cannot be applied to component '%s'\n", command_string, component_name); mirror_t *mirror = NULL; beamsplitter_t *bs = NULL; const char *dot = strrchr(parameter_filename, '.'); if(dot != NULL && dot != parameter_filename){ if(strncasecmp(dot, ".rom", 4) == 0) { isROMMap = true; } } if(component_type == MIRROR){ mirror = &inter.mirror_list[component_index]; if(isROMMap){ if(mirror->map_rom != NULL) gerror("Line `%s':\n Too many ROM maps applied to %s\n", command_string, mirror->name); mirror->map_rom = & (inter.rom_maps[inter.num_ROM_maps]); strcpy(mirror->map_rom->filename, parameter_filename); read_rom_map(mirror->map_rom); } else { if (mirror->num_maps == MAX_MAPS) gerror("Line `%s':\ntoo many maps for this mirror\n", command_string); mirror->map[mirror->num_maps] = (surface_map_t *) calloc(1, sizeof (surface_map_t)); if (mirror->map[mirror->num_maps] == NULL) { bug_error("memory allocation for surface map failed"); } strcpy(mirror->map[mirror->num_maps]->filename, parameter_filename); read_surface_map(mirror->map[mirror->num_maps]); mirror->num_maps++; } } else { bs = &inter.bs_list[component_index]; if (bs->num_maps == MAX_MAPS) gerror("Line `%s':\ntoo many maps for this mirror\n", command_string); bs->map[bs->num_maps] = (surface_map_t *) calloc(1, sizeof (surface_map_t)); if (bs->map[bs->num_maps] == NULL) bug_error("memory allocation for surface map failed"); strcpy(bs->map[bs->num_maps]->filename, parameter_filename); read_surface_map(bs->map[bs->num_maps]); bs->num_maps++; } if(isROMMap) inter.num_ROM_maps++; } //! Check if given attributes can be set / are already set, and set them /*! * \param parameter_name the parameter name to check/set * \param command_string the string containing the command input * \param component_name the name of the component to check/set the attributes * \param parameter_value the value to set to the parameter of the component * * \todo component_type == LIGHT_INPUT branch untested */ void check_and_set_attribute(const char *parameter_name, const char *parameter_value_string, const char *command_string, const char *component_name) { int eta = -1; int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { gerror("Line `%s':\nno such component '%s'\n", command_string, component_name); } int attribute_type = get_attribute_type(parameter_name, &eta, command_string); int component_type = get_component_type_decriment_index(&component_index); component_attribute_t component_attribute; component_attribute.component_index = component_index; component_attribute.attribute_type = attribute_type; component_attribute.parameter_string = parameter_value_string; component_attribute.command_string = command_string; component_attribute.component_name = component_name; // determine if we want a string or double input switch(component_attribute.attribute_type){ case MECH_TF: case MECH_RY_TF: case MECH_RX_TF: component_attribute.parameter_value = 0; break; default: if(atod(parameter_value_string, &component_attribute.parameter_value)) gerror("Line `%s':\nCould not parse number for parameter %s",command_string, parameter_name); } if (component_type == MIRROR) { set_mirror_attribute(&component_attribute); } else if (component_type == BEAMSPLITTER) { set_beamsplitter_attribute(&component_attribute); } else if (component_type == SPACE) { set_space_attribute(&component_attribute); } else if (component_type == GRATING) { set_grating_attribute(&component_attribute, eta); } else if (component_type == LIGHT_INPUT) { set_laser_attribute(&component_attribute); } else if (component_type == OUT) { set_light_output_attribute(&component_attribute); } else { gerror("Line `%s':\nno such attribute at this component\n", command_string, component_name); } } //! Gets the type of attribute dpending upon the parameter name /*! * \param parameter_name the name of the parameter * \param eta grating efficiency index, passed in and out of routine * \param command_string the command string */ int get_attribute_type(const char *parameter_name, int *eta, const char *command_string) { int attribute_type = NO_TYPE_SET; if (strcasecmp("Rcx", parameter_name) == 0 || strcasecmp("rx", parameter_name) == 0 || strcasecmp("Rx", parameter_name) == 0 || strcasecmp("rcx", parameter_name) == 0 || strcasecmp("rocx", parameter_name) == 0 || strcasecmp("ROCx", parameter_name) == 0) { attribute_type = XROC; } else if (strcasecmp("r_ap",parameter_name) == 0 || strcasecmp("rap",parameter_name) == 0 || strcasecmp("Rap",parameter_name) == 0) { attribute_type = APERTURE; } else if (strcasecmp("map_deg",parameter_name) == 0) { attribute_type = MAP_DEG; } else if (strcasecmp("x_off",parameter_name) == 0) { attribute_type = XOFF; } else if (strcasecmp("y_off",parameter_name) == 0) { attribute_type = YOFF; } else if (strcasecmp("Rcy", parameter_name) == 0 || strcasecmp("ry", parameter_name) == 0 || strcasecmp("Ry", parameter_name) == 0 || strcasecmp("rcy", parameter_name) == 0 || strcasecmp("rocy", parameter_name) == 0 || strcasecmp("ROCy", parameter_name) == 0) { attribute_type = YROC; } else if (strcasecmp("Rc", parameter_name) == 0 || strcasecmp("rc", parameter_name) == 0 || strcasecmp("roc", parameter_name) == 0 || strcasecmp("ROC", parameter_name) == 0) { attribute_type = ROC; } else if (strcasecmp("M", parameter_name) == 0 || strcasecmp("m", parameter_name) == 0 || strcasecmp("mass", parameter_name) == 0 || strcasecmp("Mass", parameter_name) == 0) { attribute_type = MASS; } else if (strcasecmp("ix", parameter_name) == 0 || strcasecmp("moix", parameter_name) == 0|| strcasecmp("iyaw", parameter_name) == 0) { attribute_type = MOIX; } else if (strcasecmp("iy", parameter_name) == 0 || strcasecmp("moiy", parameter_name) == 0 || strcasecmp("ipitch", parameter_name) == 0) { attribute_type = MOIY; } else if (strcasecmp("xbeta", parameter_name) == 0 || strcasecmp("yaw", parameter_name) == 0 || strcasecmp("xBeta", parameter_name) == 0) { attribute_type = XANGLE; } else if (strcasecmp("ybeta", parameter_name) == 0 || strcasecmp("pitch", parameter_name) == 0 || strcasecmp("yBeta", parameter_name) == 0) { attribute_type = YANGLE; } else if (strcasecmp("gx", parameter_name) == 0 || strcasecmp("gouyx", parameter_name) == 0) { attribute_type = GOUYX; } else if (strcasecmp("gy", parameter_name) == 0 || strcasecmp("gouyy", parameter_name) == 0) { attribute_type = GOUYY; } else if (strcasecmp("g", parameter_name) == 0 || strcasecmp("gouy", parameter_name) == 0) { attribute_type = GOUY; } else if (strcasecmp("alpha", parameter_name) == 0) { attribute_type = ALPHA; } else if ((strncasecmp("eta_", parameter_name, 4) == 0) && (((*eta = parameter_name[4] - 48) >= 0) && ((parameter_name[4] - 48) < 5))) { attribute_type = ETA; } else if ((strncasecmp("eta", parameter_name, 3) == 0) && (((*eta = parameter_name[3] - 48) >= 0) && ((parameter_name[3] - 48) < 5))) { attribute_type = ETA; } else if (strncasecmp("rho0", parameter_name, 4) == 0) { *eta = 3; attribute_type = ETA; } else if (strncasecmp("noise", parameter_name, 5) == 0) { attribute_type = LASER_NOISE; } else if (strncasecmp("mech", parameter_name, 4) == 0 || strncasecmp("zmech", parameter_name, 5) == 0) { attribute_type = MECH_TF; } else if (strncasecmp("rxmech", parameter_name, 6) == 0 || strncasecmp("yawmech", parameter_name, 7) == 0) { attribute_type = MECH_RX_TF; } else if (strncasecmp("rymech", parameter_name, 6) == 0 || strncasecmp("pitchmech", parameter_name, 9) == 0 ) { attribute_type = MECH_RY_TF; } else if (strncasecmp("homangle", parameter_name, 8) == 0) { attribute_type = HOM_ANGLE; } else if (strncasecmp("backscatter", parameter_name, 11) == 0) { attribute_type = BACKSCATTER; } else { gerror("Line `%s':\nno attribute named '%s', " "use Rap, map_deg, M, Rc, Rcx, Rcy, gx, gy, xbeta, ybeta, alpha, eta or rho!\n", command_string, parameter_name); // replace above error message with one below when noise attribute made public //gerror("Line `%s':\nno attribute named '%s', " //"use M, Rc, Rcx, Rcy, gx, gy, xbeta, ybeta, alpha, eta, rho or noise!\n", //command_string, parameter); } return attribute_type; } void set_mech_tf(transfer_func_t **attr_tf, component_attribute_t *component_attribute) { int i; if(*attr_tf == &mtf_free_mass) *attr_tf = NULL; if(*attr_tf != NULL){ warn("Line `%s':\nMechanical transfer function had already set for %s, replacing previous one.\n", component_attribute->command_string, component_attribute->component_name); *attr_tf = NULL; } for(i=0; i< inter.num_transfer_funcs; i++){ if(strcmp(component_attribute->parameter_string, inter.tf_list[i].name) == 0){ *attr_tf = &inter.tf_list[i]; break; } } if(*attr_tf == NULL) gerror("Line `%s':\nCould not find mechanical transfer function `%s`\n", component_attribute->command_string, component_attribute->parameter_string); } //! Set a mirror's attribute /*! * \param component_attribute structure of values used to set the attribute * * \todo setting MASS, XROC, YROC branches untested */ void set_mirror_attribute(component_attribute_t *component_attribute) { mirror_t *mirror; mirror = &inter.mirror_list[component_attribute->component_index]; int attribute_type = component_attribute->attribute_type; if (mirror->attribs & attribute_type) { warn("Line `%s':\nattribute was already set and is overwritten\n", component_attribute->command_string); } mirror->attribs |= attribute_type; if (attribute_type == XROC || attribute_type == YROC) { mirror->attribs |= ROC; } else { if (attribute_type == ROC) { mirror->attribs |= XROC; mirror->attribs |= YROC; } } double parameter_value = component_attribute->parameter_value; switch (attribute_type) { case MASS: if (parameter_value <= 0) gerror("Line `%s':\nmass must be >0\n", component_attribute->command_string); mirror->mass = parameter_value; if(mirror->long_tf == NULL) mirror->long_tf = &mtf_free_mass; break; case MOIX: if (parameter_value <= 0) gerror("Line `%s':\nMoment of inertia Ix must be > 0\n", component_attribute->command_string); if (!inter.tem_is_set) gerror("Line `%s':\nMust enable higher order modes to use rotational motions\n", component_attribute->command_string); mirror->Ix = parameter_value; if(mirror->rot_x_tf == NULL) mirror->rot_x_tf = &mtf_free_mass; break; case MOIY: if (parameter_value <= 0) gerror("Line `%s':\nMoment of inertia Iy must be > 0\n", component_attribute->command_string); if (!inter.tem_is_set) gerror("Line `%s':\nMust enable higher order modes to use rotational motions\n", component_attribute->command_string); mirror->Iy = parameter_value; if(mirror->rot_y_tf == NULL) mirror->rot_y_tf = &mtf_free_mass; break; case XOFF: mirror->x_off = parameter_value; break; case YOFF: mirror->y_off = parameter_value; break; case XROC: mirror->Rcx = parameter_value; break; case YROC: mirror->Rcy = parameter_value; break; case ROC: mirror->Rcx = parameter_value; mirror->Rcy = parameter_value; break; case XANGLE: mirror->beta_x = parameter_value; break; case YANGLE: mirror->beta_y = parameter_value; break; case MAP_DEG: mirror->angle = parameter_value; break; case APERTURE: if(parameter_value < 0) gerror("Line `%s':\naperture must be >= 0\n",component_attribute->command_string); mirror->r_aperture = parameter_value; break; case MECH_TF: set_mech_tf(&(mirror->long_tf), component_attribute); break; case MECH_RX_TF: set_mech_tf(&(mirror->rot_x_tf), component_attribute); break; case MECH_RY_TF: set_mech_tf(&(mirror->rot_y_tf), component_attribute); break; default: gerror("Line `%s':\n" "no such attribute at this component\n", component_attribute->command_string, component_attribute->component_name); } } //! Search a given filename for a header for either map data or coefficients /*! * \param mapfile file that contains surface map data * \param header_type integerer: what header to search for" * 0: map data, search for string '% Surface map:' * 1: map coefficients, search for string '% Coupling coefficents:' */ int search_file_for_headers(FILE *mapfile, int header_type) { char search_string[LINE_LEN] = {0}; char *str_ptr; str_ptr = NULL; if (header_type == 1) { strcpy(search_string, "% Coupling coefficients"); } else { strcpy(search_string, "% Surface map"); } char s0[LINE_LEN] = {0}; while (str_ptr == NULL && fgets(s0, LINE_LEN - 1, mapfile) != NULL) { str_ptr = strstr(s0, search_string); } if (str_ptr == NULL) { return 0; } else { return 1; } } //! Read header from a surface map file /*! * \param mapfile file that contains surface map data * \param map structure to store map info and data * Example header: * % Surface map * % Name: lg33phaseplate * % Type: phase reflection * % Size: 400 400 * % Optical center (x,y): 200 200 * % Step size (x,y): 0.00015 0.00015 * % Scaling: 1064e-9 */ void read_map_data_header(FILE *mapfile, surface_map_t *map) { char s0[LINE_LEN] = {0}; char name[LINE_LEN] = {0}; char stype1[LINE_LEN] = {0}; char stype2[LINE_LEN] = {0}; char ssize1[LINE_LEN] = {0}; char ssize2[LINE_LEN] = {0}; char sx0[LINE_LEN] = {0}; char sy0[LINE_LEN] = {0}; char sstepx[LINE_LEN] = {0}; char sstepy[LINE_LEN] = {0}; char sscaling[LINE_LEN] = {0}; char rest_string[LINE_LEN] = {0}; int num_var_read; char *filename = map->filename; // read first line // e.g.: Name: lg33phaseplate if (fgets(s0, LINE_LEN - 1, mapfile) != NULL) { num_var_read = sscanf(s0, "%% Name: %s %80s", name, rest_string); if (num_var_read == 1) { strcpy(map->name, name); } else { gerror("cannot read map (data) name in file '%s'\n", filename); } } else { gerror("cannot read first header line in file '%s'\n", filename); } // read first line // % type: phase, reflection if (fgets(s0, LINE_LEN - 1, mapfile) != NULL) { num_var_read = sscanf(s0, "%% Type: %s %s %80s", stype1, stype2, rest_string); if (num_var_read == 2) { if (strcasecmp("phase", stype1) == 0) { map->type = PHASE_MAP; } else if (strcasecmp("absorption", stype1) == 0) { map->type = ABSORPTION_MAP; } else if (strcasecmp("reflectivity", stype1) == 0) { map->type = REFLECTIVITY_MAP; } else { gerror("cannot read map type (phase/absorption/reflectivity) in file '%s'\n", filename); } if (strcasecmp("reflection", stype2) == 0) { map->reflection = true; map->transmission = false; } else if (strcasecmp("transmission", stype2) == 0) { map->reflection = false; map->transmission = true; } else if (strcasecmp("both", stype2) == 0) { map->reflection = true; map->transmission = true; } else { gerror("cannot read map type (reflection/transmission/both) in file '%s'\n", filename); } } else { gerror("cannot read map type in file '%s'\n", filename); } } else { gerror("cannot read second data header line in file '%s'\n", filename); } // read third line //% size: 400, 400 if (fgets(s0, LINE_LEN - 1, mapfile) != NULL) { num_var_read = sscanf(s0, "%% Size: %s %s %80s", ssize1, ssize2, rest_string); if (num_var_read == 2) { if (my_atoi(ssize1, &(map->rows))) { gerror("failed char to integer conversion, reading map size in file '%s'\n", filename); } if (my_atoi(ssize2, &(map->cols))) { gerror("failed char to integer conversion, reading map size in file '%s'\n", filename); } } else { gerror("cannot read map size in file '%s'\n", filename); } } else { gerror("cannot read third data header line in file '%s'\n", filename); } // read fourth line //% Optical center (x,y): 200, 200 if (fgets(s0, LINE_LEN - 1, mapfile) != NULL) { double tx, ty; num_var_read = sscanf(s0, "%% Optical center (x,y): %s %s %80s", sx0, sy0, rest_string); if (num_var_read == 2) { if (atod(sx0, &tx)) { gerror("cannot read optical center of map in file '%s'\n", filename); } if (atod(sy0, &ty)) { gerror("cannot read optical center of map in file '%s'\n", filename); } map->x0 = tx; map->y0 = ty; } else { gerror("cannot read optical center of map in file '%s'\n", filename); } } else { gerror("cannot read fourth data header line in file '%s'\n", filename); } //read fifth line //% Step size (x,y): 0.00015, 0.00015 if (fgets(s0, LINE_LEN - 1, mapfile) != NULL) { num_var_read = sscanf(s0, "%% Step size (x,y): %s %s %80s", sstepx, sstepy, rest_string); if (num_var_read == 2) { if (atod(sstepx, &(map->xstep))) { gerror("cannot read step size of map in file '%s'\n", filename); } if (atod(sstepy, &(map->ystep))) { gerror("cannot read step size of map in file '%s'\n", filename); } } else { gerror("cannot read step size of map in file '%s'\n", filename); } } else { gerror("cannot read fifth data header line in file '%s'\n", filename); } //read sixth line //% Scaling: 1064e-9 if (fgets(s0, LINE_LEN - 1, mapfile) != NULL) { num_var_read = sscanf(s0, "%% Scaling: %s %80s", sscaling, rest_string); if (num_var_read == 1) { if (atod(sscaling, &(map->scaling))) { gerror("cannot read scaling of map in file '%s'\n", filename); } } else { gerror("cannot read scaling of map in file '%s'\n", filename); } } else { gerror("cannot read sixth data header line in file '%s'\n", filename); } } void __parse_rom_weights(FILE *romfile, zmatrix *w, size_t *nx, size_t *ny, const char* filename){ int n,m; n = fscanf(romfile, "(%zu,%zu)\n", nx, ny); if(n != 2) gerror("Error node size from '%s'\n", filename); assert(*nx == *ny); allocate_zmatrix(w, *nx, NULL); for(n=0; n<(int)(*nx); n++){ for(m=0; m<(int)(*ny); m++){ int p = fscanf(romfile, "%le%lej\n", &((*w)[n][m].re), &((*w)[n][m].im)); if(p != 2) gerror("Error parsing weights from '%s'\n", filename); } } } void read_roq_weights(FILE *romfile, roq_weights_t *rom, const char *filename) { int n, m; // First read header information n = fscanf(romfile, "zmin=%le\n", & rom->zmin); if(n==0) gerror("Error parsing zmin from '%s'\n", filename); n = fscanf(romfile, "zmax=%le\n", & rom->zmax); if(n==0) gerror("Error parsing zmax from '%s'\n", filename); n = fscanf(romfile, "w0min=%le\n", & rom->w0min); if(n==0) gerror("Error parsing w0min from '%s'\n", filename); n = fscanf(romfile, "w0max=%le\n", & rom->w0max); if(n==0) gerror("Error parsing w0max from '%s'\n", filename); n = fscanf(romfile, "maxorder=%i\n", & rom->maxorder); if(n==0) gerror("Error parsing maxorder from '%s'\n", filename); n = fscanf(romfile, "R=%le\n", & rom->R); if(n==0) gerror("Error parsing R from '%s'\n", filename); n = fscanf(romfile, "mapSamples=%i\n", & rom->mapSamples); if(n==0) gerror("Error parsing mapSamples from '%s'\n", filename); n = fscanf(romfile, "nr1=%le\n", & rom->nr1); if(n==0) gerror("Error parsing nr1 from '%s'\n", filename); n = fscanf(romfile, "nr2=%le\n", & rom->nr2); if(n==0) gerror("Error parsing nr2 from '%s'\n", filename); n = fscanf(romfile, "xnodes=%zu\n", & rom->num_xnodes); if(n==0) gerror("Error parsing xnodes from '%s'\n", filename); assert(rom->num_xnodes > 0); rom->x_nodes = (double *) calloc(rom->num_xnodes, sizeof(double)); for(n=0; n<(int)rom->num_xnodes; n++){ if(fscanf(romfile, "%le\n", rom->x_nodes + n) == 0) gerror("Error parsing x nodes from '%s'\n", filename); } n = fscanf(romfile, "ynodes=%zu\n", & rom->num_ynodes); if(n==0) gerror("Error parsing ynodes from '%s'\n", filename); assert(rom->num_ynodes > 0); rom->y_nodes = (double *) calloc(rom->num_ynodes, sizeof(double)); for(n=0; n<(int)rom->num_ynodes; n++){ if(fscanf(romfile, "%le\n", rom->y_nodes + n) == 0) gerror("Error parsing y nodes from '%s'\n", filename); } // Now read all the zmatrix wQ1=NULL, wQ2=NULL, wQ3=NULL, wQ4=NULL; size_t xQ1=0, yQ1=0, xQ2=0, yQ2=0, xQ3=0, yQ3=0, xQ4=0, yQ4=0; __parse_rom_weights(romfile, &wQ1, &xQ1, &yQ1, filename); __parse_rom_weights(romfile, &wQ2, &xQ2, &yQ2, filename); __parse_rom_weights(romfile, &wQ3, &xQ3, &yQ3, filename); __parse_rom_weights(romfile, &wQ4, &xQ4, &yQ4, filename); allocate_zmatrix2(&rom->w_Q1Q2, xQ1, yQ2, NULL); allocate_zmatrix2(&rom->w_Q1Q3, xQ1, yQ3, NULL); allocate_zmatrix2(&rom->w_Q1Q4, xQ1, yQ4, NULL); allocate_zmatrix2(&rom->w_Q2Q3, xQ2, yQ3, NULL); allocate_zmatrix2(&rom->w_Q2Q4, xQ2, yQ4, NULL); allocate_zmatrix2(&rom->w_Q3Q4, xQ3, yQ4, NULL); allocate_zmatrix2(&rom->w_Q1Q2Q3Q4, xQ1, yQ1, NULL); assert(rom->w_Q1Q2 != NULL); assert(rom->w_Q1Q3 != NULL); assert(rom->w_Q1Q4 != NULL); assert(rom->w_Q2Q3 != NULL); assert(rom->w_Q2Q4 != NULL); assert(rom->w_Q3Q4 != NULL); assert(rom->w_Q1Q2Q3Q4 != NULL); for(n=0; n<(int)xQ1; n++){ for(m=0; m<(int)yQ1; m++){ rom->w_Q1Q2[n][m] = z_pl_z(wQ1[n][m], wQ2[n][m]); rom->w_Q1Q3[n][m] = z_pl_z(wQ1[n][m], wQ3[n][m]); rom->w_Q1Q4[n][m] = z_pl_z(wQ1[n][m], wQ4[n][m]); rom->w_Q2Q3[n][m] = z_pl_z(wQ2[n][m], wQ3[n][m]); rom->w_Q2Q4[n][m] = z_pl_z(wQ2[n][m], wQ4[n][m]); rom->w_Q3Q4[n][m] = z_pl_z(wQ3[n][m], wQ4[n][m]); rom->w_Q1Q2Q3Q4[n][m] = z_pl_z(rom->w_Q1Q2[n][m], rom->w_Q3Q4[n][m]); } } free_zmatrix(wQ1); free_zmatrix(wQ2); free_zmatrix(wQ3); free_zmatrix(wQ4); } void read_rom_map(rom_map_t *rom){ assert(rom != NULL); assert(strlen(rom->filename) > 0); FILE *romfile = fopen(rom->filename, "r"); if(romfile == NULL) gerror("Could not open file '%s'\n", rom->filename); rom->roq11.enabled = false; rom->roq22.enabled = false; rom->roq12.enabled = false; rom->roq21.enabled = false; // Keep looping through and while(!feof(romfile)){ roq_weights_t *w = NULL; char direction[LINE_LEN] = {0}; int n = fscanf(romfile, "direction=%s\n", direction); if(n==0) gerror("Error parsing zmin from '%s'\n", rom->filename); if(strcasecmp(direction, "reflection_front") == 0) { w = &rom->roq11; rom->roq11.enabled = true; } else if(strcasecmp(direction, "reflection_back") == 0) { w = &rom->roq22; rom->roq22.enabled = true; } else if(strcasecmp(direction, "transmission_front") == 0) { w = &rom->roq12; rom->roq12.enabled = true; } else if(strcasecmp(direction, "transmission_back") == 0) { w = &rom->roq21; rom->roq21.enabled = true; } read_roq_weights(romfile, w, rom->filename); } fclose(romfile); } /** Read map information from a file * \param mapfile file that contains surface map data * \param map structure to store map info and data */ void read_surface_map(surface_map_t *map) { FILE *mapfile; mapfile = fopen(map->filename, "r"); if (mapfile == NULL) { gerror("could not open file '%s'\n", map->filename); } if(inter.debug & 128 && !options.quiet){ message("\n* Computing hash for map %s...\n", map->filename); } file_MD5(mapfile, map->hash); map->has_map_source = false; map->has_coefficients = false; *(map->name) = '\0'; if(inter.debug && !options.quiet){ char *B64_hash = encode_base64(sizeof (map->hash), map->hash); debug_msg("done: hash(base64) = %s\n", B64_hash); free(B64_hash); } // trying to read map data int found_source = search_file_for_headers(mapfile, 0); if (found_source) { read_map_data_header(mapfile, map); map->has_map_source = true; map->data = (double **) calloc((map->cols + 1), sizeof (double *)); if (map->data == NULL) { bug_error("memory allocation for surface map data failed (1)"); } int i; for (i = 0; i < map->cols; i++) { map->data[i] = (double *) calloc((map->rows + 1), sizeof (double)); if (map->data[i] == NULL) { bug_error("memory allocation for surface map data failed (2)"); } } int j; int loaded; double tmp_value; for (i = 0; i < map->rows; i++) { for (j = 0; j < map->cols; j++) { loaded = fscanf(mapfile, "%lg", &tmp_value); if (loaded == EOF) { gerror("Missing values in file '%s', the specified phasemap size is not correct.\n", map->filename); } map->data[i][j] = map->scaling*tmp_value; } } // for amplitude maps: check that all values are between 0 and 1 int wrong_value = 0; if (map->type != PHASE_MAP) { for (i = 0; i < map->rows; i++) { for (j = 0; j < map->cols; j++) { if (map->data[i][j] < 0 || map->data[i][j] > 1) { wrong_value |= 1; } } } if (wrong_value) { gerror("Map file '%s', values for amplitude maps must be between 0 and 1.\n", map->filename); } } } else { // set map data related data to zero map->rows = 0; map->cols = 0; map->x0 = 0; map->y0 = 0; map->xstep = 0; map->ystep = 0; map->scaling = 0; } // Close the file fclose(mapfile); if (map->has_map_source == false && map->has_coefficients == false) { gerror("did not find map source data or coefficients in file '%s'\n", map->filename); } map->function = 0; } //! Set a beamsplitter's attribute /*! * \param component_attribute structure of values used to set the attribute * * \todo setting MASS attribute untested */ void set_beamsplitter_attribute(component_attribute_t *component_attribute) { beamsplitter_t *beamsplitter; beamsplitter = &inter.bs_list[component_attribute->component_index]; int attribute_type = component_attribute->attribute_type; if (beamsplitter->attribs & attribute_type) { warn("Line `%s':\n" "attribute was already set and is overwritten\n", component_attribute->command_string); } beamsplitter->attribs |= attribute_type; if (attribute_type == XROC || attribute_type == YROC) { beamsplitter->attribs |= ROC; } else if (attribute_type == ROC) { beamsplitter->attribs |= XROC; beamsplitter->attribs |= YROC; } double parameter_value = component_attribute->parameter_value; switch (attribute_type) { case BACKSCATTER: if (parameter_value < 0 && parameter_value < 1) { gerror("Line `%s':\nbackscatter must be 0 > backscatter < 1\n", component_attribute->command_string); } beamsplitter->backscatter = parameter_value; break; case MASS: if (parameter_value <= 0) { gerror("Line `%s':\nmass must be >0\n", component_attribute->command_string); } beamsplitter->mass = parameter_value; if(beamsplitter->long_tf == NULL) beamsplitter->long_tf = &mtf_free_mass; break; case MOIY: if (parameter_value <= 0) { gerror("Line `%s':\nMoment of inertia y must be >0\n", component_attribute->command_string); } if (!inter.tem_is_set) gerror("Line `%s':\nMust enable higher order modes to use rotational motions\n", component_attribute->command_string); beamsplitter->Iy = parameter_value; if(beamsplitter->rot_y_tf == NULL) beamsplitter->rot_y_tf = &mtf_free_mass; break; case MOIX: if (parameter_value <= 0) { gerror("Line `%s':\nMoment of inertia x must be >0\n", component_attribute->command_string); } if (!inter.tem_is_set) gerror("Line `%s':\nMust enable higher order modes to use rotational motions\n", component_attribute->command_string); beamsplitter->Ix = parameter_value; if(beamsplitter->rot_x_tf == NULL) beamsplitter->rot_x_tf = &mtf_free_mass; break; case XROC: beamsplitter->Rcx = parameter_value; break; case YROC: beamsplitter->Rcy = parameter_value; break; case XOFF: beamsplitter->x_off = parameter_value; break; case YOFF: beamsplitter->y_off = parameter_value; break; case ROC: beamsplitter->Rcx = parameter_value; beamsplitter->Rcy = parameter_value; break; case XANGLE: beamsplitter->beta_x = parameter_value; break; case YANGLE: beamsplitter->beta_y = parameter_value; break; case APERTURE: if(parameter_value < 0) gerror("Line `%s':\naperture must be >= 0\n", component_attribute->command_string); beamsplitter->r_aperture = parameter_value; break; case MECH_TF: set_mech_tf(&(beamsplitter->long_tf), component_attribute); break; case MECH_RX_TF: set_mech_tf(&(beamsplitter->rot_x_tf), component_attribute); break; case MECH_RY_TF: set_mech_tf(&(beamsplitter->rot_y_tf), component_attribute); break; default: gerror("Line `%s':\n" "no such attribute at this component\n", component_attribute->command_string, component_attribute->component_name); } } //! Set a space's attribute /*! * \param component_attribute structure of values used to set the attribute * * \todo setting GOUYX, GOUYY attributes untested */ void set_space_attribute(component_attribute_t *component_attribute) { space_t *space; space = &inter.space_list[component_attribute->component_index]; int attribute_type = component_attribute->attribute_type; if (space->attribs & attribute_type) { warn("Line `%s':\n" "attribute was already set and is overwritten\n", component_attribute->command_string); } space->attribs |= attribute_type; if (attribute_type == GOUYX || attribute_type == GOUYY) { space->attribs |= GOUY; } else if (attribute_type == GOUY) { space->attribs |= GOUYX; space->attribs |= GOUYY; } double parameter_value = component_attribute->parameter_value; switch (attribute_type) { case GOUY: if (parameter_value < 0) { gerror("Line `%s':\nGouy phase must be >=0\n", component_attribute->command_string); } space->gouy_x = parameter_value; space->gouy_y = parameter_value; break; case GOUYX: if (parameter_value < 0) { gerror("Line `%s':\nGouy phase must be >=0\n", component_attribute->command_string); } space->gouy_x = parameter_value; break; case GOUYY: if (parameter_value < 0) { gerror("Line `%s':\nGouy phase must be >=0\n", component_attribute->command_string); } space->gouy_y = parameter_value; break; default: gerror("Line `%s':\nno such attribute at this component\n", component_attribute->command_string, component_attribute->component_name); } } //! Set a grating's attribute /*! * \param component_attribute structure of values used to set the attribute * \param eta Grating efficiency index * * \todo setting XROC, YROC, ROC attributes untested */ void set_grating_attribute(component_attribute_t *component_attribute, int eta) { grating_t *grating; grating = &inter.grating_list[component_attribute->component_index]; int attribute_type = component_attribute->attribute_type; grating->attribs |= attribute_type; if (attribute_type == XROC || attribute_type == YROC) { grating->attribs |= ROC; } else { if (attribute_type == ROC) { grating->attribs |= XROC; grating->attribs |= YROC; } } double parameter_value = component_attribute->parameter_value; switch (attribute_type) { case ALPHA: if (grating->num_of_ports != 4) { gerror("Line `%s':\n" "angle of incidence can only be set for grating type 'gr4'\n", component_attribute->command_string); } if (grating->attribs & attribute_type) { warn("Line `%s':\nattribute was already set and is overwritten\n", component_attribute->command_string); } grating->attribs |= attribute_type; grating->alpha = parameter_value; break; case ETA: if (eta < 0 || eta > 4) { bug_error("grating, eta: wrong index"); } switch (grating->num_of_ports) { case 2: if (eta > 1) { gerror("Line `%s':\nwrong efficiency index\n", component_attribute->command_string); } break; case 3: if (eta > 3) { gerror("Line `%s':\nwrong efficiency index\n", component_attribute->command_string); } break; case 4: if (eta > 3) { gerror("Line `%s':\nwrong efficiency index\n", component_attribute->command_string); } break; default: bug_error("wrong number of ports 222"); } if (parameter_value < 0) { gerror("Line `%s':\nefficency eta must be >=0\n", component_attribute->command_string); } if (grating->etaset[eta]) { warn("Line `%s':\nefficiency was already set and is overwritten\n", component_attribute->command_string); } grating->eta[eta] = parameter_value; grating->etaset[eta] = 1; grating->attribs |= attribute_type; break; case XROC: grating->Rcx = parameter_value; break; case YROC: grating->Rcy = parameter_value; break; case ROC: grating->Rcx = parameter_value; grating->Rcy = parameter_value; break; default: gerror("Line `%s':\nno such attribute at this component\n", component_attribute->command_string, component_attribute->component_name); } } void set_light_output_attribute(component_attribute_t *component_attribute) { light_out_t *out = &inter.light_out_list[component_attribute->component_index]; if (out->attribs & component_attribute->attribute_type) { warn("Line `%s':\n" "attribute was already set and will be overwritten\n", component_attribute->command_string); } out->attribs |= component_attribute->attribute_type; if (component_attribute->attribute_type == HOM_ANGLE) { out->homodyne_angle = component_attribute->parameter_value; } else { gerror("Line `%s':\nno such attribute at this component\n", component_attribute->command_string); } } //! Set a laser's attribute /*! * \param component_attribute structure of values used to set the attribute * * \todo untested */ void set_laser_attribute(component_attribute_t *component_attribute) { light_in_t *laser; laser = &inter.light_in_list[component_attribute->component_index]; if (laser->attribs & component_attribute->attribute_type) { warn("Line `%s':\n" "attribute was already set and will be overwritten\n", component_attribute->command_string); } laser->attribs |= component_attribute->attribute_type; if (component_attribute->attribute_type == LASER_NOISE) { laser->noise_value = UNIT_VACUUM + component_attribute->parameter_value; } else { gerror("Line `%s':\nno such attribute at this component\n", component_attribute->command_string); } } //! Read the x-axis parameters (why the '2' ???) /*! * \param command_string the input command string */ void read_xaxis2(const char *command_string) { char unit[20] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char parameter_name[MAX_TOKEN_LEN] = {0}; char linlog[MAX_TOKEN_LEN] = {0}; char min_value_string[LINE_LEN] = {0}; char max_value_string[LINE_LEN] = {0}; int num_steps; char rest_string[REST_STRING_LEN] = {0}; endcomp = 1; lastparam = -1; if (inter.x1.xsteps != NO_FREQ || inter.x1.xtype != NO_FREQ) { gerror("Line `%s':\nxaxis already defined'\n", command_string); } int num_vars_read = sscanf(command_string, "%s %s %s %3s %s %s %d %80s", command_name, component_name, parameter_name, linlog, min_value_string, max_value_string, &num_steps, rest_string); int num_vars_expected = 7; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\n" "expected 'xaxis* component parameter lin/log min max steps'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } // following can be removed: // check if component is actually a variable //if ((strcasecmp(component_name, "var") == 0) || (strcasecmp(component_name, "variable") == 0)) { // strcpy(component_name, parameter_name); //} //################################################################################## //add to xaxis and put as well!! CAn be removed I think!!!!!!!!!! int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { int detector_index = get_detector_or_node_index_from_name(component_name); if (detector_index == NOT_FOUND) { gerror("Line `%s':\ncomponent name '%s' not found.\n", command_string, component_name); } else { component_index = detector_index; } } if (strncasecmp(linlog, "lin", 3) == 0) { inter.x1.xtype = FLIN; } else if (strncasecmp(linlog, "log", 3) == 0) { inter.x1.xtype = FLOG; } else { // (inter.x1.xtype == NO_FREQ) gerror("Line `%s':\n" "expected 'xaxis* component parameter lin/log min max steps'\n", command_string); } if (num_steps < 1) { gerror("Line `%s':\nnumber of steps < 1 illegal'\n", command_string); } int error_code = get_xparam(&inter.x1.xaxis, component_index, parameter_name, unit, command_string, &inter.x1.lborder, &inter.x1.uborder, &inter.x1.min, &inter.x1.max); if (error_code != 0) { my_finish(1); } inter.x1.op = *inter.x1.xaxis; double axis_min; if (atod(min_value_string, &axis_min)) { gerror("Line `%s':\nUnable to read axis minimum value\n", command_string); } double axis_max; if (atod(max_value_string, &axis_max)) { gerror("Line `%s':\nUnable to read axis maximum value\n", command_string); } if (inter.x1.xtype == FLOG) { axis_min = axis_min * inter.x1.op; axis_max = axis_max * inter.x1.op; } else { axis_min = axis_min + inter.x1.op; axis_max = axis_max + inter.x1.op; } /* testing 110205 if (x2 num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { //################################################################################ // never used can be removed here in other xaxis put function int detector_index = get_detector_or_node_index_from_name(component_name); if (detector_index == NOT_FOUND) { gerror("Line `%s':\ncomponent name '%s' not found.\n", command_string, component_name); } else { component_index = detector_index; } } if (strncasecmp(linlog, "lin", 3) == 0) { inter.x1.xtype = FLIN; } if (strncasecmp(linlog, "log", 3) == 0) { inter.x1.xtype = FLOG; } if (inter.x1.xtype == NO_FREQ) { gerror("Line `%s':\n" "expected 'xaxis component parameter lin/log min max steps'\n", command_string); } if (num_steps < 1) { gerror("Line `%s':\nnumber of steps < 1 illegal'\n", command_string); } int error_code = get_xparam(&inter.x1.xaxis, component_index, parameter_name, unit, command_string, &inter.x1.lborder, &inter.x1.uborder, &inter.x1.min, &inter.x1.max); if (error_code) { my_finish(1); } double axis_min; if (atod(min_value_string, &axis_min)) { gerror("Line `%s':\nUnable to read minimum axis value\n", command_string); } double axis_max; if (atod(max_value_string, &axis_max)) { gerror("Line `%s':\nUnable to read maximum axis value\n", command_string); } check_xparam(inter.x1.lborder, inter.x1.uborder, inter.x1.min, inter.x1.max, axis_min, axis_max, inter.x1.xtype, command_string, 0); strcpy(inter.x1.xname, parameter_name); strcat(inter.x1.xname, unit); strcat(inter.x1.xname, " ("); strcat(inter.x1.xname, component_name); strcat(inter.x1.xname, ")"); inter.x1.component_idx = component_index; inter.x1.xmin = axis_min; inter.x1.xmax = axis_max; inter.x1.xsteps = num_steps; inter.x1.minus_xaxis = 0.0; if (inter.x1.xtype == FLOG) { inter.x1.op = 1.0; } else { inter.x1.op = 0.0; } } //! Read a put* command /*! * \param command_string the input command string */ void read_put_star_command(const char *command_string) { char new_command_string[LINE_LEN] = {0}; // construct the new put command string strcpy(new_command_string, "put"); strcat(new_command_string, command_string + 4); read_put_command(new_command_string); inter.put_list[inter.num_put_cmds - 1].mode = 1; } //! Reads a put command /*! * \param command_string the input command string */ void read_put_command(const char *command_string) { char unit[16] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char parameter_name[MAX_TOKEN_LEN] = {0}; char function_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; put_command_t *put_command = NULL; if (inter.num_put_cmds >= mem.num_put_cmds) { gerror("Line `%s':\ntoo many puts.\n", command_string); } put_command = &inter.put_list[inter.num_put_cmds]; int num_vars_read = sscanf(command_string, "%s %s %s %s %80s", command_name, component_name, parameter_name, function_name, rest_string); int num_vars_expected = 4; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\n" "expected 'put component parameter function/set/axis'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } //################################################################################## // to test!!! does this work, why has this not been here before, 140508 int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { int detector_index = get_detector_or_node_index_from_name(component_name); if (detector_index == NOT_FOUND) { gerror("Line `%s':\ncomponent name '%s' not found.\n", command_string, component_name); } else { component_index = detector_index; } } if (get_xparam(&put_command->target, component_index, parameter_name, unit, command_string, &put_command->lborder, &put_command->uborder, &put_command->min, &put_command->max)) { my_finish(1); } // check for more than one pointer to the same value if ((put_command->target == inter.x1.xaxis) || (put_command->target == inter.x2.xaxis) || (put_command->target == inter.x3.xaxis)) { gerror("Line `%s':\nsame parameter used in x-axis settings\n", command_string); } int cmd_index; for (cmd_index = 0; cmd_index < inter.num_put_cmds; cmd_index++) { if (put_command->target == inter.put_list[cmd_index].target) { gerror("Line `%s':\nsame parameter used with another 'put'\n", command_string); } } put_command->startvalue = *(put_command->target); /* get source */ int num_function_names_found = 0; for (cmd_index = 0; cmd_index < inter.num_set_cmds; cmd_index++) { if (strcasecmp(function_name, inter.set_list[cmd_index].name) == 0) { num_function_names_found++; put_command->source = inter.set_list[cmd_index].value; if (put_command->source == NULL) { bug_error("null pointer put, set"); } } } for (cmd_index = 0; cmd_index < inter.num_func_cmds; cmd_index++) { if (strcasecmp(function_name, inter.function_list[cmd_index].name) == 0) { num_function_names_found++; put_command->source = &(inter.function_list[cmd_index].result); if (put_command->source == NULL) { bug_error("null pointer put, func"); } } } for (cmd_index = 0; cmd_index < inter.num_locks; cmd_index++) { if (strcasecmp(function_name, inter.lock_list[cmd_index].name) == 0) { num_function_names_found++; put_command->source = &(inter.lock_list[cmd_index].value); if (put_command->source == NULL) { bug_error("null pointer put, lock"); } } } if (strcasecmp(function_name, "$fs") == 0) { num_function_names_found++; put_command->source = &(inter.fsig); if (put_command->source == NULL) { bug_error("null pointer put, fs"); } } if (strcasecmp(function_name, "$mfs") == 0) { num_function_names_found++; put_command->source = &(inter.mfsig); if (put_command->source == NULL) { bug_error("null pointer put, mfs"); } } if (strcasecmp(function_name, "$x1") == 0) { if (inter.x1.xtype == NO_FREQ) { gerror("no 'xaxis' defined, so cannot use $x1\n"); } num_function_names_found++; put_command->source = inter.x1.xaxis; if (put_command->source == NULL) { bug_error("null pointer put, x1"); } } if (strcasecmp(function_name, "$x2") == 0) { if (inter.x2.xtype == NO_FREQ) { gerror("Line `%s':\nno x2axis defined, so cannot use $x2\n", command_string); } num_function_names_found++; put_command->source = inter.x2.xaxis; if (put_command->source == NULL) { bug_error("null pointer put, x2"); } } if (strcasecmp(function_name, "$x3") == 0) { if (inter.x3.xtype == NO_FREQ) { gerror("Line `%s':\nno x3axis defined, so cannot use $x3\n", command_string); } num_function_names_found++; put_command->source = inter.x3.xaxis; if (put_command->source == NULL) { bug_error("null pointer put, x3"); } } if (strcasecmp(function_name, "$mx1") == 0) { if (inter.x1.xtype == NO_FREQ) { gerror("no 'xaxis' defined, so cannot use $mx1\n"); } num_function_names_found++; put_command->source = &inter.x1.minus_xaxis; if (put_command->source == NULL) { bug_error("null pointer put, mx1"); } } if (strcasecmp(function_name, "$mx2") == 0) { if (inter.x2.xtype == NO_FREQ) { gerror("Line `%s':\nno x2axis defined, so cannot use $mx2\n", command_string); } num_function_names_found++; put_command->source = &inter.x2.minus_xaxis; if (put_command->source == NULL) { bug_error("null pointer put, mx2"); } } if (strcasecmp(function_name, "$mx3") == 0) { if (inter.x3.xtype == NO_FREQ) { gerror("Line `%s':\nno x3axis defined, so cannot use $mx3\n", command_string); } num_function_names_found++; put_command->source = &inter.x3.minus_xaxis; if (put_command->source == NULL) { bug_error("null pointer put, mx3"); } } if (num_function_names_found == 0) { gerror("Line `%s':\nfunction_name/set/axis name '%s' not found.\n", command_string, function_name); } if (num_function_names_found > 1) { warn("Line `%s':\n" "function/set/axis name '%s' found more than once (using last).\n", command_string, function_name); } put_command->mode = 0; strcpy(put_command->component_name, component_name); strcpy(put_command->parameter_name, parameter_name); strcpy(put_command->function_name, function_name); inter.num_put_cmds++; } //! Reads a set command /*! * \param command_string the input command string * * \todo refactor routine for readability * * \todo setting im, abs, deg branches untested * \todo main else branch untested */ void read_set_command(const char *command_string) { char unit[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char parameter_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; set_command_t *set_command; if (inter.num_set_cmds >= mem.num_set_cmds) { gerror("Line `%s':\ntoo many set commands.\n", command_string); } set_command = &inter.set_list[inter.num_set_cmds]; int num_vars_read = sscanf(command_string, "%s %s %s %s %80s", command_name, object_name, component_name, parameter_name, rest_string); int num_vars_expected = 4; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'set name component parameter'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } check_funcname(object_name, command_string); int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { gerror("Line `%s':\ncomponent name '%s' not found.\n", command_string, component_name); } int component_type = get_component_type(component_index); if (component_type == OUT) { int detector_index = get_component_index(component_index); output_data_t *output_data; output_data = &inter.output_data_list[detector_index]; strcpy(set_command->component_name, output_data->name); if (strcasecmp("re", parameter_name) == 0) { set_command->value = &(output_data->re); strcpy(set_command->parameter_name, "re"); } else if (strcasecmp("im", parameter_name) == 0) { set_command->value = &(output_data->im); strcpy(set_command->parameter_name, "im"); } else if (strcasecmp("abs", parameter_name) == 0) { set_command->value = &(output_data->abs); strcpy(set_command->parameter_name, "abs"); } else if (strcasecmp("deg", parameter_name) == 0) { set_command->value = &(output_data->deg); strcpy(set_command->parameter_name, "deg"); } else { gerror("Line `%s':\nplease give re/im/abs/deg as parameter.\n", command_string, component_name); } set_command->is_detector = true; } else { int error_code = get_xparam(&set_command->value, component_index, parameter_name, unit, command_string, &set_command->lborder, &set_command->uborder, &set_command->min, &set_command->max); if (error_code != 0) { my_finish(1); } strcpy(set_command->component_name, component_name); strcpy(set_command->parameter_name, parameter_name); set_command->is_detector = false; } char *dollar_char; dollar_char = strchr(object_name, '$'); if (dollar_char != NULL) { gerror("must not use '$' in set names.\n", command_string); } set_command->name[0] = '$'; strcpy(set_command->name + 1, object_name); inter.num_set_cmds++; } //! Reads a noplot command /*! * \param command_string the input command string */ void read_noplot(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; int component_type; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %16s %80s", command_name, component_name, rest_string); int num_vars_expected = 2; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'noplot output\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { gerror("Line `%s':\noutput name '%s' not found.\n", command_string, component_name); } component_type = get_component_type_decriment_index(&component_index); if (component_type != OUT) { gerror("Line `%s':\nexpected 'noplot output\n", command_string); } else { inter.output_data_list[component_index].noplot = true; } } //! Reads a func command /*! * \param command_string the input command string * * \todo num_locks > 0 branch untested * \todo object_name -> function_name */ void read_func_command(const char *command_string) { char function_string[LINE_LEN] = {0}; char object_name[LINE_LEN] = {0}; char object_name_string[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; char token[2] = {0}; if (inter.num_func_cmds >= mem.num_func_cmds) { gerror("Line `%s':\ntoo many functions.\n", command_string); } output_data_t *output_data; output_data = &(inter.output_data_list[inter.num_outputs]); func_command_t *func_command; func_command = &inter.function_list[inter.num_func_cmds]; strcpy(function_string, command_string + 4); int err = find_equal(object_name, function_string); if (err == 1) { gerror("Line `%s':\nNo equals sign found. Expected 'func name = function-string'\n", command_string); } else if (err == 2) { gerror("Line `%s':\nFunction name too long\n", command_string); } int num_vars_read = sscanf(object_name, "%16s %80s", object_name_string, rest_string); if (num_vars_read != 1) { gerror("Line `%s':\nexpected 'func name = function-string'\n", command_string); } strcpy(object_name, object_name_string); check_funcname(object_name, command_string); func_command->is_detector = false; // find "set" variables in function string and replace by // single letter int num_tokens_found = 0; token[1] = '\0'; int num_replaced_strings = 0; int set_cmd_index; for (set_cmd_index = 0; set_cmd_index < inter.num_set_cmds; set_cmd_index++) { token[0] = *(functokens + num_tokens_found); set_command_t *set_command; set_command = &inter.set_list[set_cmd_index]; num_replaced_strings = replace_string(function_string, set_command->name, token, strlen(set_command->name), 1); if (num_replaced_strings < 0) { bug_error("func lengths 1"); } if (num_replaced_strings > 0) { func_command->input[num_tokens_found] = set_command->value; if (func_command->input[num_tokens_found] == NULL) { bug_error("null pointer func, set 1"); } func_command->type[num_tokens_found] = XSET; func_command->token_number[num_tokens_found] = set_cmd_index; if (set_command->is_detector) { func_command->is_detector = true; } num_tokens_found++; } } // find already defined function names in function string and replace by // single letter int func_cmd_index; for (func_cmd_index = 0; func_cmd_index < inter.num_func_cmds; func_cmd_index++) { token[0] = *(functokens + num_tokens_found); func_command_t *func_command_read; func_command_read = &inter.function_list[func_cmd_index]; num_replaced_strings = replace_string(function_string, func_command_read->name, token, strlen(func_command_read->name), 1); if (num_replaced_strings < 0) { bug_error("func lengths 2"); } if (num_replaced_strings > 0) { func_command->input[num_tokens_found] = &(func_command_read->result); if (func_command->input[num_tokens_found] == NULL) { bug_error("read func NULL pointer 2"); } func_command->type[num_tokens_found] = FUNC; func_command->token_number[num_tokens_found] = func_cmd_index; if (func_command_read->is_detector) { func_command->is_detector = true; } num_tokens_found++; } } // find already defined lock names in function string and replace by // single letter int lock_index; for (lock_index = 0; lock_index < inter.num_locks; lock_index++) { token[0] = *(functokens + num_tokens_found); lock_command_t *lock_command; lock_command = &inter.lock_list[lock_index]; num_replaced_strings = replace_string(function_string, lock_command->name, token, strlen(lock_command->name), 1); if (num_replaced_strings < 0) { bug_error("func lengths 3"); } if (num_replaced_strings > 0) { func_command->input[num_tokens_found] = &(lock_command->value); if (func_command->input[num_tokens_found] == NULL) { bug_error("read func NULL pointer 3"); } func_command->type[num_tokens_found] = LOCK; func_command->token_number[num_tokens_found] = lock_index; num_tokens_found++; } } // find xaxis names (x/x1, x2, x3, mx1, mx2, mx3) in function string and replace by // single letter token[0] = *(functokens + num_tokens_found); num_replaced_strings = replace_string(function_string, "$mx3", token, 4, 1); if (num_replaced_strings < 0) { bug_error("func lengths 3a"); } if (num_replaced_strings > 0) { func_command->input[num_tokens_found] = &inter.x3.minus_xaxis; if (func_command->input[num_tokens_found] == NULL) { bug_error("null pointer func, mx3"); } func_command->type[num_tokens_found] = MX3; func_command->token_number[num_tokens_found] = 1; num_tokens_found++; } token[0] = *(functokens + num_tokens_found); num_replaced_strings = replace_string(function_string, "$mx2", token, 4, 1); if (num_replaced_strings < 0) { bug_error("func lengths 3b"); } if (num_replaced_strings > 0) { func_command->input[num_tokens_found] = &inter.x2.minus_xaxis; if (func_command->input[num_tokens_found] == NULL) { bug_error("null pointer func, mx2"); } func_command->type[num_tokens_found] = MX2; func_command->token_number[num_tokens_found] = 1; num_tokens_found++; } token[0] = *(functokens + num_tokens_found); num_replaced_strings = replace_string(function_string, "$mx1", token, 4, 1); if (num_replaced_strings < 0) { bug_error("func lengths 3c"); } if (num_replaced_strings > 0) { func_command->input[num_tokens_found] = &inter.x1.minus_xaxis; if (func_command->input[num_tokens_found] == NULL) { bug_error("null pointer func, mx1"); } func_command->type[num_tokens_found] = MX1; func_command->token_number[num_tokens_found] = 1; num_tokens_found++; } token[0] = *(functokens + num_tokens_found); num_replaced_strings = replace_string(function_string, "$x3", token, 3, 1); if (num_replaced_strings < 0) { bug_error("func lengths 3"); } if (num_replaced_strings > 0) { func_command->input[num_tokens_found] = inter.x3.xaxis; if (func_command->input[num_tokens_found] == NULL) { bug_error("null pointer func, x3"); } func_command->type[num_tokens_found] = X3; func_command->token_number[num_tokens_found] = 1; num_tokens_found++; } token[0] = *(functokens + num_tokens_found); num_replaced_strings = replace_string(function_string, "$x2", token, 3, 1); if (num_replaced_strings < 0) { bug_error("func lengths 4"); } if (num_replaced_strings > 0) { func_command->input[num_tokens_found] = inter.x2.xaxis; if (func_command->input[num_tokens_found] == NULL) { bug_error("null pointer func, x2"); } func_command->type[num_tokens_found] = X2; func_command->token_number[num_tokens_found] = 1; num_tokens_found++; } token[0] = *(functokens + num_tokens_found); num_replaced_strings = replace_string(function_string, "$x1", token, 3, 1); if (num_replaced_strings < 0) { bug_error("func lengths 5"); } if (num_replaced_strings > 0) { func_command->input[num_tokens_found] = inter.x1.xaxis; if (func_command->input[num_tokens_found] == NULL) { bug_error("null pointer func, x1"); } func_command->type[num_tokens_found] = X1; func_command->token_number[num_tokens_found] = 1; num_tokens_found++; } token[0] = *(functokens + num_tokens_found); num_replaced_strings = replace_string(function_string, "$fs", token, 3, 1); if (num_replaced_strings < 0) { bug_error("func lengths 3"); } if (num_replaced_strings > 0) { func_command->input[num_tokens_found] = &inter.fsig; if (func_command->input[num_tokens_found] == NULL) { bug_error("null pointer func, fsig"); } func_command->type[num_tokens_found] = _FS; func_command->token_number[num_tokens_found] = 1; num_tokens_found++; } token[0] = *(functokens + num_tokens_found); num_replaced_strings = replace_string(function_string, "$mfs", token, 4, 1); if (num_replaced_strings < 0) { bug_error("func lengths 4"); } if (num_replaced_strings > 0) { func_command->input[num_tokens_found] = &inter.mfsig; if (func_command->input[num_tokens_found] == NULL) { bug_error("null pointer func, -fsig"); } func_command->type[num_tokens_found] = _MFS; func_command->token_number[num_tokens_found] = 1; num_tokens_found++; } func_command->num_tokens = num_tokens_found; strncpy(func_command->tokens, functokens, num_tokens_found); strcpy(func_command->fstring, function_string); int function_length; int error_code; func_command->formula = translate(function_string, func_command->tokens, &function_length, &error_code); if (function_length == 0) { fprintf(stderr, "*** Error in translating function:\n"); fprintf(stderr, " %s = %s (tokens:", object_name, function_string); int token_index; for (token_index = 0; token_index < func_command->num_tokens; token_index++) { fprintf(stderr, " %c=", *(func_command->tokens + token_index)); int func_token_index = func_command->token_number[token_index]; switch (func_command->type[token_index]) { case XSET: fprintf(stderr, "%s", inter.set_list[func_token_index].name); break; case FUNC: fprintf(stderr, "%s", inter.function_list[func_token_index].name); break; case LOCK: fprintf(stderr, "%s", inter.lock_list[func_token_index].name); break; case X1: fprintf(stderr, "$x1"); break; case X2: fprintf(stderr, "$x2"); break; case X3: fprintf(stderr, "$x3"); break; case MX1: fprintf(stderr, "$mx1"); break; case MX2: fprintf(stderr, "$mx2"); break; case MX3: fprintf(stderr, "$mx3"); break; default: bug_error("translate errmsg 1"); } } fprintf(stderr, ")\n"); int i; for (i = 0; i < error_code + (int) strlen(object_name) + 1; i++) { putc('-', stderr); } fprintf(stderr, "---^\n"); fprintf(stderr, "%s\n", fget_error()); my_finish(1); } char *dollar_char; dollar_char = strchr(object_name, '$'); if (dollar_char != NULL) { gerror("must not use '$' in function names.\n", command_string); } func_command->name[0] = '$'; strcpy(func_command->name + 1, object_name); inter.func_order[inter.num_func_cmds] = inter.num_locks_and_funcs; inter.is_locked[inter.num_locks_and_funcs] = false; output_data->output_type = REAL; strcpy(output_data->name, func_command->name + 1); output_data->beam_param_not_set = true; output_data->detector_type = UFUNCTION; output_data->qx = NULL; output_data->qy = NULL; output_data->detector_index = inter.num_func_cmds; func_command->output = inter.num_outputs; inter.num_outputs++; output_data->noplot = false; inter.num_func_cmds++; inter.num_locks_and_funcs++; } //! Reads the showiterate command /*! * \param command_string the input command string * * \todo refactor routine for readability * * \todo untested */ void read_showiterate(const char *command_string) { int val1; int num_vars_read; char rest_string[REST_STRING_LEN] = {0}; if ((num_vars_read = sscanf(command_string + 12, "%d %80s", &val1, rest_string)) < 1) { gerror("Line `%s':\nexpected showiterate steps\n", command_string); } if (num_vars_read > 1) { warn("Line `%s': text '%s' ignored\n", command_string, rest_string); } if ((val1 <= 0) && (val1 != -1)) { gerror("Line `%s':\nsteps must be -1 or >0\n", command_string); } if (inter.showiterate) { warn("Line `%s': showiterate already set, using new value.\n", command_string, rest_string); } inter.showiterate = val1; } //! Reads a lock* command /*! * \param command_string the input command string * * \todo refactor routine for readability */ void read_lock2(const char *command_string) { char sc[LINE_LEN] = {0}; strcpy(sc, "lock"); strcat(sc, command_string + 5); read_lock_command(sc); inter.lock_list[inter.num_locks - 1].once = 1; } //! Reads a lock command /*! * \param command_string the input command string */ void read_lock_command(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char func_or_set_name[MAX_TOKEN_LEN] = {0}; char gain_string[LINE_LEN] = {0}; char accuracy_string[LINE_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; lock_command_t *lock_command; output_data_t *output_data; if (inter.num_locks >= mem.num_locks) { gerror("Line `%s':\ntoo many locks.\n", command_string); } output_data = &(inter.output_data_list[inter.num_outputs]); lock_command = &inter.lock_list[inter.num_locks]; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %80s", command_name, object_name, func_or_set_name, gain_string, accuracy_string, rest_string); int num_vars_expected = 5; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'lock name function/set gain accuracy'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } // get the accuracy value and check it double accuracy; if (atod(accuracy_string, &accuracy)) { gerror("Line `%s':\nUnable to read accuracy\n", command_string); } if (accuracy <= 0) { gerror("Line `%s':\naccuracy must be >0.\n", command_string); } lock_command->accuracy = accuracy; // get the gain value and check it double gain; if (atod(gain_string, &gain)) { gerror("Line `%s':\nUnable to read gain\n", command_string); } if (gain == 0) { gerror("Line `%s':\ngain must not be 0.\n", command_string); } lock_command->gain = gain; check_funcname(object_name, command_string); int num_sets_and_funcs_found = 0; int set_cmd_index; for (set_cmd_index = 0; set_cmd_index < inter.num_set_cmds; set_cmd_index++) { set_command_t *set_command; set_command = &inter.set_list[set_cmd_index]; if (strcasecmp(func_or_set_name, set_command->name) == 0) { lock_command->input = set_command->value; if (lock_command->input == NULL) { bug_error("null pointer lock, set 1"); } if (!set_command->is_detector) { gerror("Line `%s':\n" "lock input must include some detector signal.\n", command_string); } num_sets_and_funcs_found++; } } int func_cmd_index; for (func_cmd_index = 0; func_cmd_index < inter.num_func_cmds; func_cmd_index++) { func_command_t *func_command; func_command = &inter.function_list[func_cmd_index]; if (strcasecmp(func_or_set_name, func_command->name) == 0) { lock_command->input = &(func_command->result); if (lock_command->input == NULL) { bug_error("null pointer lock, set 2"); } if (!func_command->is_detector) { gerror("Line `%s':\n" "lock input must include some detector signal.\n", command_string); } num_sets_and_funcs_found++; } } if (num_sets_and_funcs_found == 0) { gerror("Line `%s':\nlock input signal not found.\n", command_string); } lock_command->name[0] = '$'; strcpy(lock_command->name + 1, object_name); strcpy(lock_command->iname, func_or_set_name); lock_command->value = 0.0; lock_command->once = 0; inter.lock_order[inter.num_func_cmds] = inter.num_locks_and_funcs; inter.is_locked[inter.num_locks_and_funcs] = true; output_data->output_type = REAL; strcpy(output_data->name, lock_command->name + 1); output_data->beam_param_not_set = true; output_data->detector_type = FEEDBACK; output_data->qx = NULL; output_data->qy = NULL; output_data->detector_index = inter.num_locks; inter.num_outputs++; output_data->noplot = false; inter.num_locks++; inter.num_locks_and_funcs++; inter.lock |= 1; } //! Reads the x2 axis command /*! * \param command_string the input command string */ void read_x2axis2(const char *command_string) { char unit[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char component_name[MAX_TOKEN_LEN] = {0}; char parameter_name[MAX_TOKEN_LEN] = {0}; char lin_or_log[MAX_TOKEN_LEN] = {0}; char axis_minimum_string[LINE_LEN] = {0}; char axis_maximum_string[LINE_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; endcomp = 1; lastparam = -1; if (inter.x2.xsteps != NO_FREQ || inter.x2.xtype != NO_FREQ) { gerror("Line `%s':\nx2axis already defined'\n", command_string); } int num_steps; int num_vars_read = sscanf(command_string, "%s %s %s %3s %s %s %d %80s", command_name, component_name, parameter_name, lin_or_log, axis_minimum_string, axis_maximum_string, &num_steps, rest_string); int num_vars_expected = 7; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\n" "expected 'x2axis* component parameter lin/log min max steps'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { int detector_index = get_detector_or_node_index_from_name(component_name); if (detector_index == NOT_FOUND) { gerror("Line `%s':\ncomponent name '%s' not found.\n", command_string, component_name); component_index = detector_index; } } if (strncasecmp(lin_or_log, "lin", 3) == 0) { inter.x2.xtype = FLIN; } if (strncasecmp(lin_or_log, "log", 3) == 0) { inter.x2.xtype = FLOG; } if (inter.x2.xtype == NO_FREQ) { gerror("Line `%s':\n" "expected 'x2axis* component parameter lin/log min max steps'\n", command_string); } if (num_steps < 1) { gerror("Line `%s':\nnumber of steps < 1 illegal'\n", command_string); } if (get_xparam(&inter.x2.xaxis, component_index, parameter_name, unit, command_string, &inter.x2.lborder, &inter.x2.uborder, &inter.x2.min, &inter.x2.max)) { my_finish(1); } inter.x2.op = *inter.x2.xaxis; double axis_min; if (atod(axis_minimum_string, &axis_min)) { gerror("Line `%s':\nUnable to read axis minimum value\n", command_string); } double axis_max; if (atod(axis_maximum_string, &axis_max)) { gerror("Line `%s':\nUnable to read axis maximum value\n", command_string); } if (inter.x2.xtype == FLOG) { axis_min = axis_min * inter.x2.op; axis_max = axis_max * inter.x2.op; } else { axis_min = axis_min + inter.x2.op; axis_max = axis_max + inter.x2.op; } /* if (x2 num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { int detector_index = get_detector_or_node_index_from_name(component_name); if (detector_index == NOT_FOUND) { gerror("Line `%s':\ncomponent name '%s' not found.\n", command_string, component_name); component_index = detector_index; } } if (strncasecmp(linlog, "lin", 3) == 0) { inter.x2.xtype = FLIN; } if (strncasecmp(linlog, "log", 3) == 0) { inter.x2.xtype = FLOG; } if (inter.x2.xtype == NO_FREQ) { gerror("Line `%s':\n" "expected 'x2axis component parameter lin/log min max steps'\n", command_string); } if (num_steps < 0) { gerror("Line `%s':\nsteps<0 illegal'\n", command_string); } /* if (x2 num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { int detector_index = get_detector_or_node_index_from_name(component_name); if (detector_index == NOT_FOUND) { gerror("Line `%s':\ncomponent name '%s' not found.\n", command_string, component_name); component_index = detector_index; } } if (strncasecmp(linlog, "lin", 3) == 0) { inter.x3.xtype = FLIN; } if (strncasecmp(linlog, "log", 3) == 0) { inter.x3.xtype = FLOG; } if (inter.x3.xtype == NO_FREQ) { gerror("Line `%s':\n" "expected 'x3axis* component parameter lin/log min max steps'\n", command_string); } if (num_steps < 0) { gerror("Line `%s':\nsteps<0 illegal'\n", command_string); } int error_code = get_xparam(&inter.x3.xaxis, component_index, parameter_name, unit, command_string, &inter.x3.lborder, &inter.x3.uborder, &inter.x3.min, &inter.x3.max); if (error_code != 0) { my_finish(1); } inter.x3.op = *inter.x3.xaxis; double axis_min; if (atod(axis_minimum_string, &axis_min)) { gerror("Line `%s':\nUnable to read axis minimum value\n", command_string); } double axis_max; if (atod(axis_maximum_string, &axis_max)) { gerror("Line `%s':\nUnable to read axis maximum value\n", command_string); } if (inter.x3.xtype == FLOG) { axis_min = axis_min * inter.x3.op; axis_max = axis_max * inter.x3.op; } else { axis_min = axis_min + inter.x3.op; axis_max = axis_max + inter.x3.op; } /* if (x2 num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { int detector_index = get_detector_or_node_index_from_name(component_name); if (detector_index == NOT_FOUND) { gerror("Line `%s':\ncomponent name '%s' not found.\n", command_string, component_name); component_index = detector_index; } } if (strncasecmp(linlog, "lin", 3) == 0) { inter.x3.xtype = FLIN; } if (strncasecmp(linlog, "log", 3) == 0) { inter.x3.xtype = FLOG; } if (inter.x3.xtype == NO_FREQ) { gerror("Line `%s':\n" "expected 'x3axis component parameter lin/log min max steps'\n", command_string); } if (num_steps < 0) { gerror("Line `%s':\nsteps<0 illegal'\n", command_string); } /* if (x2= mem.num_diff_cmds) { gerror("Line `%s':\ntoo many differentiations\n", command_string); } int num_vars_read = sscanf(command_string, "%s %s %s %80s", command_name, component_name, parameter_name, rest_string); int num_vars_expected = 3; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'diff component parameter'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_diff_cmds >= mem.num_diff_cmds) { gerror("Line `%s':\ntoo many differentiations\n", command_string); } derivative = &(inter.deriv_list[inter.num_diff_cmds]); int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { int detector_index = get_detector_or_node_index_from_name(component_name); if (detector_index == NOT_FOUND) { gerror("Line `%s';\ncomponent name '%s' not found.\n", command_string, component_name); component_index = detector_index; } } int error_code = get_xparam(&(derivative->xderiv), component_index, parameter_name, unit, command_string, &(derivative->lborder), &(derivative->uborder), &(derivative->min), &(derivative->max)); if (error_code != 0) { my_finish(1); } strcpy(derivative->name, parameter_name); strcat(derivative->name, " ("); strcat(derivative->name, component_name); strcat(derivative->name, ")"); inter.num_diff_cmds++; } //! Sets upper and/or lower boundaries for parameters. /*! * lborder, uborder = 0 -> no boundary * lborder, uborder = 1 -> boundary set: x must not be < min or > max * lborder, uborder = 2 -> boundary set: x must not be <= min or >= max * * \param xparam ??? * \param i ??? * \param parameter ??? * \param unit ??? * \param command_string ??? * \param lborder ??? * \param uborder ??? * \param min ??? * \param max ??? * * \todo refactor routine for readability * * \todo LENS and DIODE branches are untested */ int get_xparam(double **xparam, int i, const char *parameter, char *unit, const char *command_string, int *lborder, int *uborder, double *min, double *max) { int component_type = get_component_type_decriment_index(&i); component_param_t component_param; component_param.xparam = xparam; component_param.component_type = component_type; component_param.component_index = i; component_param.parameter = parameter; component_param.unit = unit; component_param.command_string = command_string; component_param.lborder = lborder; component_param.uborder = uborder; component_param.min = min; component_param.max = max; switch (component_type) { case MIRROR: assign_mirror_parameter(&component_param); break; case BEAMSPLITTER: assign_beamsplitter_parameter(&component_param); break; case SPACE: assign_space_parameter(&component_param); break; case SAGNAC: assign_sagnac_parameter(&component_param); break; case LENS: assign_lens_parameter(&component_param); break; case DIODE: assign_diode_parameter(&component_param); break; case LIGHT_INPUT: assign_laser_parameter(&component_param); break; case MODULATOR: assign_modulator_parameter(&component_param); break; case GRATING: assign_grating_parameter(&component_param); break; case FSIG: assign_fsig_parameter(&component_param); break; case VARIABLE: assign_variable_parameter(&component_param); break; case OUT: assign_detector_parameter(&component_param); break; case BEAMPARAM: assign_beam_parameter(&component_param); break; case TF: assign_tf_parameter(&component_param); break; default: server_gerror("Line `%s':\ninvalid component\n", command_string); return (-1); } return (0); } //! Assign attribute parameters to the mirror object /*! * \param component_param structure containing parameter-setting information * * \todo yBeta and M branches untested */ int assign_mirror_parameter(component_param_t *component_param) { mirror_t *mirror; mirror = &inter.mirror_list[component_param->component_index]; if (strcasecmp("phi", component_param->parameter) == 0) { *component_param->xparam = &(mirror->phi); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("r", component_param->parameter) == 0 || strcasecmp("R", component_param->parameter) == 0) { *component_param->xparam = &(mirror->R); strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 1; *component_param->max = 1.0; *component_param->min = 0.0; } else if (strcasecmp("t", component_param->parameter) == 0 || strcasecmp("T", component_param->parameter) == 0) { *component_param->xparam = &(mirror->T); strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 1; *component_param->max = 1.0; *component_param->min = 0.0; } else if (strcasecmp("xbeta", component_param->parameter) == 0 || strcasecmp("xBeta", component_param->parameter) == 0 || strcasecmp("yaw", component_param->parameter) == 0) { *component_param->xparam = &(mirror->beta_x); strcpy(component_param->unit, " [rad]"); mirror->rebuild = 1; inter.rebuild |= 1; *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("ybeta", component_param->parameter) == 0 || strcasecmp("yBeta", component_param->parameter) == 0 || strcasecmp("pitch", component_param->parameter) == 0) { *component_param->xparam = &(mirror->beta_y); strcpy(component_param->unit, " [rad]"); mirror->rebuild = 1; inter.rebuild |= 1; *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("m", component_param->parameter) == 0 || strcasecmp("mass", component_param->parameter) == 0) { *component_param->xparam = &(mirror->mass); strcpy(component_param->unit, " [kg]"); *component_param->lborder = 2; *component_param->uborder = 0; *component_param->min = 0.0; } else if (strcasecmp("ix", component_param->parameter) == 0 || strcasecmp("moix", component_param->parameter) == 0) { *component_param->xparam = &(mirror->Ix); strcpy(component_param->unit, " [kg.m^2]"); *component_param->lborder = 2; *component_param->uborder = 0; *component_param->min = 0.0; } else if (strcasecmp("iy", component_param->parameter) == 0 || strcasecmp("moiy", component_param->parameter) == 0) { *component_param->xparam = &(mirror->Iy); strcpy(component_param->unit, " [kg.m^2]"); *component_param->lborder = 2; *component_param->uborder = 0; *component_param->min = 0.0; } else if (strcasecmp("Rcx", component_param->parameter) == 0 || strcasecmp("rx", component_param->parameter) == 0 || strcasecmp("Rx", component_param->parameter) == 0 || strcasecmp("rcx", component_param->parameter) == 0 || strcasecmp("ROCx", component_param->parameter) == 0 || strcasecmp("rocx", component_param->parameter) == 0) { *component_param->xparam = &(mirror->Rcx); mirror->rebuild = 2; inter.rebuild |= 2; strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("Rcy", component_param->parameter) == 0 || strcasecmp("ry", component_param->parameter) == 0 || strcasecmp("Ry", component_param->parameter) == 0 || strcasecmp("rcy", component_param->parameter) == 0 || strcasecmp("ROCy", component_param->parameter) == 0 || strcasecmp("rocy", component_param->parameter) == 0) { *component_param->xparam = &(mirror->Rcy); mirror->rebuild = 2; inter.rebuild |= 2; strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("r_ap", component_param->parameter) == 0 || strcasecmp("Rap", component_param->parameter) == 0 || strcasecmp("rap", component_param->parameter) == 0){ *component_param->xparam = &(mirror->r_aperture); mirror->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; *component_param->min = 0; } else if (strcasecmp("x_off", component_param->parameter) == 0){ *component_param->xparam = &(mirror->x_off); mirror->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; *component_param->min = 0; } else if (strcasecmp("y_off", component_param->parameter) == 0){ *component_param->xparam = &(mirror->y_off); mirror->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; *component_param->min = 0; } else if (strcasecmp("map_deg", component_param->parameter) == 0){ *component_param->xparam = &(mirror->angle); mirror->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("dither_f", component_param->parameter) == 0) { *component_param->xparam = &(mirror->dither_f); strcpy(component_param->unit, " [Hz]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("dither_m", component_param->parameter) == 0) { *component_param->xparam = &(mirror->dither_m); strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("dither_phase", component_param->parameter) == 0) { *component_param->xparam = &(mirror->dither_phase); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\nno parameter '%s' at mirror\n", component_param->command_string, component_param->parameter); return (-1); } return (0); } //! Assign attribute parameters to the beamsplitter object /*! * \param component_param structure containing parameter-setting information * * \todo alpha, yBeta, M, Rcx, Rcy, r, t setting branches untested */ int assign_beamsplitter_parameter(component_param_t *component_param) { beamsplitter_t *beamsplitter; beamsplitter = &inter.bs_list[component_param->component_index]; if (strcasecmp("phi", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->phi); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("r_ap", component_param->parameter) == 0 || strcasecmp("Rap", component_param->parameter) == 0 || strcasecmp("rap", component_param->parameter) == 0){ *component_param->xparam = &(beamsplitter->r_aperture); beamsplitter->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; *component_param->min = 0; } else if (strcasecmp("x_off", component_param->parameter) == 0){ *component_param->xparam = &(beamsplitter->x_off); beamsplitter->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; *component_param->min = 0; } else if (strcasecmp("y_off", component_param->parameter) == 0){ *component_param->xparam = &(beamsplitter->y_off); beamsplitter->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; *component_param->min = 0; } else if (strcasecmp("alpha", component_param->parameter) == 0 || strcasecmp("Alpha", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->alpha_1); strcpy(component_param->unit, " [deg]"); beamsplitter->rebuild = 2; inter.rebuild |= 2; *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("xbeta", component_param->parameter) == 0 || strcasecmp("xBeta", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->beta_x); strcpy(component_param->unit, " [rad]"); beamsplitter->rebuild = 1; inter.rebuild |= 1; *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("ybeta", component_param->parameter) == 0 || strcasecmp("yBeta", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->beta_y); strcpy(component_param->unit, " [rad]"); beamsplitter->rebuild = 1; inter.rebuild |= 1; *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("m", component_param->parameter) == 0 || strcasecmp("M", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->mass); strcpy(component_param->unit, " [kg]"); *component_param->lborder = 2; *component_param->uborder = 0; *component_param->min = 0.0; } else if (strcasecmp("Rcx", component_param->parameter) == 0 || strcasecmp("rx", component_param->parameter) == 0 || strcasecmp("Rx", component_param->parameter) == 0 || strcasecmp("rcx", component_param->parameter) == 0 || strcasecmp("ROCx", component_param->parameter) == 0 || strcasecmp("rocx", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->Rcx); beamsplitter->rebuild = 2; inter.rebuild |= 2; strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("Rcy", component_param->parameter) == 0 || strcasecmp("ry", component_param->parameter) == 0 || strcasecmp("Ry", component_param->parameter) == 0 || strcasecmp("rcy", component_param->parameter) == 0 || strcasecmp("ROCy", component_param->parameter) == 0 || strcasecmp("rocy", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->Rcy); beamsplitter->rebuild = 2; inter.rebuild |= 2; strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("r", component_param->parameter) == 0 || strcasecmp("R", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->R); strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 1; *component_param->max = 1.0; *component_param->min = 0.0; } else if (strcasecmp("t", component_param->parameter) == 0 || strcasecmp("T", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->T); strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 1; *component_param->max = 1.0; *component_param->min = 0.0; } else if (strcasecmp("angle", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->map_rotation); beamsplitter->rebuild = 2; inter.rebuild |= 2; strcpy(component_param->unit, " [deg] "); *component_param->max = 0.0; *component_param->min = 0.0; } else if (strcasecmp("dither_f", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->dither_f); strcpy(component_param->unit, " [Hz]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("dither_m", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->dither_m); strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("dither_phase", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->dither_phase); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("backscatter", component_param->parameter) == 0) { *component_param->xparam = &(beamsplitter->backscatter); strcpy(component_param->unit, " "); *component_param->lborder = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\nno parameter '%s' at beamsplitter\n", component_param->command_string, component_param->parameter); return (-1); } return (0); } //! Assign attribute parameters to the space object /*! * \param component_param structure containing parameter-setting information * * \todo gouyx, gouyy, and n setting branches untested */ int assign_space_parameter(component_param_t *component_param) { space_t *space; space = &inter.space_list[component_param->component_index]; if ((strcasecmp("phix", component_param->parameter) == 0) || (strcasecmp("gouyx", component_param->parameter) == 0) || (strcasecmp("gx", component_param->parameter) == 0)) { *component_param->xparam = &(space->gouy_x); //inter.space_list[component_param->component_index].rebuild=0; strcpy(component_param->unit, " [rad]"); *component_param->lborder = 0; *component_param->uborder = 0; *component_param->min = 0; } else if (strcasecmp("phiy", component_param->parameter) == 0 || strcasecmp("gouyy", component_param->parameter) == 0 || strcasecmp("gy", component_param->parameter) == 0) { *component_param->xparam = &(space->gouy_y); //inter.space_list[component_param->component_index].rebuild=0; strcpy(component_param->unit, " [rad]"); *component_param->lborder = 0; *component_param->uborder = 0; *component_param->min = 0.0; } else if (strcasecmp("L", component_param->parameter) == 0) { *component_param->xparam = &(space->L); space->rebuild = 2; inter.rebuild |= 2; strcpy(component_param->unit, " [m]"); *component_param->lborder = 1; *component_param->uborder = 0; *component_param->min = 0.0; } else if (strcasecmp("n", component_param->parameter) == 0) { *component_param->xparam = &(space->n); space->rebuild = 2; inter.rebuild |= 2; strcpy(component_param->unit, " "); *component_param->lborder = 2; *component_param->uborder = 0; *component_param->min = 0.0; } else { server_gerror("Line `%s':\nno parameter '%s' at space\n", component_param->command_string, component_param->parameter); return (-1); } return (0); } //! Assign attribute parameters to the sagnac object /*! * \param component_param structure containing parameter-setting information */ int assign_sagnac_parameter(component_param_t *component_param) { sagnac_t *sagnac; sagnac = &inter.sagnac_list[component_param->component_index]; if (strcasecmp("phi", component_param->parameter) == 0) { *component_param->xparam = &(sagnac->dphi); strcpy(component_param->unit, " [rad]"); *component_param->lborder = 1; *component_param->uborder = 0; *component_param->min = 0.0; } else { server_gerror("Line `%s':\nno parameter '%s' at sagnac\n", component_param->command_string, component_param->parameter); return (-1); } return (0); } //! Assign attribute parameters to the lens object /*! * \param component_param structure containing parameter-setting information * * \todo untested */ int assign_lens_parameter(component_param_t *component_param) { lens_t *lens; lens = &inter.lens_list[component_param->component_index]; if (strcasecmp("f", component_param->parameter) == 0) { if(!lens->is_focal_length){ warn("Tuning focal length when lens %s was set to use optical power\n", lens->name); lens->is_focal_length = true; lens->f_of_D = 1.0/lens->f_of_D; } *component_param->xparam = &(lens->f_of_D); lens->rebuild = 2; inter.rebuild |= 2; strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("P", component_param->parameter) == 0) { if(lens->is_focal_length){ warn("Tuning optical power when lens %s was set to use focal length\n", lens->name); lens->is_focal_length = false; lens->f_of_D = 1.0/lens->f_of_D; } *component_param->xparam = &(lens->f_of_D); lens->rebuild = 2; inter.rebuild |= 2; strcpy(component_param->unit, " [Dioptres]"); *component_param->lborder = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\nno parameter '%s' at lens\n", component_param->command_string, component_param->parameter); return (-1); } return (0); } //! Assign attribute parameters to the diode object /*! * \param component_param structure containing parameter-setting information * * \todo untested */ int assign_diode_parameter(component_param_t *component_param) { if (strcasecmp("S", component_param->parameter)) { server_gerror("Line `%s':\nno parameter '%s' at isolator\n", component_param->command_string, component_param->parameter); return (-1); } *component_param->xparam = &(inter.diode_list[component_param->component_index].S); strcpy(component_param->unit, " [dB]"); *component_param->lborder = 1; *component_param->uborder = 0; *component_param->min = 0.0; return (0); } //! Assign attribute parameters to the 'variable' object /*! * \param component_param structure containing parameter-setting information * * \todo untested */ int assign_variable_parameter(component_param_t *component_param) { *component_param->xparam = &(inter.variable_list[component_param->component_index].param); strcpy(component_param->unit, " [a.u.]"); *component_param->lborder = 0; *component_param->uborder = 0; *component_param->min = 0.0; return (0); } //! Assign attribute parameters to the laser object /*! * \param component_param structure containing parameter-setting information * * \todo phi and I branches untested */ int assign_laser_parameter(component_param_t *component_param) { light_in_t *laser; laser = &inter.light_in_list[component_param->component_index]; if (strcasecmp("f", component_param->parameter) == 0) { if(laser->f == NULL) { if(strlen(laser->__frequency_name) > 0) { gerror("Can't tune %s frequency when set with a name\n", laser->name); } else { assert(laser->f != NULL); } } laser->f->isTuned = 1; *component_param->xparam = &(laser->f->f); strcpy(component_param->unit, " [Hz]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("phi", component_param->parameter) == 0 || strcasecmp("phase", component_param->parameter) == 0) { *component_param->xparam = &(laser->phase); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("I", component_param->parameter) == 0 || strcasecmp("p", component_param->parameter) == 0) { *component_param->xparam = &(laser->I0); strcpy(component_param->unit, " [W]"); *component_param->lborder = 1; *component_param->min = 0; *component_param->uborder = 0; } else if(laser->isSqueezed && strcasecmp("angle", component_param->parameter) == 0){ *component_param->xparam = &(laser->squeeze_angle); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if(laser->isSqueezed && strcasecmp("r", component_param->parameter) == 0){ *component_param->xparam = &(laser->squeeze_db); strcpy(component_param->unit, " [db]"); *component_param->lborder = 1; *component_param->min = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\nno parameter '%s' at input\n", component_param->command_string, component_param->parameter); return (-1); } return (0); } //! Assign attribute parameters to the modulator object /*! * \param component_param structure containing parameter-setting information * * \todo phase branch untested */ int assign_modulator_parameter(component_param_t *component_param) { modulator_t *modulator; modulator = &inter.modulator_list[component_param->component_index]; if (strcasecmp("f", component_param->parameter) == 0) { *component_param->xparam = &(modulator->f_mod); strcpy(component_param->unit, " [Hz]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("midx", component_param->parameter) == 0) { *component_param->xparam = &(modulator->modulation_index); strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 0; *component_param->min = 0; if (modulator->type == MODTYPE_AM) { *component_param->uborder = 1; *component_param->max = 1; } } else if (strcasecmp("phase", component_param->parameter) == 0 || strcasecmp("phi", component_param->parameter) == 0|| strcasecmp("phs", component_param->parameter) == 0) { *component_param->xparam = &(modulator->phase); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\nno parameter '%s' at modulator\n", component_param->command_string, component_param->parameter); return (-1); } return (0); } //! Assign attribute parameters to the grating object /*! * \param component_param structure containing parameter-setting information * * \todo d setting branch untested * \todo case 4: branch untested */ int assign_grating_parameter(component_param_t *component_param) { grating_t *grating; grating = &inter.grating_list[component_param->component_index]; if (strcasecmp("d", component_param->parameter) == 0) { *component_param->xparam = &(grating->d); grating->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " [nm]"); *component_param->lborder = 1; *component_param->uborder = 0; *component_param->min = 0; } else { switch (grating->num_of_ports) { case 2: if (strcasecmp("eta0", component_param->parameter) == 0) { *component_param->xparam = &(grating->eta[0]); grating->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 1; *component_param->min = 0; *component_param->max = 1; } else if (strcasecmp("eta1", component_param->parameter) == 0) { *component_param->xparam = &(grating->eta[1]); grating->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 1; *component_param->min = 0; *component_param->max = 1; } else { server_gerror("Line `%s':\nno parameter '%s' at grating (gr2)\n", component_param->command_string, component_param->parameter); return (-1); } break; case 3: if (strcasecmp("eta0", component_param->parameter) == 0) { *component_param->xparam = &(grating->eta[0]); grating->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 1; *component_param->min = 0; *component_param->max = 1; } else if (strcasecmp("eta1", component_param->parameter) == 0) { *component_param->xparam = &(grating->eta[1]); grating->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 1; *component_param->min = 0; *component_param->max = 1; } else if (strcasecmp("eta2", component_param->parameter) == 0) { *component_param->xparam = &(grating->eta[2]); grating->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 1; *component_param->min = 0; *component_param->max = 1; } else if (strcasecmp("rho0", component_param->parameter) == 0) { *component_param->xparam = &(grating->eta[3]); grating->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 1; *component_param->min = 0; *component_param->max = 1; } else { server_gerror("Line `%s':\nno parameter '%s' at grating (gr3)\n", component_param->command_string, component_param->parameter); return (-1); } break; case 4: if (strcasecmp("eta0", component_param->parameter) == 0) { *component_param->xparam = &(grating->eta[0]); grating->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 1; *component_param->min = 0; *component_param->max = 1; } else if (strcasecmp("eta1", component_param->parameter) == 0) { *component_param->xparam = &(grating->eta[1]); grating->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " "); *component_param->lborder = 1; *component_param->uborder = 1; *component_param->min = 0; *component_param->max = 1; } else if (strcasecmp("alpha", component_param->parameter) == 0) { *component_param->xparam = &(grating->alpha); grating->rebuild = 1; inter.rebuild |= 1; strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\nno parameter '%s' at grating (gr4)\n", component_param->command_string, component_param->parameter); return (-1); } break; default: bug_error("grating, wrong number of ports"); } } return (0); } //! Assign attribute parameters to the fsig object /*! * \param component_param structure containing parameter-setting information * * \todo phase and amp setting branches untested */ int assign_fsig_parameter(component_param_t *component_param) { signal_t *signal; signal = &inter.signal_list[component_param->component_index]; if (strcasecmp("f", component_param->parameter) == 0) { *component_param->xparam = &(inter.fsig); strcpy(component_param->unit, " [Hz]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("phase", component_param->parameter) == 0 || strcasecmp("phi", component_param->parameter) == 0|| strcasecmp("phs", component_param->parameter) == 0) { *component_param->xparam = &(signal->phase); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("amp", component_param->parameter) == 0) { *component_param->xparam = &(signal->amplitude); strcpy(component_param->unit, " "); *component_param->lborder = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\nno parameter '%s' at fsig\n", component_param->command_string, component_param->parameter); return (-1); } return (0); } //! Assign attribute parameters to the detector object /*! * \param component_param structure containing parameter-setting information * * \todo refactor!!! * \todo split up if/elseif sections into separate routines */ int assign_detector_parameter(component_param_t *component_param) { output_data_t *output_data; output_data = &inter.output_data_list[component_param->component_index]; if (output_data->detector_type == PD0 || output_data->detector_type == SHOT || output_data->detector_type == BP || output_data->detector_type == PG ) { server_gerror("Line `%s':\n" "cannot tune any parameter at this detector type " "(pd0/shot/bp/gouy)\n", component_param->command_string); return (-1); } else if(output_data->detector_type == HOMODYNE){ homodyne_t *hom = &inter.homodyne_list[output_data->detector_index]; assign_homodyne_detector_params(hom, component_param); } else if(output_data->detector_type == QD){ int detector_index = output_data->detector_index; light_out_t *detector; detector = &inter.light_out_list[detector_index]; assign_qd_detector_params(detector, component_param); } else { if (output_data->detector_type == FEEDBACK || output_data->detector_type == UFUNCTION) { bug_error("outtype FBACK 1"); } int detector_index = output_data->detector_index; light_out_t *detector; detector = &inter.light_out_list[detector_index]; if (output_data->detector_type == BEAM) { assign_beam_detector_params(detector, component_param); } else if (output_data->detector_type == AD) { int error_num = assign_amplitude_detector_params(detector, component_param); if (error_num != 0) { return error_num; } } else if (detector->num_demods == 1) { int error_num = assign_one_demod_detector_params(detector, component_param); if (error_num != 0) { return error_num; } }// handle f as a parameter else if (detector->num_demods > 1) { int error_num = assign_multi_demod_detector_params(detector, component_param); if (error_num != 0) { return error_num; } } else { bug_error("detector_type(new) xparam"); } } return (0); } /** * * @param component_param * @return */ int assign_tf_parameter(component_param_t *component_param) { transfer_func_t *tf = &inter.tf_list[component_param->component_index]; if(strcasecmp("factor", component_param->parameter) == 0){ *component_param->xparam = &(tf->gain); strcpy(component_param->unit, " [a.u]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if(strcasecmp("phase", component_param->parameter) == 0){ *component_param->xparam = &(tf->phase); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if(strlen(component_param->parameter) >= 3){ char first = component_param->parameter[0]; if(first == 'f' || first == 'F' || first == 'q' || first == 'Q'){ if(tf->type != Q_F_TF) { server_gerror("Line `%s':\nparameter '%s' not tunable for this type of transfer function\n", component_param->command_string, component_param->parameter); } char second = component_param->parameter[1]; const char *rest = &(component_param->parameter[2]); int index = atoi(rest); if(index < 1){ server_gerror("Line `%s':\nparameter '%s' number suffix must be greater than 0\n", component_param->command_string, component_param->parameter); return (-1); } if(second == 'p' || second == 'P') { if(index > tf->num_poles){ server_gerror("Line `%s':\nparameter '%s' pole %i does not exist\n", component_param->command_string, component_param->parameter, index); return (-1); } else if(first == 'f' || first == 'F'){ *component_param->xparam = &(tf->pole_Q_f[index-1].f); strcpy(component_param->unit, " [Hz]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if(first == 'q' || first == 'Q'){ *component_param->xparam = &(tf->pole_Q_f[index-1].Q); strcpy(component_param->unit, " [a.u]"); *component_param->lborder = 0; *component_param->uborder = 0; } } else if(second == 'z' || second == 'Z') { if(index > tf->num_zeros){ server_gerror("Line `%s':\nparameter '%s' zero %i does not exist\n", component_param->command_string, component_param->parameter, index); return (-1); } else if(first == 'f' || first == 'F'){ *component_param->xparam = &(tf->zero_Q_f[index-1].f); strcpy(component_param->unit, " [Hz]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if(first == 'q' || first == 'Q'){ *component_param->xparam = &(tf->zero_Q_f[index-1].Q); strcpy(component_param->unit, " [a.u]"); *component_param->lborder = 0; *component_param->uborder = 0; } } else { server_gerror("Line `%s':\nparameter '%s' second letter must be 'p' (pole) or 'z' (zero) for this type of transfer function\n", component_param->command_string, component_param->parameter); return (-1); } } } else { server_gerror("Line `%s':\nparameter '%s' not tunable for transfer function command\n", component_param->command_string, component_param->parameter); return (-1); } return 0; } //! Assign attribute parameters to a beam parametera at a given node /*! * \param component_param structure containing parameter-setting information * */ int assign_beam_parameter(component_param_t *component_param) { gauss_t *gauss; gauss = &(inter.gauss_list[component_param->component_index]); if (strcasecmp("zx", component_param->parameter) == 0) { *component_param->xparam = &(gauss->qx.re); strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("zy", component_param->parameter) == 0) { *component_param->xparam = &(gauss->qy.re); strcpy(component_param->unit, " [m]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("Zrx", component_param->parameter) == 0 || strcasecmp("zrx", component_param->parameter) == 0) { *component_param->xparam = &(gauss->qx.im); strcpy(component_param->unit, " [m]"); *component_param->lborder = 1; *component_param->min = 0.0; *component_param->uborder = 0; } else if (strcasecmp("Zry", component_param->parameter) == 0 || strcasecmp("zry", component_param->parameter) == 0) { *component_param->xparam = &(gauss->qy.im); strcpy(component_param->unit, " [m]"); *component_param->lborder = 1; *component_param->min = 0.0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\nparameter '%s' not tunable at gauss command (only zx, zy, zrx, zry)\n", component_param->command_string, component_param->parameter); return (-1); } // switching automatic retrace for this inter.rebuild |= 2; return (0); } void assign_homodyne_detector_params( homodyne_t *hom, component_param_t *component_param) { if (strcasecmp("phase", component_param->parameter) == 0) { *component_param->xparam = &(hom->phase); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\nparameter '%s' not tunable at homodyne (only phase)\n", component_param->command_string, component_param->parameter); return; } } void assign_qd_detector_params( light_out_t *detector, component_param_t *component_param) { if (strcasecmp("homangle", component_param->parameter) == 0 || strcasecmp("hom", component_param->parameter) == 0) { *component_param->xparam = &(detector->homodyne_angle); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\nparameter '%s' not tunable at qd (only homangle)\n", component_param->command_string, component_param->parameter); return; } } //! Assign the parameters for the beam detector /*! * \param detector reference to detector object * \param component_param reference to component_param object */ void assign_beam_detector_params( light_out_t *detector, component_param_t *component_param) { if (strcasecmp("x", component_param->parameter) == 0 || strcasecmp("X", component_param->parameter) == 0) { *component_param->xparam = &(detector->x); strcpy(component_param->unit, " [x/wx0]"); *component_param->lborder = 0; *component_param->uborder = 0; } if (strcasecmp("y", component_param->parameter) == 0 || strcasecmp("Y", component_param->parameter) == 0) { *component_param->xparam = &(detector->y); strcpy(component_param->unit, " [y/wy0]"); *component_param->lborder = 0; *component_param->uborder = 0; } } //! Assign the parameters for the amplitude detector /*! * \param detector reference to detector object * \param component_param reference to component_param object */ int assign_amplitude_detector_params( light_out_t *detector, component_param_t *component_param) { if (strcasecmp("f", component_param->parameter) == 0) { *component_param->xparam = &(detector->f[1]); strcpy(component_param->unit, " [Hz]"); *component_param->lborder = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\n no parameter %s at detector \n", component_param->command_string, component_param->parameter); return (-1); } return 0; } //! Assign the detector parameters for one demodulation /*! * \param detector reference to detector object * \param component_param reference to component_param object */ int assign_one_demod_detector_params( light_out_t *detector, component_param_t *component_param) { if (strcasecmp("f", component_param->parameter) == 0 || strcasecmp("f1", component_param->parameter) == 0) { *component_param->xparam = &(detector->f[1]); strcpy(component_param->unit, " [Hz]"); *component_param->lborder = 0; *component_param->uborder = 0; } else if (strcasecmp("phi", component_param->parameter) == 0 || strcasecmp("phase1", component_param->parameter) == 0 || strcasecmp("phase", component_param->parameter) == 0 || strcasecmp("phi1", component_param->parameter) == 0) { if (detector->demod_phase_mode[1] == USER_PHASE) { *component_param->xparam = &(detector->phi[1]); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\n cannot tune phase at detector \n", component_param->command_string); return (-1); } } else { server_gerror("Line `%s':\n no parameter %s at detector \n", component_param->command_string, component_param->parameter); return (-1); } return 0; } //! Assign the detector parameters for multiple demodulations /*! * \param detector reference to detector object * \param component_param reference to component_param object */ int assign_multi_demod_detector_params( light_out_t *detector, component_param_t *component_param) { int l; if (component_param->parameter[0] == 'f') { l = component_param->parameter[1]; if (l != '\0') { l -= 48; if ((l > 0) && (l <= MAX_DEMOD)) { *component_param->xparam = &(detector->f[l]); strcpy(component_param->unit, " [Hz]"); *component_param->lborder = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\n" " no parameter %s at detector \n", component_param->command_string, component_param->parameter); return (-1); } } else { server_gerror("Line `%s':\n" " no parameter %s at detector \n", component_param->command_string, component_param->parameter); return (-1); } } else if (strncasecmp("phase", component_param->parameter, 5) == 0 || strncasecmp("phi", component_param->parameter, 3) == 0) { if (strncasecmp("phase", component_param->parameter, 5) == 0) { l = component_param->parameter[5]; } else { l = component_param->parameter[3]; } if (l != '\0') { l -= 48; if ((l > 0) && (l <= MAX_DEMOD)) { if (detector->demod_phase_mode[1] == USER_PHASE) { *component_param->xparam = &(detector->phi[l]); strcpy(component_param->unit, " [deg]"); *component_param->lborder = 0; *component_param->uborder = 0; } else { server_gerror("Line `%s':\n cannot tune phase at detector \n", component_param->command_string); return (-1); } } else { server_gerror("Line `%s':\n" " no parameter %s at detector \n", component_param->command_string, component_param->parameter); return (-1); } } else { server_gerror("Line `%s':\n no parameter %s at detector \n", component_param->command_string, component_param->parameter); return (-1); } } else { server_gerror("Line `%s':\n no parameter %s at detector \n", component_param->command_string, component_param->parameter); return (-1); } return 0; } //! Check the axis parameters /*! * \param lborder the lower border * \param uborder the upper border * \param min the minimum value * \param max the maximum value * \param x1 ??? * \param x2 ??? * \param type the type of parameter (FLOG or FLIN) * \param command_string the input command string * \param axis_or_param is this an axis or a parameter? * * \todo refactor routine for readability */ void check_xparam(int lborder, int uborder, double min, double max, double x1, double x2, int type, const char *command_string, int axis_or_param) { // type should be either FLOG or FLIN assert(type == FLOG || type == FLIN); if ((lborder && x1 < min) || (uborder && x2 > max)) { gerror("Line `%s':\nparameter will be out of range\n", command_string); } if (type == FLOG && axis_or_param == 0) { if (x1 < 0 || x2 < 0) { gerror("Line `%s':\nnegative values illegal with log scale'\n", command_string); } if (x1 == 0.0) { gerror("Line `%s':\nmin=0 illegal with log scale'\n", command_string); } } } //! Read the y-axis command /*! * \param command_string the input command string * * \todo db:deg, re, im branches untested */ void read_yaxis(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char linlog[MAX_TOKEN_LEN] = {0}; char y_axis_type[LINE_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; endcomp = 1; lastparam = -1; if (inter.yaxis[0]) { gerror("Line `%s':\nyaxis already defined'\n", command_string); } int num_vars_read = sscanf(command_string, "%s %s %s %80s", command_name, linlog, y_axis_type, rest_string); int num_vars_expected = 3; if (num_vars_read < num_vars_expected) { int num_vars_read = sscanf(command_string, "%s %s %80s", command_name, y_axis_type, rest_string); int num_vars_expected = 2; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\n" "expected 'yaxis [lin/log] abs:deg/db:deg/re:im/abs/db/deg'\n", command_string); } } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (strcasecmp(y_axis_type, "abs:deg") == 0) { inter.yaxis[0] = OTYPE_ABS; inter.yaxis[1] = OTYPE_DEG; inter.ploty2axis = true; strcpy(inter.y1name, "Abs "); strcpy(inter.y2name, "Phase [Deg] "); } else if (strcasecmp("db:deg", y_axis_type) == 0) { inter.yaxis[0] = OTYPE_DB; inter.yaxis[1] = OTYPE_DEG; inter.ploty2axis = true; strcpy(inter.y1name, "dB "); strcpy(inter.y2name, "Phase [Deg] "); } else if (strcasecmp("re:im", y_axis_type) == 0) { inter.yaxis[0] = OTYPE_RE; inter.yaxis[1] = OTYPE_IM; inter.ploty2axis = true; strcpy(inter.y1name, "Re "); strcpy(inter.y2name, "Im "); } else if (strcasecmp("abs", y_axis_type) == 0) { inter.yaxis[0] = OTYPE_ABS; strcpy(inter.y1name, "Abs "); } else if (strcasecmp("re", y_axis_type) == 0) { inter.yaxis[0] = OTYPE_RE; strcpy(inter.y1name, "Re "); } else if (strcasecmp("im", y_axis_type) == 0) { inter.yaxis[0] = OTYPE_IM; strcpy(inter.y1name, "Im "); } else if (strcasecmp("db", y_axis_type) == 0) { inter.yaxis[0] = OTYPE_DB; strcpy(inter.y1name, "dB "); } else if (strcasecmp("deg", y_axis_type) == 0) { inter.yaxis[0] = OTYPE_DEG; strcpy(inter.y1name, "Phase [deg]"); } else { gerror("Line `%s':\n" "expected 'yaxis [lin/log] abs:deg/db:deg/re:im/abs/db/deg'\n", command_string); } if (num_vars_read == num_vars_expected) { if (strncasecmp(linlog, "lin", 3) == 0) { inter.ytype = FLIN; } else if (strncasecmp(linlog, "log", 3) == 0) { if (inter.yaxis[0] == OTYPE_DB) { warn("yaxis : don't need 'log' with dB - using 'lin' instead.\n"); inter.ytype = FLIN; } else if (inter.yaxis[0] == OTYPE_DEG) { warn("yxasis : 'log' makes no sense with 'deg' - " "using 'lin' instead.\n"); inter.ytype = FLIN; } else { inter.ytype = FLOG; } } else { gerror("Line `%s':\n" "expected 'yaxis [lin/log] abs:deg/db:deg/re:im/abs/db/deg'\n", command_string); } } } //! Read the photodetector type /*! * \param command_string the input command string */ void read_pdtype(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char pdtype_name[LINE_LEN] = {0}; char detector_string[LINE_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %s %80s %80s", command_name, detector_string, pdtype_name, rest_string); int num_vars_expected = 3; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'pdtype detector type-name '\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } bool pdtype_is_found = false; //! \todo pdtype_index is used in two places -- fix!!! int pdtype_index; for (pdtype_index = 0; pdtype_index < init.num_pdtypes; pdtype_index++) { if (strcasecmp(pdtype_name, init.pdt[pdtype_index].name) == 0) { pdtype_is_found = true; break; } } if (NOT pdtype_is_found) { gerror("Line `%s':\ndetector type '%s' not found in kat.ini\n", command_string, pdtype_name); return; } int component_index = get_component_index_from_name(detector_string); if (component_index == NOT_FOUND) { gerror("Line `%s':\nno such detector\n", command_string); } int component_type = get_component_type_decriment_index(&component_index); if (component_type != OUT) { gerror("Line `%s':\ncomponent not a detector\n", command_string); } output_data_t *output_data; output_data = &inter.output_data_list[component_index]; if (output_data->detector_type != PD1 && output_data->detector_type != PD0) { warn("Line `%s':\n" "setting a type for this kind of detector makes no sense\n", command_string); } inter.light_out_list[output_data->detector_index].detector_type = pdtype_index; } //! Read the gnuplot terminal command /*! * \param command_string the input command string * * \todo refactor routine for readability */ void read_gnuterm(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char terminal_name[MAX_TOKEN_LEN] = {0}; char fname[LINE_LEN] = {0}; int num_vars_read, i, number, found; char rest_string[REST_STRING_LEN] = {0}; gnuplot_terminal_t *gnuplot_terminal; if (inter.num_gnuterm_cmds == NO_GNUTERM) { warn("Line `%s' : Gnuplot terminal definition ignored'\n", command_string); } else { num_vars_read = sscanf(command_string, "%s %s %80s %80s", command_name, terminal_name, fname, rest_string); if (num_vars_read < 2) { gerror("Line `%s':\nexpected 'gnuterm terminal [filename]'\n", command_string); } found = 0; if (strcasecmp(terminal_name, "NO") == 0) { inter.num_gnuterm_cmds = NO_GNUTERM; } else { //! \todo i is used in two places for different meanings -- fix!! for (i = 0; i < init.num_gnuplot_terminals; i++) { if (strcasecmp(terminal_name, init.gnuterm[i].name) == 0) { found = 1; break; } } if (found == 0) { warn("Line `%s':\n" "GNUPLOT Terminal '%s' not found in kat.ini\n", command_string, terminal_name); return; } gnuplot_terminal = &(init.gnuterm[i]); if (NOT gnuplot_terminal->output_is_file && num_vars_read > 2) { warn("Line `%s':\ntext '%s' ignored\n", command_string, fname); } if (num_vars_read > 3) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } assert(inter.num_gnuterm_cmds < mem.num_gnuterm_cmds); // if termianl has file output add at the end // if not -> shift everything up and add at the start // needed for proper plotting with Gnuplot (I believe). if (gnuplot_terminal->output_is_file) { number = inter.num_gnuterm_cmds; } else { number = 0; int j; for (j = inter.num_gnuterm_cmds; j > 0; j--) { inter.gnuterm[j] = inter.gnuterm[j - 1]; if (init.gnuterm[inter.gnuterm[j - 1]].output_is_file) { inter.gnutermfn[j] = duplicate_string(inter.gnutermfn[j - 1]); } } } inter.gnuterm[number] = i; if (gnuplot_terminal->output_is_file) { if (num_vars_read == 3) { inter.gnutermfn[number] = duplicate_string(fname); } else { inter.gnutermfn[number] = duplicate_to_longer_string(inter.basename, strlen(gnuplot_terminal->suffix) + 1); strcat(inter.gnutermfn[number], "."); strcat(inter.gnutermfn[number], gnuplot_terminal->suffix); } } ++inter.num_gnuterm_cmds; } } } //! Read the python terminal command /*! * \param command_string the input command string * */ void read_pyterm(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char terminal_name[MAX_TOKEN_LEN] = {0}; char fname[LINE_LEN] = {0}; int num_vars_read, number, found; char rest_string[REST_STRING_LEN] = {0}; python_terminal_t *python_terminal; if (inter.num_pyterm_cmds == NO_PYTERM) { warn("Line `%s' : Python terminal definition ignored'\n", command_string); } else { num_vars_read = sscanf(command_string, "%s %s %80s %80s", command_name, terminal_name, fname, rest_string); if (num_vars_read < 2) { gerror("Line `%s':\nexpected 'python terminal [filename]'\n", command_string); } found = 0; int idx=-1; if (strcasecmp(terminal_name, "NO") == 0) { inter.num_pyterm_cmds = NO_PYTERM; } else { for (idx = 0; idx < init.num_python_terminals; idx++) { if (strcasecmp(terminal_name, init.pyterm[idx].name) == 0) { found = 1; break; } } if (found == 0) { warn("Line `%s':\n" "Python terminal '%s' not found in kat.ini\n", command_string, terminal_name); return; } python_terminal = &(init.pyterm[idx]); if (NOT python_terminal->output_is_file && num_vars_read > 2) { warn("Line `%s':\ntext '%s' ignored\n", command_string, fname); } if (num_vars_read > 3) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } assert(inter.num_pyterm_cmds < mem.num_pyterm_cmds); if (python_terminal->output_is_file) { number = inter.num_pyterm_cmds; } else { number = 0; int j; for (j = inter.num_pyterm_cmds; j > 0; j--) { inter.pyterm[j] = inter.pyterm[j - 1]; if (init.pyterm[inter.pyterm[j - 1]].output_is_file) { inter.pytermfn[j] = duplicate_string(inter.pytermfn[j - 1]); } } } inter.pyterm[number] = idx; if (python_terminal->output_is_file) { if (num_vars_read == 3) { inter.pytermfn[number] = duplicate_string(fname); } else { inter.pytermfn[number] = duplicate_to_longer_string(inter.basename, strlen(python_terminal->suffix) + 1); strcat(inter.pytermfn[number], "."); strcat(inter.pytermfn[number], python_terminal->suffix); } } ++inter.num_pyterm_cmds; } } } //! Read the colour /*! * \param command_string the input command string * * \todo refactor routine for readability */ void read_color(const char *command_string) { char sval1[LINE_LEN] = {0}; double val1 = 0.0; int num_vars_read; char rest_string[REST_STRING_LEN] = {0}; lastparam = -1; if ((num_vars_read = sscanf(command_string + 5, "%s %80s", sval1, rest_string)) < 1 || atod(sval1, &val1)) { gerror("Line `%s':\nexpected 'color number'\n", command_string); } else if (num_vars_read > 1) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (val1 > 2 || val1 < 0) { gerror("Line `%s':\n available color numbers: 0, 1, 2'\n", command_string); } inter.mycolor = val1; } //! Read the width (of output plot lines ???) /*! * \param command_string the input command string * * \todo refactor routine for readability */ void read_width(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char width_string[LINE_LEN] = {0}; double width; char rest_string[REST_STRING_LEN] = {0}; lastparam = -1; int num_vars_read = sscanf(command_string, "%s %s %80s", command_name, width_string, rest_string); int num_vars_expected = 1; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'width number'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (atod(width_string, &width)) { gerror("Line `%s':\nUnable to read width value\n", command_string); } if (width >= 8 || width <= 0) { gerror("Line `%s':\n width must be >0 and <8 '\n", command_string); } inter.width = width; } //! Read the deriv_h, to overwrite value given in kat.ini /*! * \param command_string the input command string * * \todo refactor routine for readability */ void read_deriv_h(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char deriv_string[LINE_LEN] = {0}; double deriv_h; char rest_string[REST_STRING_LEN] = {0}; lastparam = -1; int num_vars_read = sscanf(command_string, "%s %s %80s", command_name, deriv_string, rest_string); int num_vars_expected = 2; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'width number'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (atod(deriv_string, &deriv_h)) { gerror("Line `%s':\nUnable to read deriv_h value\n", command_string); } init.deriv_h = deriv_h; } //! Read the scale command /*! * \param command_string the input command string * * \todo refactor routine for readability * * \todo ampere, qshot:meter, qshot branches untested */ void read_scale(const char *command_string) { char sval1[LINE_LEN] = {0}; char sval2[LINE_LEN] = {0}; double val1; int i, j, num_vars_read; char rest_string[REST_STRING_LEN] = {0}; endcomp = 1; lastparam = -1; if (inter.num_scale_cmds >= mem.num_scale_cmds) { gerror("Line `%s':\ntoo many scale factors\n", command_string); } if ((num_vars_read = sscanf(command_string + 5, "%s %s %80s", sval1, sval2, rest_string)) < 2 || (strncasecmp(sval1, "meter", 5) && (strncasecmp(sval1, "ampere", 6) && strncasecmp(sval1, "deg", 3) && strncasecmp(sval1, "rad", 3) && strncasecmp(sval1, "1/deg", 5) && strncasecmp(sval1, "1/rad", 5) && strncasecmp(sval1, "ASD", 3) && strncasecmp(sval1, "PSD", 3) && strncasecmp(sval1, "PSD_HF", 6) && strncasecmp(sval1, "ASD_HF", 6) && strncasecmp(sval1, "qshot", 5) && strncasecmp(sval1, "qshot:meter", 11) && atod(sval1, &val1)))) { if ((num_vars_read = sscanf(command_string + 5, "%s %80s", sval1, rest_string)) < 1 || (strncasecmp(sval1, "meter", 5) && (strncasecmp(sval1, "ampere", 6) && strncasecmp(sval1, "deg", 3) && strncasecmp(sval1, "rad", 3) && strncasecmp(sval1, "1/deg", 5) && strncasecmp(sval1, "1/rad", 5) && strncasecmp(sval1, "ASD", 3) && strncasecmp(sval1, "PSD", 3) && strncasecmp(sval1, "PSD_HF", 6) && strncasecmp(sval1, "ASD_HF", 6) && strncasecmp(sval1, "qshot", 5) && strncasecmp(sval1, "qshot:meter", 11) && atod(sval1, &val1)))) { gerror("Line `%s':\nexpected 'scale factor [output]'\n", command_string); } else { if (num_vars_read > 1) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } inter.scale_list[inter.num_scale_cmds].output = -1; warn("Global scaling factor applied to ALL outputs\n"); } } else { if (num_vars_read > 2) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } i = get_component_index_from_name(sval2); if (i == NOT_FOUND) { gerror("Line `%s':\noutput name '%s' not found.\n", command_string, sval2); } j = get_component_type_decriment_index(&i); if (j != OUT) { gerror("Line `%s':\n'%s' is not an output\n", command_string, sval2); } inter.scale_list[inter.num_scale_cmds].output = i; } if (strncasecmp(sval1, "meter", 5) == 0) { inter.scale_list[inter.num_scale_cmds].type = SCALE_METER; val1 = 0; } else if (strncasecmp(sval1, "deg", 3) == 0) { inter.scale_list[inter.num_scale_cmds].type = SCALE_RAD2DEG; val1 = 0; } else if (strncasecmp(sval1, "rad", 3) == 0) { inter.scale_list[inter.num_scale_cmds].type = SCALE_DEG2RAD; val1 = 0; } else if (strncasecmp(sval1, "1/deg", 3) == 0) { inter.scale_list[inter.num_scale_cmds].type = SCALE_DEG2RAD; val1 = 0; } else if (strncasecmp(sval1, "1/rad", 3) == 0) { inter.scale_list[inter.num_scale_cmds].type = SCALE_RAD2DEG; val1 = 0; } else if (strncasecmp(sval1, "ampere", 6) == 0) { inter.scale_list[inter.num_scale_cmds].type = SCALE_AMPERE; val1 = 0; } else if (strncasecmp(sval1, "qshot:meter", 11) == 0) { inter.scale_list[inter.num_scale_cmds].type = SCALE_QSHOT_METER; val1 = 0; } else if (strncasecmp(sval1, "qshot", 5) == 0) { inter.scale_list[inter.num_scale_cmds].type = SCALE_QSHOT; val1 = 0; } else if (strncasecmp(sval1, "PSD", 6) == 0) { inter.scale_list[inter.num_scale_cmds].type = SCALE_PSD; val1 = 0; } else if (strncasecmp(sval1, "PSD_HF", 7) == 0) { inter.scale_list[inter.num_scale_cmds].type = SCALE_PSD_HF; val1 = 0; } else if (strncasecmp(sval1, "ASD", 8) == 0) { inter.scale_list[inter.num_scale_cmds].type = SCALE_ASD; val1 = 0; } else if (strncasecmp(sval1, "ASD_HF", 9) == 0) { inter.scale_list[inter.num_scale_cmds].type = SCALE_ASD_HF; val1 = 0; } else { inter.scale_list[inter.num_scale_cmds].type = SCALE_USER; if (val1 == 0) { gerror("Line `%s':\nscale factor zero makes no sense\n", command_string); } } inter.scale_list[inter.num_scale_cmds].factor = val1; inter.num_scale_cmds++; } //! Read the powers command /*! * \param command_string the input command string */ void read_powers(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; int power_level; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %d %80s", command_name, &power_level, rest_string); int num_vars_expected = 2; if (num_vars_read > num_vars_expected) { warn("Line `%s': text '%s' ignored\n", command_string, rest_string); } else { if (num_vars_read >= num_vars_expected) { inter.powers = inter.powers | power_level; } else { inter.powers = inter.powers | 1; } } } //! Read the trace command /*! * \param command_string the input command string */ void read_trace(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; int trace_level; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %d %80s", command_name, &trace_level, rest_string); int num_vars_expected = 2; if (num_vars_read > num_vars_expected) { warn("Line `%s': text '%s' ignored\n", command_string, rest_string); } else { if (num_vars_read >= num_vars_expected) { inter.trace = inter.trace | trace_level; } else { inter.trace = inter.trace | 1; } } } //! Read the grating information in a verbose manner ??? /*! * \param command_string the input command string * * \todo refactor routine for readability * * \todo untested */ void read_verbose_grating(const char *command_string) { int val1; int num_vars_read; char rest_string[REST_STRING_LEN] = {0}; debug_msg("read_verbose_grating()\n"); if ((num_vars_read = sscanf(command_string + 7, "%d %80s", &val1, rest_string)) > 1) { warn("Line `%s': text '%s' ignored\n", command_string, rest_string); } else { if (num_vars_read >= 1) { inter.grating = inter.grating | val1; } else { inter.grating = inter.grating | 1; } } } //! Read the maximum TEM order /*! * \param command_string the input command string */ void read_maxtem(const char *command_string) { char command_name[MAX_TOKEN_LEN] = {0}; char maxtem_value_string[LINE_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %s %80s", command_name, maxtem_value_string, rest_string); int num_vars_expected = 2; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'maxtem order'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s': text '%s' ignored\n", command_string, rest_string); } if (inter.tem_is_set) { warn("Line `%s': order was already set and is overwritten\n", command_string); } if (strncasecmp(maxtem_value_string, "off", 3) == 0) { inter.trace = 0; inter.tem_is_set = false; inter.tem = NOT_SET; } else { int maxtem_value; if (my_atoi(maxtem_value_string, &maxtem_value)) { gerror("Line `%s':\nUnable to read maxtem value\n", command_string); } if (maxtem_value < 0) { gerror("Line `%s':\norder must be positive\n", command_string); } inter.tem = maxtem_value; inter.tem_is_set = true; mem.hg_mode_order = inter.tem; } } //! Read the retrace command /*! * \param command_string the input command string * * \todo refactor routine for readability * \todo inter.retrace looks boolean; check and if so, change to bool */ void read_retrace(const char *command_string) { char retrace_arg_string[LINE_LEN] = {0}; char rest[REST_STRING_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %s %80s", command_name, retrace_arg_string, rest); int num_vars_expected = 2; if (num_vars_read == num_vars_expected && (strncasecmp(retrace_arg_string, "off", 3) != 0 && strncasecmp(retrace_arg_string, "force", 5) != 0)) { gerror("Line `%s':\nexpected 'retrace [off]'\n", command_string); } if (num_vars_read > num_vars_expected) { warn("Line `%s': text '%s' ignored\n", command_string, rest); } if (strncasecmp(retrace_arg_string, "off", 3) == 0) { inter.retrace = 0; } else if (strncasecmp(retrace_arg_string, "force", 5) == 0) { // user can force retrace to continue regardless of no stable gauss param being found // User should understand what they are doing though! inter.retrace = 2; } else { inter.retrace = 1; } inter.retrace_manual = 1; } //! Read the knm command /*! * \param command_string the input command string * */ void read_knm(const char *command_string) { char command_name[LINE_LEN] = {0}; char component_name[LINE_LEN] = {0}; char filename[LINE_LEN] = {0}; char flags[LINE_LEN] = {0}; int val1; int num_vars_read; char rest_string[REST_STRING_LEN] = {0}; num_vars_read = sscanf(command_string, "%s %s %s %s %80s", command_name, component_name, filename, flags, rest_string); if (num_vars_read >= 3) { if (num_vars_read >= 5) warn("Line `%s': text '%s' ignored\n", command_string, rest_string); int component_index = get_component_index_from_name(component_name); if (component_index == NOT_FOUND) { gerror("Line `%s':\nno such component '%s'\n", command_string, component_name); } int component_type = get_component_type_decriment_index(&component_index); unsigned int *knm_flag = NULL; bool *savefile = NULL; char *fname = NULL; switch(component_type){ case MIRROR: knm_flag = &inter.mirror_list[component_index].knm_flags; savefile = &inter.mirror_list[component_index].map_merged.save_to_file; fname = inter.mirror_list[component_index].map_merged.filename; break; case BEAMSPLITTER: knm_flag = &inter.bs_list[component_index].knm_flags; savefile = &inter.bs_list[component_index].map_merged.save_to_file; fname = inter.bs_list[component_index].map_merged.filename; break; case DIODE: knm_flag = &inter.diode_list[component_index].knm_flags; break; case MODULATOR: knm_flag = &inter.modulator_list[component_index].knm_flags; break; case LENS: knm_flag = &inter.lens_list[component_index].knm_flags; break; case SPACE: knm_flag = &inter.space_list[component_index].knm_flags; break; default: gerror("Line `%s':\nknm not supported for this component '%s'\n", command_string, component_name); } if(fname != NULL) strcpy(fname, filename); else warn("Ignored filename as this component does not support knm file saving.\n"); if(savefile != NULL) *savefile = true; if(num_vars_read >= 4 && !my_atoi(flags,&val1) && knm_flag != NULL){ if (*knm_flag != 0) warn("Line `%s': knm was already set and is overwritten\n", command_string); *knm_flag = val1; } } else { gerror("Line `%s':\nexpected 'knm component_name flag' or 'knm component_name prefix_filename'\n", command_string); } } //! Read the debug command /*! * \param command_string the input command string * * \todo refactor routine for readability */ void read_debug(const char *command_string) { int val1; int num_vars_read; char rest_string[REST_STRING_LEN] = {0}; if ((num_vars_read = sscanf(command_string + 5, "%d %80s", &val1, rest_string)) > 1) { warn("Line `%s': text '%s' ignored\n", command_string, rest_string); } else { if (num_vars_read >= 1) { inter.debug = inter.debug | val1; } else { inter.debug = inter.debug | 1; } } } void read_minimize(const char *command_string) { const char *usage = "maximize/minimize name output parameter target parameter lower upper abserr"; char command_name[LINE_LEN] = {0}; char name[LINE_LEN] = {0}; char output_name[LINE_LEN] = {0}; char output_param[LINE_LEN] = {0}; char target_name[LINE_LEN] = {0}; char target_param[LINE_LEN] = {0}; char lower[LINE_LEN] = {0}; char upper[LINE_LEN] = {0}; char abserr[LINE_LEN] = {0}; char rest_string[LINE_LEN] = {0}; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %s %s %s %[^\n]", command_name, name, output_name, output_param, target_name, target_param, lower, upper, abserr, rest_string); if (num_vars_read != 9) { gerror("Line `%s':\nexpected '%s'\n", command_string, usage); } if(strcmp(command_name, "maximize") == 0) { inter.minimizer->find_max = true; } else { inter.minimizer->find_max = false; } int detector_index = get_component_index_from_name(output_name); inter.minimizer->target_type = get_component_type_decriment_index(&detector_index); inter.minimizer->target_index = detector_index; if (detector_index == NOT_FOUND) { gerror("Line `%s':\nCouldn't find detector called '%s'.\n", command_string, target_name); } else { inter.minimizer->target_output = &inter.output_data_list[detector_index]; } if (strcasecmp("re", output_param) == 0) { strcpy(inter.minimizer->target_parameter, "re"); } else if (strcasecmp("im", output_param) == 0) { strcpy(inter.minimizer->target_parameter, "im"); } else if (strcasecmp("abs", output_param) == 0) { strcpy(inter.minimizer->target_parameter, "abs"); } else if (strcasecmp("deg", output_param) == 0) { strcpy(inter.minimizer->target_parameter, "deg"); } else { gerror("Line `%s':\nOutput parameter should be either re/im/abs/deg\n", command_string); } double min, max; int lborder, uborder; char unit[LINE_LEN] = {0}; int component_index = get_component_index_from_name(target_name); if (component_index == NOT_FOUND) { int detector_index = get_detector_or_node_index_from_name(target_name); if (detector_index == NOT_FOUND) { gerror("Line `%s':\nCouldn't find component or detector called '%s'.\n", command_string, target_name); } else { component_index = detector_index; } } int error_code = get_xparam(&inter.minimizer->variable, component_index, target_param, unit, command_string, &lborder, &uborder, &min, &max); if (error_code) { my_finish(1); } if(atod(lower, &inter.minimizer->A)){ gerror("Line `%s':\nMinimize lower bound (%s) not a valid floating point number\n", command_string, lower); } if(atod(upper, &inter.minimizer->B)){ gerror("Line `%s':\nMinimize upper bound not a valid floating point number\n", command_string); } if(atod(abserr, &inter.minimizer->abserr)){ gerror("Line `%s':\nMinimize error not a valid floating point number\n", command_string); } output_data_t *result = &inter.output_data_list[inter.num_outputs]; strcpy(result->name, name); strcpy(inter.minimizer->name, name); result->output_type = REAL; result->beam_param_not_set = true; result->detector_type = MINIMIZER; result->qx = NULL; result->qy = NULL; result->noplot = false; result->detector_index = 0; inter.minimizer->result_output = result; inter.num_outputs++; } //! Read the phase command /*! * \param command_string the input command string * * \todo refactor routine for readability */ void read_phase(const char *command_string) { int gouy_phase_level; int num_vars_read; char command_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; if ((num_vars_read = sscanf(command_string, "%s %d %80s", command_name, &gouy_phase_level, rest_string)) > 2) { warn("Line `%s': text '%s' ignored\n", command_string, rest_string); } else { if (num_vars_read >= 2) { if (gouy_phase_level < 0 || gouy_phase_level > 7) { gerror("Line `%s':\ninteger must be between 0 and 7\n", command_string); } else { inter.set_tem_phase_zero = gouy_phase_level; } } else { inter.set_tem_phase_zero = 0; } } } //! Read the diode command and information /*! * \param command_string the input command string */ void read_diode(const char *command_string) { char vars[6][MAX_TOKEN_LEN] = {{0}}; char* suppression_string = NULL; char* object_name = NULL; char* loss_string = NULL; char command_name[MAX_TOKEN_LEN] = {0}; char* node1_name = NULL; char* node2_name = NULL; char* node3_name = NULL; char rest_string[REST_STRING_LEN] = {0}; debug_msg("read_diode()\n"); diode_t *diode; diode = &(inter.diode_list[inter.num_diodes]); int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %s %[^\n]", command_name, vars[0], vars[1], vars[2], vars[3], vars[4], vars[5], rest_string); int num_vars_max = 7; double suppression; double loss; if(num_vars_read == num_vars_max){ object_name = vars[0]; suppression_string = vars[1]; loss_string = vars[2]; node1_name = vars[3]; node2_name = vars[4]; node3_name = vars[5]; gerror("Line `%s':\n3 node isolator has been depreciated. Use `dbs` component instead.'\n", command_string); } else if(num_vars_read == 6){ object_name = vars[0]; suppression_string = vars[1]; // check if loss_string is a number... if(atod((char *)vars[2], &loss)) { node1_name = vars[2]; node2_name = vars[3]; node3_name = vars[4]; } else { loss_string = vars[2]; node1_name = vars[3]; node2_name = vars[4]; } } else if(num_vars_read == 5){ object_name = vars[0]; suppression_string = vars[1]; loss_string = NULL; node1_name = vars[2]; node2_name = vars[3]; // node 3 is not actually read but set it to dump node3_name = vars[4]; strcpy(node3_name, "dump"); } else gerror("Line `%s':\nexpected 'isol name S [Loss] node1 node2 [node3]'\n", command_string); if (num_vars_read > num_vars_max) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_diodes >= mem.num_diodes) { gerror("Line `%s':\ntoo many dbs\n", command_string); } check_name(command_string, object_name); strcpy(diode->name, object_name); if (atod(suppression_string, &suppression)) gerror("Line `%s':\nUnable to read suppression value\n", command_string); if (suppression >= 0.0) { diode->S = suppression; } else { gerror("Line `%s':\nsuppression must not be negative\n", command_string); } if(loss_string != NULL){ if (atod(loss_string, &loss)) gerror("Line `%s':\nUnable to read loss value\n", command_string); if (loss >= 0.0 && loss <= 1) { diode->loss = loss; } else { gerror("Line `%s':\nLoss must be between 0 and 1\n", command_string); } } else diode->loss = 0.0; // grab node indices diode->node1_index = update_node_index_for(node1_name, IN_OUT); diode->node2_index = update_node_index_for(node2_name, OUT_IN); if(node3_name != NULL && strlen(node3_name) != 0) diode->node3_index = update_node_index_for(node3_name, IN_OUT); else diode->node3_index = update_node_index_for("dump", IN_OUT); connect_component_to_node(diode->node1_index, (void*)diode, DIODE); connect_component_to_node(diode->node2_index, (void*)diode, DIODE); connect_component_to_node(diode->node3_index, (void*)diode, DIODE); // calculate the reduced node indices from the node indices diode->node1_reduced_index = get_reduced_index_for(diode->node1_index); diode->node2_reduced_index = get_reduced_index_for(diode->node2_index); if(command_name[strlen(command_name)-1] == '*'){ diode->option = 1; } else { diode->option = 0; } ++inter.num_diodes; ++inter.num_components; check_diode(diode); } void read_dbs(const char *command_string) { char suppression_string[MAX_TOKEN_LEN] = {0}; char object_name[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char node1_name[MAX_TOKEN_LEN] = {0}; char node2_name[MAX_TOKEN_LEN] = {0}; char node3_name[MAX_TOKEN_LEN] = {0}; char node4_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; debug_msg("read_dbs\n"); dbs_t *dbs; dbs = &(inter.dbs_list[inter.num_dbss]); // TODO - Add suppression later suppression_string[0] = '0'; int num_vars_read = sscanf(command_string, "%s %s %s %s %s %s %[^\n]", command_name, object_name, node1_name, node3_name, node2_name, node4_name, rest_string); // NOTE: that node 3 and 2 are swapped. Originally wrote matrix filling // to couple nodes differently as an isolator component. Now it is a // directional BS so the node pattern matches that . int num_vars_max = 6; double suppression; if(num_vars_read < num_vars_max){ gerror("Line `%s':\nexpected 'dbs name node1 node2 node3 node4'\n", command_string); } if (num_vars_read > num_vars_max) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_dbss >= mem.num_dbss) { gerror("Line `%s':\ntoo many dbs \n", command_string); } check_name(command_string, object_name); strcpy(dbs->name, object_name); if (atod(suppression_string, &suppression)) gerror("Line `%s':\nUnable to read suppression value\n", command_string); if (suppression >= 0.0) { dbs->S = suppression; } else { gerror("Line `%s':\nsuppression must not be negative\n", command_string); } // grab node indices dbs->node1_index = update_node_index_for(node1_name, IN_OUT); dbs->node2_index = update_node_index_for(node2_name, IN_OUT); dbs->node3_index = update_node_index_for(node3_name, IN_OUT); dbs->node4_index = update_node_index_for(node4_name, IN_OUT); connect_component_to_node(dbs->node1_index, (void*)dbs, DBS); connect_component_to_node(dbs->node2_index, (void*)dbs, DBS); connect_component_to_node(dbs->node3_index, (void*)dbs, DBS); connect_component_to_node(dbs->node4_index, (void*)dbs, DBS); // calculate the reduced node indices from the node indices dbs->node1_reduced_index = get_reduced_index_for(dbs->node1_index); dbs->node2_reduced_index = get_reduced_index_for(dbs->node2_index); ++inter.num_dbss; ++inter.num_components; check_dbs(dbs); } //! Read the 'variable' command and information /*! * \param command_string the input command string */ void read_variable(const char *command_string) { char object_name[MAX_TOKEN_LEN] = {0}; char value_string[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; debug_msg("read_variable()\n"); variable_t *variable; variable = &(inter.variable_list[inter.num_variables]); int num_vars_read = sscanf(command_string, "%s %s %s %80s", command_name, object_name, value_string, rest_string); int num_vars_expected = 3; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'variable name value'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } if (inter.num_variables >= mem.num_variables) { gerror("Line `%s':\ntoo many variables\n", command_string); } check_name(command_string, object_name); strcpy(variable->name, object_name); double parameter_value; if (atod(value_string, ¶meter_value)) { gerror("Line `%s':\nUnable to read suppression value\n", command_string); } ++inter.num_variables; } /** * Alters the integration method for this individual script file * * @param command_string input string from script file */ void read_intmethod(const char *command_string) { char intmethod_string[MAX_TOKEN_LEN] = {0}; char command_name[MAX_TOKEN_LEN] = {0}; char rest_string[REST_STRING_LEN] = {0}; debug_msg("read_intmethod()\n"); int num_vars_read = sscanf(command_string, "%s %s %80s", command_name, intmethod_string, rest_string); int num_vars_expected = 2; if (num_vars_read < num_vars_expected) { gerror("Line `%s':\nexpected 'intmethod method'\n", command_string); } else if (num_vars_read > num_vars_expected) { warn("Line `%s':\ntext '%s' ignored\n", command_string, rest_string); } int method_value; if (my_atoi(intmethod_string, &method_value)) { gerror("Line `%s':\nUnable to read method value\n", command_string); } #if __CYGWIN__ if (!bCygserverRunning && method_value != RIEMANN_SUM_NEW){ // throw warning when user tries to use cuba when not runnning // the cygwin cygserver service warn(CYGSERVER_WARNING); method_value = RIEMANN_SUM_NEW; } #endif switch (method_value) { case RIEMANN_SUM_NEW: init.mapintmethod = RIEMANN_SUM_NEW; break; case NEWTON_COTES: init.mapintmethod = NEWTON_COTES; break; #if INCLUDE_CUBA == 1 case CUBA_CUHRE_PARA: init.mapintmethod = CUBA_CUHRE_PARA; break; case CUBA_CUHRE_SERIAL: init.mapintmethod = CUBA_CUHRE_SERIAL; break; #else case CUBA_CUHRE_PARA: case CUBA_CUHRE_SERIAL: warn("The CUBA library is not included in this build of FINESSE.\nPlease obtain a version that has this feature built in.\n Defaulting to Riemann sum method."); init.mapintmethod = RIEMANN_SUM_NEW; #endif default: gerror("Line `%s':\nThere is no integration method that matches this input\n", command_string); } }