Giter Club home page Giter Club logo

omc3's Introduction

3

Tests Code Climate coverage Code Climate maintainability (percentage) GitHub last commit GitHub release DOI

This is the python-tool package of the Optics Measurements and Corrections team (OMC) at CERN.

Most of the codes are generic and not limited to CERN accelerators, and the package can easily be used for your favorite circular accelerator. To see how to adapt this for your machine, see our documentation, Model section. To contribute, see our guidelines on the OMC website.

Documentation

Installing

Installation is easily done via pip:

pip install omc3

For development purposes, we recommend creating a new virtual environment and installing from VCS in editable mode with all extra dependencies (cern for packages only available in the CERN GPN, test for pytest and relevant plugins, and doc for packages needed to build documentation)

git clone https://github.com/pylhc/omc3
pip install --editable "omc3[all]"

Codes can then be run with either python -m omc3.SCRIPT --FLAG ARGUMENT or calling the .py file directly.

Functionality

Main Scripts

Main scripts to be executed lie in the /omc3 directory. These include:

  • global_correction.py to calculate corrections from measurement files.
  • hole_in_one.py to perform frequency analysis on turn by turn BPM data and infer optics (and more) for a given accelerator.
  • madx_wrapper.py to start a MAD-X run with a file or string as input.
  • model_creator.py to generate optics models required for optics analysis.
  • response_creator.py to provide correction response files.
  • run_kmod.py to analyze data from K-modulation and return the measured optics functions.
  • tbt_converter.py to convert different turn by turn data types to SDDS, potentially adding noise.
  • amplitude_detuning_analysis.py to perform amp. det. analysis on optics data with tune correction.
  • knob_extractor.py to extract from NXCALS the value of given knobs in the machine at a given time.

Plotting Scripts

Plotting scripts for analysis outputs can be found in /omc3/plotting:

  • plot_spectrum.py to generate plots from files generated by frequency analysis.
  • plot_bbq.py to generate plots from files generated by BBQ analysis.
  • plot_amplitude_detuning.py to generate plots from files generated by amplitude detuning analysis.
  • plot_optics_measurements.py to generate plots from files generated by optics_measurements.
  • plot_tfs.py all-purpose tfs-file plotter.

Other Scripts

Other general utility scripts are in /omc3/scripts:

  • update_nattune_in_linfile.py to update the natural tune columns in the lin files by finding the highest peak in the spectrum in a given interval.
  • write_madx_macros.py to generate MAD-X tracking macros with observation points from a TWISS file.
  • merge_kmod_results.py to merge LSA results files created by kmod, and add the luminosity imbalance if the 4 needed IP/Beam files combination are present.
  • fake_measurement_from_model.py to create a fake measurement based on a model TWISS file.
  • betabeatsrc_output_converter.py to convert outputs from our old codes to omc3's new standardized format.
  • linfile_clean.py to automatically clean given columns in lin files.

Example use for these scripts can be found in the tests files. Documentation including relevant flags and parameters can be found at https://pylhc.github.io/omc3/.

License

This project is licensed under the MIT License - see the LICENSE file for details.

omc3's People

Contributors

awegsche avatar fscarlier avatar fsoubelet avatar hgarciam avatar jacquelinekeintzel avatar jaimecp89 avatar joschd avatar lmalina avatar mael-le-garrec avatar mihofer avatar tpersson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

omc3's Issues

Replace tfs and sdds with their respective packages

