def get_dpoverp_amp(model_tfs, panda, bpm_samples): # Interval is around integer phases for positive dpoverp # and around halfes for the negative dpoverp bpm_data = bpm_samples.loc[panda.index, :].values mask = manager.get_accel_class(accel="lhc").get_element_types_mask(panda.index, types=["arc_bpm"]) #arc_bpm_names, arc_bpm_samples = _get_lhc_arc_bpms(panda.index.values, bpm_data) tunez = np.mean(panda.loc[mask, "TUNEZ"]) tunez_phase = _phase_mean(panda.loc[mask, "MUZ"]) turns = bpm_samples.shape[1] pos = _get_positive_dpoverp_intervals(tunez, tunez_phase, turns) neg = _get_negative_dpoverp_intervals(tunez, tunez_phase, turns) # We assume 3D kicks only happen in LHC for now. co = np.zeros_like(mask, dtype=float) model_dx = model_tfs.set_index("NAME").loc[panda.index.values[mask], "DX"] length = 0 for bin in pos: mini, maxi = bin co = co + np.sum(bpm_data[:, mini:maxi], axis=1) length = length + maxi - mini for bin in neg: mini, maxi = bin co = co - np.sum(bpm_data[:, mini:maxi], axis=1) length = length + maxi - mini print("ORBIT: {} {}".format(np.max(bpm_data[mask]), np.min(bpm_data[mask]))) co = co / 1e3 # Going from mm to m. codx = co[mask] * model_dx / length dx2 = model_dx ** 2 print("CODX: {}, DX2: {}".format(np.mean(codx), np.mean(dx2))) return np.sum(codx) / np.sum(dx2), pos, neg
def _get_lhc_arc_bpms(bpm_names, bpm_samples): accel_cls = manager.get_accel_class(accel="lhc") arc_bpms_mask = accel_cls.get_element_types_mask(bpm_names, types=["arc_bpm"]) arc_bpm_samples = bpm_samples[arc_bpms_mask] arc_bpm_names = bpm_names[arc_bpms_mask] return arc_bpm_names, arc_bpm_samples
def get_arc_bpms(model_twiss, bpm_names): # twiss_ac, intersected BPM names model_twiss.set_index("NAME", inplace=True) sequence = model_twiss.headers["SEQUENCE"].lower().replace("b1", "").replace("b2", "") AccelClass = manager.get_accel_class(accel=sequence) arc_bpms_mask = AccelClass.get_element_types_mask(bpm_names, types=["arc_bpm"]) arc_bpm_names = bpm_names[arc_bpms_mask] return arc_bpm_names
def get_dpoverp_amp(model_tfs, panda, bpm_samples): # Interval is around integer phases for positive dpoverp # and around halfes for the negative dpoverp bpm_data = bpm_samples.loc[panda.index, :].values mask = manager.get_accel_class(accel="lhc").get_element_types_mask( panda.index, types=["arc_bpm"]) #arc_bpm_names, arc_bpm_samples = _get_lhc_arc_bpms(panda.index.values, bpm_data) tunez = np.mean(panda.loc[mask, "TUNEZ"]) tunez_phase = _phase_mean(panda.loc[mask, "MUZ"]) turns = bpm_samples.shape[1] pos = _get_positive_dpoverp_intervals(tunez, tunez_phase, turns) neg = _get_negative_dpoverp_intervals(tunez, tunez_phase, turns) # We assume 3D kicks only happen in LHC for now. co = np.zeros_like(mask, dtype=float) model_dx = model_tfs.set_index("NAME").loc[panda.index.values[mask], "DX"] length = 0 for bin in pos: mini, maxi = bin co = co + np.sum(bpm_data[:, mini:maxi], axis=1) length = length + maxi - mini for bin in neg: mini, maxi = bin co = co - np.sum(bpm_data[:, mini:maxi], axis=1) length = length + maxi - mini print("ORBIT: {} {}".format(np.max(bpm_data[mask]), np.min(bpm_data[mask]))) co = co / 1e3 # Going from mm to m. codx = co[mask] * model_dx / length dx2 = model_dx**2 print("CODX: {}, DX2: {}".format(np.mean(codx), np.mean(dx2))) return np.sum(codx) / np.sum(dx2), pos, neg
def __init__(self, matchers_list, match_path, lhc_mode, minimize, madx_templates_runner): self._matchers_list = matchers_list self._match_path = match_path self._accel_cls = manager.get_accel_class("lhc", lhc_mode=lhc_mode) self._minimize = minimize self._madx_templates_runner = madx_templates_runner self._set_up_collections()
def get_arc_bpms(model_twiss, bpm_names): # twiss_ac, intersected BPM names model_twiss.set_index("NAME", inplace=True) sequence = model_twiss.headers["SEQUENCE"].lower().replace("b1", "").replace( "b2", "") AccelClass = manager.get_accel_class(accel=sequence) arc_bpms_mask = AccelClass.get_arc_bpms_mask(bpm_names) arc_bpm_names = bpm_names[arc_bpms_mask] return arc_bpm_names
def main(opt, accel_opt): """ Do all corrections in given correction-subfolders. Runs Mad-X with corrections applied. The files to use for corrections need to be in subfolders and it is assumed, that all corrections of one subfolder are applied at the same time. The files are found by the pattern in CHANGEFILE_PATTERN. This function also requires accelerator class options. Keyword Args: Required meas_dir (str): Path to the directory containing the measurement files. **Flags**: --meas_dir model_dir (str): Path to the model to use. **Flags**: --model_dir Optional clean_up (bool): Clean results-folder from corrections. **Flags**: --cleanup **Default**: ``True`` corrections_dir (str): Path to the directory containing the correction files. Defaults to 'measurement_dir'/Corrections if not given. **Flags**: --corrections_dir file_pattern (str): Filepattern to use to find correction files in subfolders. **Flags**: --filepattern **Default**: ``^changeparameters.*?\.madx$`` optics_file (str): Path to the optics file to use. If not present will default to model_path/modifiers.madx, if such a file exists. **Flags**: --optics_file change_marker: Changes marker for each line in the plot. **Flags**: --changemarker **Action**: ``store_true`` show_plots: Show plots. **Flags**: --show **Action**: ``store_true`` """ LOG.info("Started 'check_calculated_corrections'.") # get accelerator class accel_cls = manager.get_accel_class(accel_opt) accel_inst = accel_cls(model_dir=opt.model_dir) if opt.optics_file is not None: accel_inst.optics_file = opt.optics_file if opt.corrections_dir is None: opt.corrections_dir = os.path.join(opt.meas_dir, "Corrections") corrections = _get_all_corrections(opt.corrections_dir, opt.file_pattern) _call_madx(accel_inst, corrections) _get_diffs(corrections, opt.meas_dir, opt.file_pattern) _plot(corrections, opt.corrections_dir, opt.show_plots, opt.change_marker) if opt.clean_up: _clean_up(opt.corrections_dir, corrections)
def __init__(self, matchers_list, match_path, lhc_mode, minimize): self._matchers_list = matchers_list self._match_path = match_path self._accel_cls = manager.get_accel_class(accel="lhc", lhc_mode=lhc_mode) self._minimize = minimize self._set_up_collections() self._log_file = os.path.join(match_path, "match_madx_log.out") self._output_file = os.path.join(match_path, "resolved_madx_match.madx") tmpl_path = os.path.join(os.path.dirname(__file__), "lhc_general_matcher.madx") with open(tmpl_path, "r") as tmpl_file: self._main_template = tmpl_file.read()
def create_response(opt, other_opt): """ Entry point for creating pandas-based response matrices. The response matrices can be either created by response_madx or TwissResponse. Keyword Args: Required model_dir (str): Path to the model directory. **Flags**: ['-m', '--model_dir'] outfile_path (str): Name of fullresponse file. **Flags**: ['-o', '--outfile'] Optional creator (str): Create either with madx or analytically from twiss file. **Flags**: --creator **Choices**: ('madx', 'twiss') **Default**: ``madx`` debug: Print debug information. **Flags**: --debug **Action**: ``store_true`` delta_k (float): Delta K1L to be applied to quads for sensitivity matrix (madx-only). **Flags**: ['-k', '--deltak'] **Default**: ``2e-05`` optics_params (str): List of parameters to correct upon (e.g. BBX BBY; twiss-only). **Flags**: --optics_params variable_categories: List of the variables classes to use. **Flags**: --variables **Default**: ``['MQM', 'MQT', 'MQTL', 'MQY']`` """ with logging_tools.DebugMode(active=opt.debug, log_file=os.path.join( opt.model_dir, "generate_fullresponse.log")): LOG.info("Creating response.") accel_cls = manager.get_accel_class(other_opt) accel_inst = accel_cls(model_dir=opt.model_dir) if opt.optics_file is not None: accel_inst.optics_file = opt.optics_file if opt.creator == "madx": fullresponse = response_madx.generate_fullresponse( accel_inst, opt.variable_categories, delta_k=opt.delta_k) elif opt.creator == "twiss": fullresponse = response_twiss.create_response( accel_inst, opt.variable_categories, opt.optics_params) LOG.debug("Saving Response into file '{:s}'".format(opt.outfile_path)) with open(opt.outfile_path, 'wb') as dump_file: pickle.Pickler(dump_file, -1).dump(fullresponse)
def create_response(opt, other_opt): """ Entry point for creating pandas-based response matrices. The response matrices can be either created by response_madx or TwissResponse. Keyword Args: Required model_dir (str): Path to the model directory. **Flags**: ['-m', '--model_dir'] outfile_path (str): Name of fullresponse file. **Flags**: ['-o', '--outfile'] Optional creator (str): Create either with madx or analytically from twiss file. **Flags**: --creator **Choices**: ('madx', 'twiss') **Default**: ``madx`` debug: Print debug information. **Flags**: --debug **Action**: ``store_true`` delta_k (float): Delta K1L to be applied to quads for sensitivity matrix (madx-only). **Flags**: ['-k', '--deltak'] **Default**: ``2e-05`` optics_params (str): List of parameters to correct upon (e.g. BBX BBY; twiss-only). **Flags**: --optics_params variable_categories: List of the variables classes to use. **Flags**: --variables **Default**: ``['MQM', 'MQT', 'MQTL', 'MQY']`` """ with logging_tools.DebugMode(active=opt.debug, log_file=os.path.join(opt.model_dir, "generate_fullresponse.log")): LOG.info("Creating response.") accel_cls = manager.get_accel_class(other_opt) accel_inst = accel_cls(model_dir=opt.model_dir) if opt.optics_file is not None: accel_inst.optics_file = opt.optics_file if opt.creator == "madx": fullresponse = response_madx.generate_fullresponse( accel_inst, opt.variable_categories, delta_k=opt.delta_k ) elif opt.creator == "twiss": fullresponse = response_twiss.create_response( accel_inst, opt.variable_categories, opt.optics_params ) LOG.debug("Saving Response into file '{:s}'".format(opt.outfile_path)) with open(opt.outfile_path, 'wb') as dump_file: pickle.Pickler(dump_file, -1).dump(fullresponse)
def _get_segment(lhc_mode, beam, match_path, label): LOGGER.info("Getting matching range for beam " + str(beam) + "...") (_, range_start), (_, range_end) = _get_match_bpm_range( os.path.join(os.path.join(match_path, "sbs"), "sbsphasext_" + label + ".out")) LOGGER.info("Matching range for Beam " + str(beam) + ": " + range_start + " " + range_end) accel_cls = manager.get_accel_class("lhc", lhc_mode=lhc_mode, beam=beam)() optics_file = os.path.join(os.path.join(match_path, "sbs"), "modifiers.madx") segment = accel_cls.get_segment(label, range_start, range_end, optics_file) return segment
def _get_segment(self): range_start, range_end = _get_match_bpm_range(self.beatings.phase["x"]) LOGGER.info("Matching range for Beam " + str(self.beam) + ": " + range_start + " " + range_end) accel_cls = manager.get_accel_class( accel="lhc", lhc_mode=self.lhc_mode, beam=self.beam ) optics_file = os.path.join( os.path.join(self.matcher_path, "sbs"), "modifiers.madx" ) segment = accel_cls.get_segment(self.label, range_start, range_end, optics_file, None) return segment
def _calc_dp_over_p(main_input, bpm_data): model_twiss = tfs.read_tfs(main_input.model) model_twiss.set_index("NAME", inplace=True) sequence = model_twiss.headers["SEQUENCE"].lower().replace("b1", "").replace("b2", "") if sequence != "lhc": return 0.0 # TODO: What do we do with other accels. accel_cls = manager.get_accel_class(accel=sequence) arc_bpms_mask = accel_cls.get_element_types_mask(bpm_data.index, types=["arc_bpm"]) arc_bpms_mask = np.array([bool(x) for x in arc_bpms_mask]) arc_bpm_data = bpm_data.loc[arc_bpms_mask] # We need it in mm: dispersions = model_twiss.loc[arc_bpm_data.index, "DX"] * 1e3 closed_orbits = np.mean(arc_bpm_data, axis=1) numer = np.sum(dispersions * closed_orbits) denom = np.sum(dispersions ** 2) if denom == 0.: raise ValueError("Cannot compute dpp probably no arc BPMs.") dp_over_p = numer / denom return dp_over_p
def calc_dp_over_p(main_input, bpm_names, bpm_data): model_twiss = tfs_pandas.read_tfs(main_input.model) model_twiss.set_index("NAME", inplace=True) sequence = model_twiss.headers["SEQUENCE"].lower().replace("b1", "").replace( "b2", "") accel_cls = manager.get_accel_class(sequence) arc_bpms_mask = accel_cls.get_arc_bpms_mask(bpm_names) arc_bpm_data = bpm_data[arc_bpms_mask] arc_bpm_names = bpm_names[arc_bpms_mask] dispersions = model_twiss.loc[arc_bpm_names, "DX"] * 1e3 # We need it in mm closed_orbits = np.mean(arc_bpm_data, axis=1) numer = np.sum(dispersions * closed_orbits) denom = np.sum(dispersions**2) if denom == 0.: raise ValueError("Cannot compute dpp probably no arc BPMs.") dp_over_p = numer / denom return dp_over_p
def _calc_dp_over_p(main_input, bpm_data): model_twiss = tfs.read_tfs(main_input.model) model_twiss.set_index("NAME", inplace=True) sequence = model_twiss.headers["SEQUENCE"].lower().replace("b1", "").replace( "b2", "") if sequence != "lhc": return 0.0 # TODO: What do we do with other accels. accel_cls = manager.get_accel_class(accel=sequence) arc_bpms_mask = accel_cls.get_arc_bpms_mask(bpm_data.index) arc_bpm_data = bpm_data[arc_bpms_mask] # We need it in mm: dispersions = model_twiss.loc[arc_bpm_data.index, "DX"] * 1e3 closed_orbits = np.mean(arc_bpm_data, axis=1) numer = np.sum(dispersions * closed_orbits) denom = np.sum(dispersions**2) if denom == 0.: raise ValueError("Cannot compute dpp probably no arc BPMs.") dp_over_p = numer / denom return dp_over_p
def main(opt, accel_opt): if len(opt.corrections) or len(opt.labels): if len(opt.corrections) != len(opt.labels): raise ArgumentError( "Length of labels and corrections need to be equal.") accel_cls = manager.get_accel_class(accel_opt) if "lhc" not in accel_cls.NAME: raise AcceleratorDefinitionError("Only implemented for LHC") accel_inst = accel_cls(model_dir=opt.model_dir) if opt.optics_file is not None: accel_inst.optics_file = opt.optics_file locations = _get_locations_of_interest(accel_inst) results = {} results["main"] = _get_result(accel_inst, locations) for correction, label in zip(opt.corrections, opt.labels): results[label] = _get_result(accel_inst, locations, correction) _write_results(opt.output_dir, results)
def _parse_args(args=None): ''' Parses the arguments, checks for valid input and returns tuple It needs also the input needed to define the accelerator: --accel=<accel_name> and all the rest of the parameters needed to define given accelerator. e.g. for LHC runII 2017 beam 1 --accel lhc --lhcmode lhc_runII_2017 --beam 1 ''' parser = argparse.ArgumentParser() parser.add_argument("--measurement", help=("Path to measurement files, " "usually the GetLLM output dir."), dest="measurement", required=True) parser.add_argument("--model", help=("Model from where to get the segments and " "elements definitions, all BPMs and elements " "defined in --elements and --segments have to " "be present in this model."), dest="model", required=True) parser.add_argument("--optics", help=("Path to the optics file to use, usually " "the path to the modifiers.madx file."), dest="optics", required=True) parser.add_argument("--elements", help=("Comma separated element name list " "to run in element mode."), dest="elements") parser.add_argument("--segments", help=("Segments to run in segment mode with format: " "segment_name1,start1,end1;segment_name2,start2,end2;" "where start and end must be existing BPM names."), dest="segments") parser.add_argument("--output", help=("Directory where to put the output files."), dest="output", required=True) options, accel_args = parser.parse_known_args(args) accel_cls = manager.get_accel_class(accel_args) return accel_cls, options
def global_correction(opt, accel_opt): """ Do the global correction. Iteratively. Keyword Args: Required meas_dir: Path to the directory containing the measurement files. **Flags**: --meas_dir model_dir: Path to the dir containing the model (twiss.dat or twiss_elements.dat) to use. **Flags**: --model_dir Optional beta_file_name: Prefix of the beta file to use. E.g.: getkmodbeta **Flags**: --beta_file_name **Default**: ``getbeta`` debug: Print debug information. **Flags**: --debug **Action**: ``store_true`` eps (float): (Not implemented yet) Convergence criterion. If :math:`<|\Delta(PARAM \cdot WEIGHT)|> < \epsilon`, stop iteration. **Flags**: --eps **Default**: ``None`` errorcut (float): Reject BPMs whose error bar is higher than the corresponding input. Input in order of optics_params. **Flags**: --error_cut fullresponse_path: Path to the fullresponse binary file. If not given, calculates the response analytically. **Flags**: --fullresponse max_iter (int): Maximum number of correction re-iterations to perform. A value of `0` means the correction is calculated once (like in the old days). **Flags**: --max_iter **Default**: ``3`` method (str): Optimization method to use. (Not implemented yet) **Flags**: --method **Choices**: ['pinv'] **Default**: ``pinv`` modelcut (float): Reject BPMs whose deviation to the model is higher than the correspoding input. Input in order of optics_params. **Flags**: --model_cut optics_file: Path to the optics file to use, usually modifiers.madx. If not present will default to model_path/modifiers.madx **Flags**: --optics_file optics_params (str): List of parameters to correct upon (e.g. BBX BBY) **Flags**: --optics_params **Default**: ``['MUX', 'MUY', 'BBX', 'BBY', 'NDX', 'Q']`` output_path: Path to the directory where to write the output files, will default to the --meas input path. **Flags**: --output_dir **Default**: ``None`` svd_cut (float): Cutoff for small singular values of the pseudo inverse. (Method: 'pinv') Singular values smaller than :math:`rcond \cdot largest_singular_value` are set to zero **Flags**: --svd_cut **Default**: ``0.01`` use_errorbars: If True, it will take into account the measured errorbars in the correction. **Flags**: --use_errorbars **Action**: ``store_true`` variable_categories: List of names of the variables classes to use. **Flags**: --variables **Default**: ``['MQM', 'MQT', 'MQTL', 'MQY']`` virt_flag: If true, it will use virtual correctors. **Flags**: --virt_flag **Action**: ``store_true`` weights (float): Weights to apply to each measured quantity. Input in order of optics_params. **Flags**: --weights """ LOG.info("Starting Iterative Global Correction.") with logging_tools.DebugMode(active=opt.debug, log_file=os.path.join(opt.model_dir, "iterative_correction.log")): not_implemented_params = [k for k in opt.optics_params if k not in _get_measurement_filters()] if any(not_implemented_params): raise NotImplementedError("Correct iterative is not equipped for parameters:" "'{:s}'".format(not_implemented_params)) # ######### Preparations ######### # # check on opt opt = _check_opt(opt) meth_opt = _get_method_opt(opt) # get accelerator class accel_cls = manager.get_accel_class(accel_opt) accel_inst = accel_cls(model_dir=opt.model_dir) if opt.optics_file is not None: accel_inst.optics_file = opt.optics_file # convert numbers to dictionaries w_dict = dict(zip(opt.optics_params, opt.weights)) mcut_dict = dict(zip(opt.optics_params, opt.modelcut)) ecut_dict = dict(zip(opt.optics_params, opt.errorcut)) # read data from files vars_list = _get_varlist(accel_cls, opt.variable_categories, opt.virt_flag) optics_params, meas_dict = _get_measurment_data( opt.optics_params, opt.meas_dir, opt.beta_file_name, w_dict, ) mcut_dict = _automate_modelcut(mcut_dict, meas_dict, opt.variable_categories) if opt.fullresponse_path is not None: resp_dict = _load_fullresponse(opt.fullresponse_path, vars_list) else: resp_dict = response_twiss.create_response( accel_inst, opt.variable_categories, optics_params ) # the model in accel_inst is modified later, so save nominal model here to variables nominal_model = _maybe_add_coupling_to_model(accel_inst.get_model_tfs(), optics_params) # apply filters to data meas_dict = _filter_measurement( optics_params, meas_dict, nominal_model, opt.use_errorbars, w_dict, ecut_dict, mcut_dict ) meas_dict = _append_model_to_measurement(nominal_model, meas_dict, optics_params) resp_dict = _filter_response_index(resp_dict, meas_dict, optics_params) resp_matrix = _join_responses(resp_dict, optics_params, vars_list) # _dump(os.path.join(opt.output_path, "measurement_dict.bin"), meas_dict) delta = tfs.TfsDataFrame(0, index=vars_list, columns=["DELTA"]) # ######### Iteration Phase ######### # for iteration in range(opt.max_iter + 1): LOG.info("Correction Iteration {:d} of {:d}.".format(iteration, opt.max_iter)) # ######### Update Model and Response ######### # if iteration > 0: LOG.debug("Updating model via MADX.") corr_model_path = os.path.join(opt.output_path, "twiss_" + str(iteration) + ".dat") _create_corrected_model(corr_model_path, opt.change_params_path, accel_inst, opt.debug) corr_model_elements = tfs.read_tfs(corr_model_path, index="NAME") corr_model_elements = _maybe_add_coupling_to_model( corr_model_elements, optics_params ) corr_model = corr_model_elements.loc[tfs.get_bpms(corr_model_elements), :] meas_dict = _append_model_to_measurement(corr_model, meas_dict, optics_params) if opt.update_response: LOG.debug("Updating response.") # please look away for the next two lines. accel_inst._model = corr_model accel_inst._elements = corr_model_elements resp_dict = response_twiss.create_response( accel_inst, opt.variable_categories, optics_params ) resp_dict = _filter_response_index(resp_dict, meas_dict, optics_params) resp_matrix = _join_responses(resp_dict, optics_params, vars_list) # ######### Actual optimization ######### # delta += _calculate_delta( resp_matrix, meas_dict, optics_params, vars_list, opt.method, meth_opt) writeparams(opt.change_params_path, delta) writeparams(opt.change_params_correct_path, -delta) LOG.debug("Cumulative delta: {:.5e}".format( np.sum(np.abs(delta.loc[:, "DELTA"].values)))) write_knob(opt.knob_path, delta) LOG.info("Finished Iterative Global Correction.")
def _get_lhc_arc_bpms(bpm_names, bpm_samples): accel_cls = manager.get_accel_class(accel="lhc") arc_bpms_mask = accel_cls.get_element_types_mask(bpm_names, types=["arc_bpm"]) #arc_bpm_samples = bpm_samples[arc_bpms_mask] #arc_bpm_names = bpm_names[arc_bpms_mask] return arc_bpm_names, arc_bpm_samples
def main(opt, accel_opt): """ Do all corrections in given correction-subfolders. Runs Mad-X with corrections applied. The files to use for corrections need to be in subfolders and it is assumed, that all corrections of one subfolder are applied at the same time. The files are found by the pattern in CHANGEFILE_PATTERN. This function also requires accelerator class options. Keyword Args: Required meas_dir (str): Path to the directory containing the measurement files. **Flags**: --meas_dir model_dir (str): Path to the model to use. **Flags**: --model_dir Optional auto_scale (float): Scales the plot, so that this percentage of points is inside the picture. **Flags**: --autoscale beta_file_name: Prefix of the beta file to use. E.g.: getkmodbeta **Flags**: --beta_file_name **Default**: ``getbeta`` change_marker: Changes marker for each line in the plot. **Flags**: --changemarker **Action**: ``store_true`` clean_up (bool): Clean results-folder from corrections. **Flags**: --cleanup **Default**: ``True`` corrections_dir (str): Path to the directory containing the correction files. Defaults to 'measurement_dir'/Corrections if not given. **Flags**: --corrections_dir error_cut (float): Reject BPMs whose error bar is higher than the corresponding input. **Flags**: --error_cut file_pattern (str): Filepattern to use to find correction files in subfolders. **Flags**: --filepattern **Default**: ``^changeparameters.*?\.madx$`` model_cut (float): Reject BPMs whose deviation to the model is higher than the corresponding input. **Flags**: --model_cut optics_file (str): Path to the optics file to use. If not present will default to model_path/modifiers.madx, if such a file exists. **Flags**: --optics_file params (basestring): Names of the parameter to cut. Only for specifying the cutting order. **Flags**: --params_cut show_plots: Show plots. **Flags**: --show **Action**: ``store_true`` """ LOG.info("Started 'check_calculated_corrections'.") # get accelerator class accel_cls = manager.get_accel_class(accel_opt) accel_inst = accel_cls(model_dir=opt.model_dir) if opt.optics_file is not None: accel_inst.optics_file = opt.optics_file if opt.corrections_dir is None: opt.corrections_dir = os.path.join(opt.meas_dir, "Corrections") logging_tools.add_module_handler( logging_tools.file_handler( os.path.join(opt.corrections_dir, LOG_FILE) ) ) # cuts are only used for rms calculation if len(opt.params) != len(opt.model_cut): raise ValueError("Length of model cut does not equal the length of the parameters.") if len(opt.params) != len(opt.error_cut): raise ValueError("Length of error cut does not equal the length of the parameters.") mcut = dict(zip(opt.params, opt.model_cut)) ecut = dict(zip(opt.params, opt.error_cut)) masks = _get_measurement_masks(accel_inst, opt.meas_dir, mcut, ecut, opt.beta_file_name) # main functionality corrections = _get_all_corrections(opt.corrections_dir, opt.file_pattern) _call_madx(accel_inst, corrections) _get_diffs(corrections, opt.meas_dir, opt.file_pattern, opt.beta_file_name) figs = _plot(corrections, opt.corrections_dir, opt.show_plots, opt.change_marker, opt.auto_scale, masks) if opt.clean_up: _clean_up(opt.corrections_dir, corrections) return figs
def main(opt, accel_opt): """ Do all corrections in given correction-subfolders. Runs Mad-X with corrections applied. The files to use for corrections need to be in subfolders and it is assumed, that all corrections of one subfolder are applied at the same time. The files are found by the pattern in CHANGEFILE_PATTERN. This function also requires accelerator class options. Keyword Args: Required meas_dir (str): Path to the directory containing the measurement files. **Flags**: --meas_dir model_dir (str): Path to the model to use. **Flags**: --model_dir Optional auto_scale (float): Scales the plot, so that this percentage of points is inside the picture. **Flags**: --autoscale beta_file_name: Prefix of the beta file to use. E.g.: getkmodbeta **Flags**: --beta_file_name **Default**: ``getbeta`` change_marker: Changes marker for each line in the plot. **Flags**: --changemarker **Action**: ``store_true`` clean_up (bool): Clean results-folder from corrections. **Flags**: --cleanup **Default**: ``True`` corrections_dir (str): Path to the directory containing the correction files. Defaults to 'measurement_dir'/Corrections if not given. **Flags**: --corrections_dir error_cut (float): Reject BPMs whose error bar is higher than the corresponding input. **Flags**: --error_cut file_pattern (str): Filepattern to use to find correction files in subfolders. **Flags**: --filepattern **Default**: ``^changeparameters.*?\.madx$`` model_cut (float): Reject BPMs whose deviation to the model is higher than the corresponding input. **Flags**: --model_cut optics_file (str): Path to the optics file to use. If not present will default to model_path/modifiers.madx, if such a file exists. **Flags**: --optics_file params (basestring): Names of the parameter to cut. Only for specifying the cutting order. **Flags**: --params_cut show_plots: Show plots. **Flags**: --show **Action**: ``store_true`` """ LOG.info("Started 'check_calculated_corrections'.") # get accelerator class accel_cls = manager.get_accel_class(accel_opt) accel_inst = accel_cls(model_dir=opt.model_dir) if opt.optics_file is not None: accel_inst.optics_file = opt.optics_file if opt.corrections_dir is None: opt.corrections_dir = os.path.join(opt.meas_dir, "Corrections") logging_tools.add_module_handler( logging_tools.file_handler( os.path.join(opt.corrections_dir, LOG_FILE) ) ) # cuts are only used for rms calculation if len(opt.params) != len(opt.model_cut): raise ValueError("Length of model cut does not equal the length of the parameters.") if len(opt.params) != len(opt.error_cut): raise ValueError("Length of error cut does not equal the length of the parameters.") mcut = dict(zip(opt.params, opt.model_cut)) ecut = dict(zip(opt.params, opt.error_cut)) masks = _get_measurement_masks(accel_inst, opt.meas_dir, mcut, ecut, opt.beta_file_name) # main functionality corrections = _get_all_corrections(opt.corrections_dir, opt.file_pattern) _call_madx(accel_inst, corrections) _get_diffs(corrections, opt.meas_dir, opt.file_pattern, opt.beta_file_name) figs = _plot(corrections, opt.corrections_dir, opt.show_plots, opt.change_marker, opt.auto_scale, masks) if opt.clean_up: _clean_up(opt.corrections_dir, corrections)
def _parse_args(args=None): ''' Parses the arguments, checks for valid input and returns tupel It needs also the input needed to define the accelerator: --accel=<accel_name> and all the rest of the parameters needed to define given accelerator. e.g. for LHC runII 2017 beam 1 --accel lhc --lhcmode lhc_runII_2017 --beam 1 ''' parser = argparse.ArgumentParser() parser.add_argument( "-f", "--path", # assumes that output is same as input help="Path to measurement files", default="./", dest="path") parser.add_argument( "-s", "--start", help= "give start,endbpm,name (multiple allowed) eg: start1,end1,name1,start2,end2,name2,...", metavar="SEGF", default="./", dest="segf") parser.add_argument( "-t", "--twiss", help= "basic twiss file, the modifiers.madx is assumed to be in the same directory", metavar="TWISS", default="./", dest="twiss") parser.add_argument("-p", "--save", help="Output path", metavar="SAVE", default="./", dest="save") parser.add_argument( "-m", "--mad", # assumes that output is same as input help="mad link", default="", dest="mad") parser.add_argument( "-b", "--bbsource", # assumes that output is same as input help="beta beat source", metavar="bb", default="/afs/cern.ch/eng/sl/lintrack/Beta-Beat.src/", dest="bb") parser.add_argument("-x", "--take", help="If present, it will run MADX on previously " "created scripts, without remaking them.", dest="madpass", action="store_true") parser.add_argument("-c", "--cuts", help="cut on error of beta in percentage", metavar="cuts", default="10", dest="cuts") parser.add_argument( "-w", "--w", # Path to Chromaticity functions help="Path to chromaticity functions, by default this is skiped", metavar="wpath", default="0", dest="wpath") options, accel_args = parser.parse_known_args(args) accel_cls = manager.get_accel_class(accel_args) return accel_cls, options