Todo:

  • install sdds and tfs-pandas in omc3-python
  • remove sdds and tfs folders
  • add sdds and tfs-pandas to requirement file
  • remove tests (don't forget input files)

Imports should be still the same!! Awesome!

Coupling in omc3

Coupling codes have to be rewritten in python3. Related to #13

  • plus a few bugfixes
  • nice, clean stuff
  • have to understand Ryoichi's black box
  • ADT, is the different position of hor and ver kickers a problem?
  • write tests

Sdds_files: split and simplify

  • Split into sdds and tbt package

  • write more unit tests

  • optimise for python 3

  • Pythonise the code as it was more or less copied from Java

Unify orbit unit to meters

Currently, we have a different unit of the orbit in the measurement (mm) and in the model (m) from MADX. Should be unified to meters (as agreed with Rogelio and Josch).
The affected codes are:
harpy and some optics_measurements modules (dpp, dispersion, kick and rdt).
The change should also include corresponding changes of input options.

bug in outliers.py

The line

mask = np.logical_and(mask,np.abs(y_orig - avg) < np.max([limit, nsig * std]))

has an issue:

With std being a list, the max function will result in
np.max(limit, np.array([some_value]))

If some_value is higher than limit, the result is [some_value] which is a list and cannot be compared by < with np.abs(...).

Proposed solution:
change to
mask = np.logical_and(mask,np.abs(y_orig - avg) < np.max(np.append(nsig * std, limit)))

TFS writer crashes if column names are not string

For example if they are int (which is the default for pandas).
Related to #11? (I don't know what #11 was referencing... please more detailed Issue descriptions).

Code Example :

import tfs
df = tfs.TfsDataFrame([[1,2,3]])
tfs.write("test.tfs", df)

Crashes with:

Traceback (most recent call last):
  File "/media/jdilly/Storage/Repositories/omc3/omc3/udillyties/tests/tfs_writer_test.py", line 3, in <module>
    tfs.write("test.tfs", df)
  File "/media/jdilly/Storage/Repositories/omc3/omc3/tfs/handler.py", line 173, in write_tfs
    colnames_str = _get_colnames_str(data_frame.columns, colwidth)
  File "/media/jdilly/Storage/Repositories/omc3/omc3/tfs/handler.py", line 202, in _get_colnames_str
    return "* " + fmt.format(*colnames)
ValueError: Unknown format code 's' for object of type 'int'

clean .gitignore

With the possibility of personal gitignores we can clean our gitignore from a lot of messy entries.

especially coding environment related ones like

.vscode
tags (from vim)
*.plist

harpy default params buggy

Crash when calling harpy (run_per_bunch) with default params from harpy_params():

omc3/omc3/hole_in_one.py

Lines 332 to 417 in 398bed5

def harpy_params():
params = EntryPointParameters()
params.add_parameter(flags="--files", name="files", required=True, nargs='+',
help="TbT files to analyse")
params.add_parameter(flags="--outputdir", name="outputdir", required=True,
help="Output directory.")
params.add_parameter(flags="--model", name="model", help="Model for BPM locations")
params.add_parameter(flags="--unit", name="unit", type=str, choices=("m", "cm", "mm", "um"),
default=HARPY_DEFAULTS["unit"],
help=f"A unit of TbT BPM orbit data. All cuts and output are in 'mm'.")
params.add_parameter(flags="--turns", name="turns", type=int, nargs=2,
default=HARPY_DEFAULTS["turns"],
help="Turn index to start and first turn index to be ignored.")
params.add_parameter(flags="--to_write", name="to_write", nargs='+',
default=HARPY_DEFAULTS["to_write"],
choices=('lin', 'spectra', 'full_spectra', 'bpm_summary'),
help="Choose the type of output. ")
# Cleaning parameters
params.add_parameter(flags="--clean", name="clean", action="store_true",
help="If present, the data are first cleaned.")
params.add_parameter(flags="--sing_val", name="sing_val", type=int,
default=HARPY_DEFAULTS["sing_val"],
help="Keep this amount of largest singular values.")
params.add_parameter(flags="--peak_to_peak", name="peak_to_peak", type=float,
default=HARPY_DEFAULTS["peak_to_peak"],
help="Peak to peak amplitude cut. This removes BPMs, "
"where abs(max(turn values) - min(turn values)) <= threshold.")
params.add_parameter(flags="--max_peak", name="max_peak", type=float,
default=HARPY_DEFAULTS["max_peak"],
help="Removes BPMs where the maximum orbit > limit.")
params.add_parameter(flags="--svd_dominance_limit", name="svd_dominance_limit",
type=float, default=HARPY_DEFAULTS["svd_dominance_limit"],
help="Limit for single BPM dominating a mode.")
params.add_parameter(flags="--bad_bpms", name="bad_bpms", nargs='*', help="Bad BPMs to clean.")
params.add_parameter(flags="--wrong_polarity_bpms", name="wrong_polarity_bpms", nargs='*',
help="BPMs with swapped polarity in both planes.")
params.add_parameter(flags="--keep_exact_zeros", name="keep_exact_zeros", action="store_true",
help="If present, will not remove BPMs with exact zeros in TbT data.")
params.add_parameter(flags="--first_bpm", name="first_bpm", type=str,
help="First BPM in the measurement. "
"Used to resynchronise the TbT data with model.")
params.add_parameter(flags="--opposite_direction", name="opposite_direction",
action="store_true",
help="If present, beam in the opposite direction to model"
" is assumed for resynchronisation of BPMs.")
# Harmonic analysis parameters
params.add_parameter(flags="--tunes", name="tunes", type=float, nargs=3,
help="Guess for the main tunes [x, y, z]. Tunez is disabled when set to 0")
params.add_parameter(flags="--nattunes", name="nattunes", type=float, nargs=3,
help="Guess for the natural tunes (x, y, z). Disabled when set to 0.")
params.add_parameter(flags="--natdeltas", name="natdeltas", type=float, nargs=3,
help="Guess for the offsets of natural tunes from the driven tunes"
" (x, y, z). Disabled when set to 0.")
params.add_parameter(flags="--autotunes", name="autotunes", type=str,
choices=("all", "transverse"),
help="The main tunes are guessed as "
"the strongest line in SV^T matrix frequency spectrum: "
"Synchrotron tune below ~0.03, betatron tunes above ~0.03.")
params.add_parameter(flags="--tune_clean_limit", name="tune_clean_limit", type=float,
default=HARPY_DEFAULTS["tune_clean_limit"],
help="The tune cleaning wont remove BPMs because of measured tune outliers"
" closer to the average tune than this limit.")
params.add_parameter(flags="--tolerance", name="tolerance", type=float,
default=HARPY_DEFAULTS["tolerance"],
help="Tolerance specifying an interval in frequency domain, where to look "
"for the tunes.")
params.add_parameter(flags="--free_kick", name="is_free_kick", action="store_true",
help="If present, it will perform the free kick phase correction")
params.add_parameter(flags="--window", name="window", type=str,
choices=("rectangle", "hann", "triangle", "welch", "hamming", "nuttal3",
"nuttal4"), default=HARPY_DEFAULTS["window"],
help="Windowing function to be used for frequency analysis.")
params.add_parameter(flags="--turn_bits", name="turn_bits", type=int,
default=HARPY_DEFAULTS["turn_bits"],
help="Number (frequency, complex coefficient) pairs in the calculation"
" is 2 ** turn_bits, i.e. the difference between "
"two neighbouring frequencies is 2 ** (- turn_bits - 1).")
params.add_parameter(flags="--output_bits", name="output_bits", type=int,
default=HARPY_DEFAULTS["output_bits"],
help="Number (frequency, complex coefficient) pairs in the output "
"is up to 2 ** output_bits (maximal in case full spectra is output). "
"There is one pair (with maximal amplitude of complex coefficient) "
"per interval of size 2 ** (- output_bits - 1).")
return params

with Error Message:
ERR: TypeError: '>' not supported between instances of 'float' and 'dict'

on

ERR:   File /media/awegsche/HDD/omc3/omc3/harpy/clean.py: line 103, in _detect_bpms_with_spikes
FILE      98     return bpm_flatness
FILE      99 
FILE     100 
FILE     101 def _detect_bpms_with_spikes(bpm_data, max_peak_cut):
FILE     102     """  Detects BPMs with spikes > max_peak_cut  """
FILE --> 103     too_high = bpm_data[bpm_data.max(axis=1) > max_peak_cut].index
FILE     104     too_low = bpm_data[bpm_data.min(axis=1) < -max_peak_cut].index
FILE     105     bpm_spikes = too_high.union(too_low)
FILE     106     if bpm_spikes.size:
FILE     107         LOGGER.debug(f"Spikes > {max_peak_cut} detected. BPMs removed: {bpm_spikes.size}")
FILE     108     return bpm_spikes

Full Error Log:

ERR: Traceback (most recent call last):
ERR:   File do_petra_analysis.py: line 47, in <module>
FILE      42     data = {}
FILE      43     data['X'] = pd.read_pickle(os.path.join(m.rawpath, "x_data"))
FILE      44     data['Y'] = pd.read_pickle(os.path.join(m.rawpath, "y_data"))
FILE      45     print(data['X'])
FILE      46 
FILE -->  47     lin_files.append(handler.run_per_bunch(TbtData([data], None, [0], 13000), hp))
FILE      48 
FILE      49 op = get_optics_params()
FILE      50 op.outputdir = os.path.join("output", SELECTION + "_output_" + ID)
FILE      51 op.modeldir = "./2019_june_26_desy"
FILE      52 op.accelerator = "petra"
ERR:     lin_files.append(handler.run_per_bunch(TbtData([data], None, [0], 13000), hp))
ERR:   File /media/awegsche/HDD/omc3/omc3/harpy/handler.py: line 43, in run_per_bunch
FILE      38     bpm_datas, usvs, lins, bad_bpms = {}, {}, {}, {}
FILE      39     output_file_path = _get_output_path_without_suffix(harpy_input.outputdir, harpy_input.files)
FILE      40     for plane in PLANES:
FILE      41         bpm_data = _get_cut_tbt_matrix(tbt_data, harpy_input.turns, plane)
FILE      42         bpm_data = _scale_to_mm(bpm_data, harpy_input.unit)
FILE -->  43         bpm_data, usvs[plane], bad_bpms[plane], bpm_res = clean.clean(harpy_input, bpm_data, model)
FILE      44         lins[plane], bpm_datas[plane] = _closed_orbit_analysis(bpm_data, model, bpm_res)
FILE      45 
FILE      46     tune_estimates = harpy_input.tunes if harpy_input.autotunes is None else frequency.estimate_tunes(
FILE      47         harpy_input, usvs if harpy_input.clean else
FILE      48         dict(X=clean.svd_decomposition(bpm_datas["X"], harpy_input.sing_val),
ERR:     bpm_data, usvs[plane], bad_bpms[plane], bpm_res = clean.clean(harpy_input, bpm_data, model)
ERR:   File /media/awegsche/HDD/omc3/omc3/harpy/clean.py: line 39, in clean
FILE      34         return bpm_data, None, [], None
FILE      35     bpm_data, bpms_not_in_model = _get_only_model_bpms(bpm_data, model)
FILE      36     if bpm_data.empty:
FILE      37         raise AssertionError("Check BPMs names! None of the BPMs was found in the model!")
FILE      38     with timeit(lambda spanned: LOGGER.debug(f"Time for filtering: {spanned}")):
FILE -->  39         bpm_data, bad_bpms_clean = _cut_cleaning(harpy_input, bpm_data, model)
FILE      40     with timeit(lambda spanned: LOGGER.debug(f"Time for SVD clean: {spanned}")):
FILE      41         bpm_data, bpm_res, bad_bpms_svd, usv = _svd_clean(bpm_data, harpy_input)
FILE      42         all_bad_bpms = bpms_not_in_model + bad_bpms_clean + bad_bpms_svd
FILE      43     return bpm_data, usv, all_bad_bpms, bpm_res
FILE      44 
ERR:     bpm_data, bad_bpms_clean = _cut_cleaning(harpy_input, bpm_data, model)
ERR:   File /media/awegsche/HDD/omc3/omc3/harpy/clean.py: line 56, in _cut_cleaning
FILE      51 
FILE      52 def _cut_cleaning(harpy_input, bpm_data, model):
FILE      53     LOGGER.debug(f"Number of BPMs in the input {bpm_data.index.size}")
FILE      54     known_bad_bpms = _detect_known_bad_bpms(bpm_data, harpy_input.bad_bpms)
FILE      55     bpm_flatness = _detect_flat_bpms(bpm_data, harpy_input.peak_to_peak)
FILE -->  56     bpm_spikes = _detect_bpms_with_spikes(bpm_data, harpy_input.max_peak)
FILE      57     exact_zeros = _detect_bpms_with_exact_zeros(bpm_data, harpy_input.keep_exact_zeros)
FILE      58     all_bad_bpms = _index_union(known_bad_bpms, bpm_flatness, bpm_spikes, exact_zeros)
FILE      59     original_bpms = bpm_data.index
FILE      60 
FILE      61     bpm_data = bpm_data.loc[bpm_data.index.difference(all_bad_bpms)]
ERR:     bpm_spikes = _detect_bpms_with_spikes(bpm_data, harpy_input.max_peak)
ERR:   File /media/awegsche/HDD/omc3/omc3/harpy/clean.py: line 103, in _detect_bpms_with_spikes
FILE      98     return bpm_flatness
FILE      99 
FILE     100 
FILE     101 def _detect_bpms_with_spikes(bpm_data, max_peak_cut):
FILE     102     """  Detects BPMs with spikes > max_peak_cut  """
FILE --> 103     too_high = bpm_data[bpm_data.max(axis=1) > max_peak_cut].index
FILE     104     too_low = bpm_data[bpm_data.min(axis=1) < -max_peak_cut].index
FILE     105     bpm_spikes = too_high.union(too_low)
FILE     106     if bpm_spikes.size:
FILE     107         LOGGER.debug(f"Spikes > {max_peak_cut} detected. BPMs removed: {bpm_spikes.size}")
FILE     108     return bpm_spikes
ERR:     too_high = bpm_data[bpm_data.max(axis=1) > max_peak_cut].index
ERR:   File /home/awegsche/anaconda3/envs/pythonthree/lib/python3.7/site-packages/pandas/core/ops.py: line 1766, in wrapper
FILE     1761 
FILE     1762         else:
FILE     1763             values = self.get_values()
FILE     1764 
FILE     1765             with np.errstate(all='ignore'):
FILE --> 1766                 res = na_op(values, other)
FILE     1767             if is_scalar(res):
FILE     1768                 raise TypeError('Could not compare {typ} type with Series'
FILE     1769                                 .format(typ=type(other)))
FILE     1770 
FILE     1771             # always return a full value series here
ERR:     res = na_op(values, other)
ERR:   File /home/awegsche/anaconda3/envs/pythonthree/lib/python3.7/site-packages/pandas/core/ops.py: line 1649, in na_op
FILE     1644                 x = x.view('i8')
FILE     1645 
FILE     1646             method = getattr(x, op_name, None)
FILE     1647             if method is not None:
FILE     1648                 with np.errstate(all='ignore'):
FILE --> 1649                     result = method(y)
FILE     1650                 if result is NotImplemented:
FILE     1651                     return invalid_comparison(x, y, op)
FILE     1652             else:
FILE     1653                 result = op(x, y)
FILE     1654 
ERR:     result = method(y)
ERR: TypeError: '>' not supported between instances of 'float' and 'dict'

make PETRA input Handler

  • decide, together with the PETRA team, which file format should be used
  • implement the corresponding input handler

Proposal: Create definition-classes for output files

In my opinion all output files should be fixed as classes in the code, which define output name and columns as well as column types. Maybe even headers.

Every reference to a column should then be handled by referring to the column of the respective class as a constant.

Also this would limit the problem with the tfs-writer that occurs sometimes, when you don't define the cloumn data-type and it tries to guess.

Should be combined somehow with tfs-collection.

create a more accelerator independent data loading routine

idea is to allow loading also non-lhc/non-sdds data without previous conversion to sdds

  • split up tbt.handler.py in data_class.py containing the class TbtData and var. accel_handler.py which all implement the read_tbt function to read the specific files (possibly also write_tbt etc.)

  • in hole_in_one.py / _run_harpy select then appropriate module to import and read tbt

Optics measurements and accelerator classes

Transfer optics measurements and accelerator classes from Beta-Beat.src:
This is a large task as the codes very entangled:

  • Make the algorithms python 3 compatible
  • Make the model creation python 3 compatible
  • Make accelerator classes python 3 compatible
  • Redesign the algorithm codes/accelerator classes to run for all accelerators
  • Refactor for easier maintainability and debugging
  • Write tests

Extension of entrypoint arguments

Extension of entrypoint arguments depends on the type of input, i.e. way to extend option differs when config file or command line arguments were used.

Chromatic analysis

Implement chromatic analysis based on 3D excitation

  • Chromaticity measurement

  • Chromatic beta-beating measurement

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.