Source code for GetLLM.GetLLM

import sys
from os.path import abspath, join, dirname, pardir
new_path = abspath(join(dirname(abspath(__file__)), pardir))
if new_path not in sys.path:
    sys.path.append(new_path)
import GetLLM
from tfs_files import tfs_pandas
r'''
.. module: GetLLM.GetLLM

Created on 11/09/09

:author: Glenn Vanbavinckhove  (gvanbavi@cern.ch)

:version: 3.00dev


GetLLM calculates a large collection of optics functions and parameters at the BPMs using the output from DRIVE.

The GetLLM output is distributed over different files according to the observable and the transverse plane:
 - getCO*; files containing the closed orbit at all BPMs, one file per plane.
 - getIP*; files containing beta and phase advance functions at the IPs.
 - getampbeta*; files containing the beta function as compputed from amplitude, one file per plane (in case of ACdipole free and driven data is also computed).
 - getbeta*; files containing the beta function as computed from phase advances between 3 BPMs. There is one file per plane (in case of AC-dipole free and driven data is computed).
 - getchi*; files containing the $\chi$ terms.
 - getcouple*; files containing the coupling resonances $f_{1001}$  and $f_{0101}$ (in case of AC-dipole free and driven data is computed).
 - getsex*; files containing the sextupolar resonance driving terms.
 - getphase*; files containing the phase advances between BPMs, one file per plane (in case of AC-dipole free and driven data is computed).
 - getphasetot*; files containing the total phase-advance using the first BPM as reference, one file per plane (in case of ACdipole free and driven data is computed).
 - getkick*; files containing the kick amplitudes and the linear invariants as derived from peak-to-peak values and spectral lines amplitudes.
 - getD*; files containing the dispersion, one per plane ( if off-momentum data is acquired).
 - getNDx*; files containing the normalized horizontal dispersion ( if off-momentum data is acquired).


Usage1::

    >pythonafs ../GetLLM.py -m ../../MODEL/SPS/twiss.dat -f ../../MODEL/SPS/SimulatedData/ALLBPMs.3 -o ./

Usage2::

    >pythonafs ../GetLLM.py -m ../../MODEL/SPS/twiss.dat -d mydictionary.py -f 37gev270amp2_12.sdds.new -o ./


Change history::

        git log GetLLM.py


        --- STRUCTURE ---

_parse_args()-function
    _parse_args
main()-function
    main
helper-functions
    _intial_setup       note the missing i in the name!
    _create_tfs_files   
    _analyse_src_files
    _check_bpm_compatibility
    _calculate_orbit
    _phase_and_beta_for_non_zero_dpp
    _calculate_getsextupoles
    _calculate_kick
    _get_calibrated_amplitudes
    _copy_calibration_files
helper-classes
    _GetllmData
        __init__
        set_outputpath
        set_bpmu_and_cut_for_closed_orbit
    _TwissData
        __init__
        has_zero_dpp_x
        has_non_zero_dpp_x
        has_zero_dpp_y
        has_non_zero_dpp_y
        has_no_input_files
    _TuneData
        __init__
        initialize_tunes
main invocation
    _start
    call _start()
'''
import os
import sys
import traceback
import math

import Python_Classes4MAD.metaclass
from tfs_utils_getllm import GetllmTfsFile
import algorithms.helper
import algorithms.phase
import algorithms.beta
import algorithms.compensate_ac_effect
import algorithms.dispersion
import algorithms.coupling
import algorithms.resonant_driving_terms
import algorithms.interaction_point
import algorithms.chi_terms
import algorithms.constants
import utils.iotools
import time, calendar
import copy

from numpy import array

from utils import logging_tools

LOGGER = logging_tools.get_logger(__name__,logging_tools.WARNING,logging_tools.WARNING)

####
#######
#########
VERSION = 'V3.0.0 Dev'
#########
#######
####
DEBUG = sys.flags.debug  # True with python option -d! ("python -d GetLLM.py...") (vimaier)

# default arguments:

ACCEL       = "LHCB1"   #@IgnorePep8
DICT        = "0"       #@IgnorePep8
MODELTWISS  = "0"       #@IgnorePep8
FILES       = "0"       #@IgnorePep8
COCUT       = 4000      #@IgnorePep8
OUTPATH     = "./"      #@IgnorePep8
NBCPL       = 2         #@IgnorePep8
NONLINEAR   = False     #@IgnorePep8
TBTANA      = "SUSSIX"  #@IgnorePep8
BPMUNIT     = "um"      #@IgnorePep8
LHCPHASE    = "0"       #@IgnorePep8
BBTHRESH    = "0.15"    #@IgnorePep8
ERRTHRESH   = "0.15"    #@IgnorePep8
NUMBER_OF_BPMS  = 10    #@IgnorePep8
RANGE_OF_BPMS   = 11    #@IgnorePep8
AVERAGE_TUNE    = 0     #@IgnorePep8
CALIBRATION     = None  #@IgnorePep8
ERRORDEFS       = None  #@IgnorePep8
NPROCESSES      = 16    #@IgnorePep8
ONLYCOUPLING    = 0     #@IgnorePep8
USE_ONLY_THREE_BPMS_FOR_BETA_FROM_PHASE   = 0    #@IgnorePep8
DEFAULT_USE_ERROR_OF_MEAN = 0 #@IgnorePep8

#===================================================================================================
# _parse_args()-function
#===================================================================================================
def _parse_args():
    ''' Parses command line arguments. '''
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option("-a", "--accel",
                    help="Which accelerator: LHCB1 LHCB2 LHCB4? SPS RHIC TEVATRON",
                    metavar="ACCEL", default=ACCEL, dest="ACCEL")
    parser.add_option("-d", "--dictionary",
                    help="File with the BPM dictionary",
                    metavar="DICT", default=DICT, dest="dict")
    parser.add_option("-m", "--model",
                    help="Twiss free model file *.dat. For free oscillations, ONLY the file *.dat should be present in the path. For AC dipole, the path should also contain a file *_ac.dat (BOTH files a needed in this case).",
                    metavar="MODELTWISS", default=MODELTWISS, dest="Twiss")
    parser.add_option("-f", "--files",
                    help="Files from analysis, separated by comma",
                    metavar="FILES", default=FILES, dest="files")
    parser.add_option("-o", "--output",
                    help="Output Path",
                    metavar="OUT", default=OUTPATH, dest="output")
    parser.add_option("-c", "--cocut",
                    help="Cut for closed orbit measurement [um]",
                    metavar="COCUT", default=COCUT, dest="COcut")
    parser.add_option("-n", "--nbcpl",
                    help="Analysis option for coupling, 1 bpm or 2 bpms",
                    metavar="NBCPL", default=NBCPL, dest="NBcpl")
    parser.add_option("-t", "--tbtana",
                    help="Turn-by-turn data analysis algorithm: SUSSIX, SVD or HA",
                    metavar="TBTANA", default=TBTANA, dest="TBTana")
    parser.add_option("--nonlinear",
                    help="Run the RDT analysis",
                    metavar="NONLINEAR", default=NONLINEAR, dest="nonlinear")
    parser.add_option("--useerrorofmean",
                      help="If true, use standard error instread of standard deviation.", 
                      metavar="DEFAULT_USE_ERROR_OF_MEAN",default=DEFAULT_USE_ERROR_OF_MEAN, dest="use_error_of_mean")
    parser.add_option("-b", "--bpmu",
                    help="BPMunit: um, mm, cm, m (default um)",
                    metavar="BPMUNIT", default=BPMUNIT, dest="BPMUNIT")
    parser.add_option("-p", "--lhcphase",
                    help="Compensate phase shifts by tunes for the LHC experiment data, off=0(default)/on=1",
                    metavar="LHCPHASE", default=LHCPHASE, dest="lhcphase")
    parser.add_option("-k", "--bbthreshold",
                    help="Set beta-beating threshold for action calculations, default = 0.15",
                    metavar="BBTHRESH", default=BBTHRESH, dest="bbthreshold")
    parser.add_option("-e", "--errthreshold",
                    help="Set beta relative uncertainty threshold for action calculations, default = 0.1",
                    metavar="ERRTHRESH", default=ERRTHRESH, dest="errthreshold")
    parser.add_option("-g", "--threebpm",
                    help="Forces to use the 3 BPM method, yes=1/no=0, default = 0",
                    metavar="USE_ONLY_THREE_BPMS_FOR_BETA_FROM_PHASE", type="int",
                    default=USE_ONLY_THREE_BPMS_FOR_BETA_FROM_PHASE, dest="use_only_three_bpms_for_beta_from_phase")
    parser.add_option("-j", "--numbpm",
                    help="Number of different BPM combinations for beta-calculation, default = 10",
                    metavar="NUMBER_OF_BPMS", type=int, default=NUMBER_OF_BPMS, dest="number_of_bpms")
    parser.add_option("-i", "--range",
                    help="Range of BPM for beta-calculation (>=3 and odd), default = 11",
                    metavar="RANGE_OF_BPMS", type=int, default=RANGE_OF_BPMS, dest="range_of_bpms")
    parser.add_option("-r", "--average_tune",
                    help="Set to 1 to use average tune for all BPMs instead of specific for each one.",
                    metavar="AVERAGE_TUNE", type="int", default=AVERAGE_TUNE, dest="use_average")
    parser.add_option("--calibration",
                    help="Path to the directory where the calibration files (calibration_x.out, calibration_y.out) are stored.",
                    metavar="CALIBRATION", default=CALIBRATION, dest="calibration_dir_path")
    parser.add_option("--errordefs",
                      help="Gives path to the error definition file. If specified, the analytical formula will be used to calculate weighted beta and alpha. Default = None",
                      metavar="PATH_TO_FILE", default=ERRORDEFS, dest="errordefspath")
    parser.add_option("--nprocesses", default=NPROCESSES, dest="nprocesses",
                      metavar="NPROCESSES", type="int",
                      help="Sets the number of processes used. -1: take the number of CPUs 0: run serially >1: take the specified number. default = {0:d}".format(NPROCESSES))
    parser.add_option("--coupling", default=ONLYCOUPLING, dest="onlycoupling",
                      metavar="ONLYCOUPLING", type="int",
                      help="When enabled only coupling is calculated. ")


    # awegsche June 2016, option to include an errorfile
    # update August 2016, looking by default for this file, raising error if unable to find it
    options, _ = parser.parse_args()
    
    return options


def get_times(files_to_analyse):
    times = []
    for f in files_to_analyse.split(','):
        meas = os.path.basename(f)
        tm = meas[11:34]
        try:
            time_obj = time.strptime(tm, '%Y_%m_%d@%H_%M_%S_%f')
        except ValueError:
            times.append(0)
            continue
            
        unix_time_utc = calendar.timegm(time_obj)
        times.append(unix_time_utc)
    return times


#===================================================================================================
# main()-function
#===================================================================================================
[docs]def main(outputpath, files_to_analyse, model_filename, dict_file=DICT, accel=ACCEL, lhcphase=LHCPHASE, bpmu=BPMUNIT, cocut=COCUT, nbcpl=NBCPL, nonlinear=NONLINEAR, tbtana=TBTANA, bbthreshold=BBTHRESH, errthreshold=ERRTHRESH, use_only_three_bpms_for_beta_from_phase=USE_ONLY_THREE_BPMS_FOR_BETA_FROM_PHASE, number_of_bpms=NUMBER_OF_BPMS, range_of_bpms=RANGE_OF_BPMS, use_average=AVERAGE_TUNE, calibration_dir_path=CALIBRATION, errordefspath=ERRORDEFS, nprocesses=NPROCESSES, onlycoupling=ONLYCOUPLING, use_error_of_mean=DEFAULT_USE_ERROR_OF_MEAN): ''' GetLLM main function. :param string outputpath: The output path to store results :param string files_to_analyse: List of files, comma separated string. :param string model_filename: Path and filename of model to be used :param string dict_file: Name of the script which will be executed. Should store dictionary with mappings of BPM names. :param string accel: Type of accelerator. LHCB1, LHCB2, LHCB4, RHIC, SPS :param string lhcphase: "0" or "1" -- Compensate phase shifts by tunes for the LHC experiment data, off=0(default)/on=1 :param string BPMU: BPMunit: "um", "mm", "cm", "m" (default "um") :param int COcut: Cut for closed orbit measurement [um] :param int NBcpl: For selecting the coupling measurement method 1 bpm or 2 bpms :param string TBTana: Turn-by-turn data analysis algorithm: SUSSIX, SVD or HA :param string bbthreshold: Threshold for _calculate_kick for (beta_d-beta_m)/beta_m :param string errthreshold: Threshold for calculate_kick for sigma(beta_d)/beta_d :param int use_only_three_bpms_for_beta_from_phase: :param int number_of_bpms: Number of BPM-combos for beta from phase :param int range_of_bpms: Range of BPMs for beta from phase :param int use_average: Uses AVG_MUX and AVG_MUY in _analyse_src_files if 1 :returns: int -- 0 if the function run successfully otherwise !=0. ''' return_code = 0 print "Starting GetLLM ", VERSION use_average = (use_average == 1) use_only_three_bpms_for_beta_from_phase = (use_only_three_bpms_for_beta_from_phase == 1) # The following objects stores multiple variables for GetLLM to avoid having many local # variables. Identifiers supposed to be as short as possible. # --vimaier twiss_d = _TwissData() tune_d = _TuneData() getllm_d = _GetllmData() getllm_d.set_outputpath(outputpath) getllm_d.set_bpmu_and_cut_for_closed_orbit(cocut, bpmu) getllm_d.lhc_phase = lhcphase getllm_d.num_bpms_for_coupling = nbcpl getllm_d.number_of_bpms = number_of_bpms getllm_d.range_of_bpms = range_of_bpms getllm_d.use_only_three_bpms_for_beta_from_phase = use_only_three_bpms_for_beta_from_phase getllm_d.errordefspath = errordefspath getllm_d.accel = accel getllm_d.nprocesses = nprocesses getllm_d.onlycoupling = onlycoupling algorithms.constants.USE_ERROR_OF_MEAN = bool(use_error_of_mean) dinj = DepInjector() dinj.initial("getllm_d", getllm_d)\ .initial("bbthreshold", bbthreshold)\ .initial("errthreshold", errthreshold) # Setup mad_twiss, mad_ac, bpm_dictionary, mad_elem, mad_best_knowledge, mad_ac_best_knowledge, mad_elem_centre = _intial_setup(getllm_d, model_filename, dict_file) dinj.initial("mad_twiss", mad_twiss)\ .initial("mad_ac", mad_ac)\ .initial("mad_elem", mad_elem)\ .initial("mad_best_knowledge", mad_best_knowledge)\ .initial("mad_ac_best_knowledge", mad_ac_best_knowledge)\ .initial("mad_elem_centre", mad_elem_centre) kick_times = get_times(files_to_analyse) # Creates the output files dictionary files_dict = _create_tfs_files(getllm_d, model_filename, nonlinear) # Copy calibration files calibration_x/y.out from calibration_dir_path to outputpath calibration_twiss = _copy_calibration_files(outputpath, calibration_dir_path) twiss_d, files_dict = _analyse_src_files(getllm_d, twiss_d, files_to_analyse, nonlinear, tbtana, files_dict, use_average, calibration_twiss) dinj.initial("calibration_twiss", calibration_twiss)\ .initial("files_dict", files_dict)\ .initial("temp_dict", copy.deepcopy(files_dict))\ .initial("twiss_d", twiss_d)\ .initial("kick_times", kick_times) # Load tunes from twiss instances, depending on with_ac_calc tune_d.initialize_tunes(getllm_d.with_ac_calc, mad_twiss, mad_ac, twiss_d) dinj.initial("tune_d", tune_d) # Construct pseudo-double plane BPMs if (getllm_d.accel == "SPS" or "RHIC" in getllm_d.accel) and twiss_d.has_zero_dpp_x() and twiss_d.has_zero_dpp_y(): [pseudo_list_x, pseudo_list_y] = algorithms.helper.pseudo_double_plane_monitors(mad_twiss, twiss_d.zero_dpp_x, twiss_d.zero_dpp_y, bpm_dictionary) else: # Initialize variables otherwise calculate_coupling would raise an exception(vimaier) pseudo_list_x = None pseudo_list_y = None dinj.initial("pseudo_list_x", pseudo_list_x)\ .initial("pseudo_list_y", pseudo_list_y) # -------- Check monitor compatibility between data and model _check_bpm_compatibility(twiss_d, mad_twiss) # -------- START Phase for beta calculation with best knowledge model in ac phase compensation if getllm_d.onlycoupling is 0: dinj.trigger(funct=algorithms.phase.calculate_phase, provides=("phase_d_bk", "_"), requires=("getllm_d", "twiss_d", "tune_d", "mad_best_knowledge", "mad_ac_best_knowledge", "mad_elem", "temp_dict")) # -------- START Phase dinj.trigger(funct=algorithms.phase.calculate_phase, provides=("phase_d", "tune_d"), requires=("getllm_d", "twiss_d", "tune_d", "mad_twiss", "mad_ac", "mad_elem", "files_dict")) # -------- START coupling. if (getllm_d.num_bpms_for_coupling > 0): dinj.trigger(funct=algorithms.coupling.calculate_coupling, provides=("tune_d", ), requires=("getllm_d", "twiss_d", "phase_d", "tune_d", "mad_twiss", "mad_ac", "files_dict", "pseudo_list_x", "pseudo_list_y")) else: print("nbcpl (num_bpms_for_coupling) is is zero or negative: skipping coupling calculation") if getllm_d.onlycoupling is 0: # -------- START Total Phase dinj.trigger(funct=algorithms.phase.calculate_total_phase, provides=("phase_tot",), requires=("getllm_d", "twiss_d", "tune_d", "phase_d", "mad_twiss", "mad_ac", "files_dict")) # -------- START Beta dinj.trigger(funct=algorithms.beta.calculate_beta_from_phase, provides=("beta_d", ), requires=("getllm_d", "twiss_d", "tune_d", "phase_d_bk", "mad_twiss", "mad_ac", "mad_elem", "mad_elem_centre", "mad_best_knowledge", "mad_ac_best_knowledge", "files_dict")) dinj.trigger(funct=algorithms.beta.calculate_beta_from_amplitude, provides=("beta_d", ), requires=("getllm_d", "twiss_d", "tune_d", "phase_d", "beta_d", "mad_twiss", "mad_ac", "files_dict")) # -------- START IP dinj.trigger(funct=algorithms.interaction_point.betastar_from_phase, requires=("getllm_d.accel", "phase_d", "mad_twiss", "files_dict")) # -------- START Orbit dinj.trigger(funct=_calculate_orbit, provides=("list_of_co_x", "list_of_co_y", "files_dict"), requires=("getllm_d", "twiss_d", "tune_d", "mad_twiss", "files_dict")) # -------- START Dispersion dinj.trigger(funct=algorithms.dispersion.calculate_dispersion, requires=("getllm_d", "twiss_d", "tune_d", "mad_twiss", "files_dict", "beta_d.x_amp", "list_of_co_x", "list_of_co_y")) # ------ Start get Q,JX,delta dinj.trigger(funct=_calculate_kick, provides=("files_dict", "inv_x", "inv_y"), requires=("kick_times", "getllm_d", "twiss_d", "phase_d", "beta_d", "mad_twiss", "mad_ac", "files_dict", "bbthreshold", "errthreshold")) # -------- START RDTs if nonlinear: dinj.trigger(funct=algorithms.resonant_driving_terms.calculate_RDTs, requires=("mad_twiss", "getllm_d", "twiss_d", "phase_d", "tune_d", "files_dict", "inv_x", "inv_y")) if tbtana == "SUSSIX": # ------ Start getsextupoles @ Glenn Vanbavinckhove dinj.trigger(funct=_calculate_getsextupoles, provides=("files_dict", ), requires=("twiss_d", "phase_d", "mad_twiss", "files_dict", "tune_d.q1f")) # ------ Start getchiterms @ Glenn Vanbavinckhove dinj.trigger(funct=algorithms.chi_terms.calculate_chiterms, provides=("files_dict", ), requires=("getllm_d", "twiss_d", "mad_twiss", "files_dict")) # Write results to files in files_dict dinj.trigger(funct=write_files, requires=("files_dict", )) return 0 if not dinj.something_raised else 1
# END main() --------------------------------------------------------------------------------------- def write_files(files_dict): print "Writing files" for tfsfile in files_dict.itervalues(): tfsfile.write_to_file(formatted=True)
[docs]class DepInjector(object): """Small "kind of" dependency injector to handle GetLLM operations. This class provides a shared namespace of dependencies between GetLLM operations. """ def __init__(self): self.results = {} self.something_raised = False
[docs] def trigger(self, funct=None, requires=None, provides=None, critical=False): """Resolves dependecies and runs the function given in "funct". Launches the function given in "funct" defining the return variables given in "provides". This function will check that all the names given in "requires" are already defined in the injector namespace with a result values, otherwise a KeyError will be thrown. If at least one of the requieres is marked as unavailable (because its defining computation failed), this computation will mark its own "provides" as unavailable as well. Arguments: funct: Callable to run. requires: Iterable of names that must be availabe for this to run. provides: Iterable of names that "funct" defines. It must have the same length as the values "funct" returns. critical: If true, if for some reason this function cannot run, an exception will be raised. Returns: The same instance of DepInjector to allow method chaining. """ deps = [self._solve_dep(name) for name in requires]\ if requires is not None\ else [] provides = provides if provides is not None else [] if any(isinstance(dep, DepInjector.Unavailable) for dep in deps): # Unavailable dependecies, so I cannot go on: if critical: raise DepInjector.MissingRequirementError() self._set_provides_unavailable(provides) return self try: # TODO: Lazy evaluation would be cooler, but this is GetLLM... results = DepInjector._to_tuple(funct(*deps)) except: self.something_raised = True if critical: raise # Report exception and mark dependencies as Unavailable: traceback.print_exc() self._set_provides_unavailable(provides) return self if provides: self.results.update(dict(zip(provides, DepInjector._to_tuple(results)))) return self
[docs] def initial(self, provides, value): """Defines a value in the dependency injector namespace. Arguments: provides: Name of the value to define. value: Value of the value to define. """ self.results[provides] = value return self
def _solve_dep(self, name): if "." in name: # Allowes attribute access parts = name.split(".") inst, rest = self.results[parts[0]], parts[1:] if isinstance(inst, DepInjector.Unavailable): return inst for subnode in rest: inst = getattr(inst, subnode) return inst return self.results[name] def _set_provides_unavailable(self, provides): for name in provides: if name not in self.results: self.results[name] = DepInjector.Unavailable() @staticmethod def _to_tuple(thing): if isinstance(thing, tuple): return thing return (thing, ) class Unavailable(object): __slots__ = ()
[docs] class MissingRequirementError(Exception): pass
#============================================================================== # helper-functions #============================================================================== def _intial_setup(getllm_d, model_filename, dict_file): if dict_file == "0": bpm_dictionary = {} else: execfile(dict_file) bpm_dictionary = dictionary # temporarily since presently name is not bpm_dictionary # Beam direction getllm_d.beam_direction = 1 if getllm_d.accel == "LHCB2": getllm_d.beam_direction = -1 # THIS IS CORRECT, be careful with tune sign in SUSSIX and eigenmode order in SVD elif getllm_d.accel == "LHCB4": getllm_d.beam_direction = 1 # IS THIS CORRECT? I (rogelio) try for Simon... getllm_d.accel = "LHCB2" # This is because elements later are named B2 anyway, not B4 #-- finding base model try: mad_twiss = Python_Classes4MAD.metaclass.twiss(model_filename, bpm_dictionary) # model from MAD : Twiss instance print "Base model found!" except IOError: print >> sys.stderr, "Twiss file loading failed for:\n\t", model_filename print >> sys.stderr, "Provide a valid model file." sys.exit(1) #-- finding the ac dipole model getllm_d.with_ac_calc = False ac_filename = model_filename.replace(".dat", "_ac.dat") adt_filename = model_filename.replace(".dat", "_adt.dat") try: if os.path.exists(ac_filename): mad_ac = Python_Classes4MAD.metaclass.twiss(ac_filename) # model with ac dipole : Twiss instance getllm_d.with_ac_calc = True print "Driven Twiss file found.\nAC dipole effects calculated with the effective model (get***_free2.out). INFO: ADT will be omitted" try: mad_ac_best_knowledge = Python_Classes4MAD.metaclass.twiss(model_filename.replace(".dat", "_ac_best_knowledge.dat")) print "Best knowledge model found for AC diapole, it will be used for beta calculation." except IOError: mad_ac_best_knowledge = mad_ac print "Best knowledge model not found for AC diapole." getllm_d.acdipole = "ACD" elif os.path.exists(adt_filename): mad_ac = Python_Classes4MAD.metaclass.twiss(adt_filename) # model with ac dipole : Twiss instance getllm_d.with_ac_calc = True print "Driven Twiss file found. ADT-AC-dipole effects calculated with the effective model (get***_free2.out)." print "Note: Using normal AC Dipole will be omitted." try: mad_ac_best_knowledge = Python_Classes4MAD.metaclass.twiss(model_filename.replace(".dat", "_adt_best_knowledge.dat")) print "Best knowledge model found for ADT-AC-dipole, it will be used for beta calculation." except IOError: mad_ac_best_knowledge = mad_ac print "Best knowledge model not found for ADT-AC-dipole." getllm_d.acdipole = "ADT" else: print "WARN: AC dipole effects not calculated. Driven twiss file does not exsist !" mad_ac = mad_twiss mad_ac_best_knowledge = mad_twiss except IOError: mad_ac = mad_twiss mad_ac_best_knowledge = mad_twiss print "WARN: IOError in loading ac/adt file." #-- Test if the AC dipole (MKQA) is in the model of LHC #TODO: This was crashing for dpp cases (WAnalysis or normal) I put this try to "fix" it, it should be check. try: mad_elem = Python_Classes4MAD.metaclass.twiss(model_filename.replace(".dat", "_elements.dat")) try: mad_elem_centre = Python_Classes4MAD.metaclass.twiss(model_filename.replace(".dat", "_elements_centre.dat")) except Exception: mad_elem_centre = mad_elem print "WARN: No elements_centre found, use end points instead. This shouldn't change much but is not recommended" except IOError: print >> sys.stderr, "ERROR: twiss_elements (filename {0:s}) not found. Systematic error calculation will fail.".format(model_filename.replace(".dat", "_elements.dat")) mad_elem = mad_twiss mad_elem_centre = mad_elem if getllm_d.with_ac_calc: if 'LHC' in getllm_d.accel: if 'MKQA.6L4.' + getllm_d.accel[3:] in getattr(mad_twiss, "NAME", []): print "AC dipole found in the model. AC dipole effects calculated with analytic equations (get***_free.out)" else: print "AC dipole found in the model. AC dipole effects calculated with analytic equations (get***_free.out)" else: print 'WARN: AC dipole effects calculated with analytic equations only for LHC for now' #-- Try to find the best knowledge model try: mad_best_knowledge = Python_Classes4MAD.metaclass.twiss(model_filename.replace(".dat", "_best_knowledge.dat")) if not getllm_d.with_ac_calc: mad_ac_best_knowledge = mad_best_knowledge print "Best knowledge model found, it will be used for beta calculation." except IOError: mad_best_knowledge = mad_twiss print "Best knowledge model not found." # look for file with important BPM pairs pairsfilename = os.path.dirname(model_filename) + "/important_pairs" if os.path.exists(pairsfilename): getllm_d.important_pairs = {} pair_file = open(pairsfilename) for line in pair_file: key_value = line.split(":") key = key_value[0].strip() value = key_value[1].strip() if key in getllm_d.important_pairs: getllm_d.important_pairs[key].append(value) else: getllm_d.important_pairs[key] = [value] return mad_twiss, mad_ac, bpm_dictionary, mad_elem, mad_best_knowledge, mad_ac_best_knowledge, mad_elem_centre # END _intial_setup --------------------------------------------------------------------------------- def _create_tfs_files(getllm_d, model_filename, nonlinear): ''' Creates the most tfs files and stores it in an dictionary whereby the key represents the file and the value is the corresponding GetllmTfsFile. :Return: dict: string --> GetllmTfsFile A dictionary of created GetllmTfsFile objects. Keys are the filenames and values are the GetllmTfsFile objects. ''' # Static variable of GetllmTfsFile to save the outputfile, GetLLM version and model filename GetllmTfsFile.s_output_path = getllm_d.outputpath GetllmTfsFile.s_getllm_version = VERSION GetllmTfsFile.s_mad_filename = model_filename files_dict = {} files_dict['getphasex.out'] = GetllmTfsFile('getphasex.out') files_dict['getphasey.out'] = GetllmTfsFile('getphasey.out') files_dict['getphasetotx.out'] = GetllmTfsFile('getphasetotx.out') files_dict['getphasetoty.out'] = GetllmTfsFile('getphasetoty.out') if getllm_d.with_ac_calc: files_dict['getphasex_free.out'] = GetllmTfsFile('getphasex_free.out') files_dict['getphasey_free.out'] = GetllmTfsFile('getphasey_free.out') files_dict['getphasex_free2.out'] = GetllmTfsFile('getphasex_free2.out') files_dict['getphasey_free2.out'] = GetllmTfsFile('getphasey_free2.out') files_dict['getphasetotx_free.out'] = GetllmTfsFile('getphasetotx_free.out') files_dict['getphasetoty_free.out'] = GetllmTfsFile('getphasetoty_free.out') files_dict['getphasetotx_free2.out'] = GetllmTfsFile('getphasetotx_free2.out') files_dict['getphasetoty_free2.out'] = GetllmTfsFile('getphasetoty_free2.out') files_dict['getbetax.out'] = GetllmTfsFile('getbetax.out') files_dict['getbetay.out'] = GetllmTfsFile('getbetay.out') if getllm_d.with_ac_calc: files_dict['getbetax_free.out'] = GetllmTfsFile('getbetax_free.out') files_dict['getbetay_free.out'] = GetllmTfsFile('getbetay_free.out') files_dict['getbetax_free2.out'] = GetllmTfsFile('getbetax_free2.out') files_dict['getbetay_free2.out'] = GetllmTfsFile('getbetay_free2.out') files_dict['getampbetax.out'] = GetllmTfsFile('getampbetax.out') files_dict['getampbetay.out'] = GetllmTfsFile('getampbetay.out') if getllm_d.with_ac_calc: files_dict['getampbetax_free.out'] = GetllmTfsFile('getampbetax_free.out') files_dict['getampbetay_free.out'] = GetllmTfsFile('getampbetay_free.out') files_dict['getampbetax_free2.out'] = GetllmTfsFile('getampbetax_free2.out') files_dict['getampbetay_free2.out'] = GetllmTfsFile('getampbetay_free2.out') files_dict['getCOx.out'] = GetllmTfsFile('getCOx.out') files_dict['getCOy.out'] = GetllmTfsFile('getCOy.out') files_dict['getNDx.out'] = GetllmTfsFile('getNDx.out') files_dict['getDx.out'] = GetllmTfsFile('getDx.out') files_dict['getDy.out'] = GetllmTfsFile('getDy.out') files_dict['getcouple.out'] = GetllmTfsFile('getcouple.out') if nonlinear: for rdt in algorithms.resonant_driving_terms.RDT_LIST: files_dict[rdt+'_line.out'] = GetllmTfsFile(rdt + '_line.out') files_dict[rdt+'.out'] = GetllmTfsFile(rdt + '.out') if getllm_d.with_ac_calc: files_dict['getcouple_free.out'] = GetllmTfsFile('getcouple_free.out') files_dict['getcouple_free2.out'] = GetllmTfsFile('getcouple_free2.out') files_dict['getcoupleterms.out'] = GetllmTfsFile('getcoupleterms.out') if "LHC" in getllm_d.accel: files_dict['getIP.out'] = GetllmTfsFile('getIP.out') files_dict['getIPx.out'] = GetllmTfsFile('getIPx.out') files_dict['getIPy.out'] = GetllmTfsFile('getIPy.out') files_dict['getIPfromphase.out'] = GetllmTfsFile('getIPfromphase.out') if getllm_d.with_ac_calc: files_dict['getIPx_free.out'] = GetllmTfsFile('getIPx_free.out') files_dict['getIPy_free.out'] = GetllmTfsFile('getIPy_free.out') files_dict['getIPx_free2.out'] = GetllmTfsFile('getIPx_free2.out') files_dict['getIPy_free2.out'] = GetllmTfsFile('getIPy_free2.out') files_dict['getIPfromphase_free.out'] = GetllmTfsFile('getIPfromphase_free.out') files_dict['getIPfromphase_free2.out'] = GetllmTfsFile('getIPfromphase_free2.out') files_dict["getsex3000.out"] = GetllmTfsFile("getsex3000.out") files_dict['getchi3000.out'] = GetllmTfsFile('getchi3000.out') files_dict['getchi1010.out'] = GetllmTfsFile('getchi1010.out') files_dict['getkick.out'] = GetllmTfsFile('getkick.out') files_dict['getkickphase.out'] = GetllmTfsFile('getkickphase.out') files_dict['getkickac.out'] = GetllmTfsFile('getkickac.out') return files_dict # END _create_tfs_files ----------------------------------------------------------------------------- def _analyse_src_files(getllm_d, twiss_d, files_to_analyse, nonlinear, turn_by_turn_algo, files_dict, use_average, calibration_twiss): if turn_by_turn_algo == "SUSSIX": suffix_x = '_linx' suffix_y = '_liny' elif turn_by_turn_algo == 'SVD': suffix_x = '_svdx' suffix_y = '_svdy' elif turn_by_turn_algo == 'HA': suffix_x = '_hax' suffix_y = '_hay' for file_in in files_to_analyse.split(','): # x file if file_in.endswith(".gz"): file_x = file_in.replace(".gz", suffix_x + ".gz") else: file_x = file_in + suffix_x if not os.path.exists(file_x): file_x = file_in + '.linx' twiss_file_x = None try: twiss_file_x = Python_Classes4MAD.metaclass.twiss(file_x) if twiss_file_x.has_no_bpm_data(): print >> sys.stderr, "Ignoring empty file:", twiss_file_x.filename twiss_file_x = None except IOError: print >> sys.stderr, "Cannot load file:", file_x except ValueError: pass # Information printed by metaclass already if None != twiss_file_x: if use_average: twiss_file_x.MUX = twiss_file_x.AVG_MUX if calibration_twiss is not None: twiss_file_x.AMPX, twiss_file_x.ERRAMPX, twiss_file_x.CALIBRATION, twiss_file_x.ERROR_CALIBRATION, twiss_file_x.NATURAL_TUNE, twiss_file_x.NATURAL_TUNE_RMS, twiss_file_x.TUNE, twiss_file_x.TUNE_RMS = _get_calibrated_amplitudes(twiss_file_x, calibration_twiss, "X") try: dppi = getattr(twiss_file_x, "DPP", 0.0) except AttributeError: dppi = 0.0 if type(dppi) != float: print >> sys.stderr, 'Warning: DPP may not be given as a number in ', file_x, '...trying to forcibly cast it as a number' try: dppi = float(dppi) print 'dppi= ', dppi except ValueError: print >> sys.stderr, 'but failing. DPP in ', file_x, ' is something wrong. String? --- leaving GetLLM' print >> sys.stderr, traceback.format_exc() sys.exit(1) if dppi == 0.0: twiss_d.zero_dpp_x.append(twiss_file_x) files_dict['getphasex.out'].add_filename_to_getllm_header(file_x) files_dict['getphasetotx.out'].add_filename_to_getllm_header(file_x) files_dict['getbetax.out'].add_filename_to_getllm_header(file_x) files_dict['getampbetax.out'].add_filename_to_getllm_header(file_x) files_dict['getCOx.out'].add_filename_to_getllm_header(file_x) files_dict['getNDx.out'].add_filename_to_getllm_header(file_x) files_dict['getDx.out'].add_filename_to_getllm_header(file_x) files_dict['getcouple.out'].add_filename_to_getllm_header(file_in) if nonlinear: for rdt in algorithms.resonant_driving_terms.RDT_LIST: files_dict[rdt+'_line.out'].add_filename_to_getllm_header(file_in) files_dict[rdt+'.out'].add_filename_to_getllm_header(file_in) if "LHC" in getllm_d.accel: files_dict['getIPx.out'].add_filename_to_getllm_header(file_in) files_dict['getIPy.out'].add_filename_to_getllm_header(file_in) files_dict['getIPfromphase.out'].add_filename_to_getllm_header(file_in) if getllm_d.with_ac_calc: files_dict['getIPx_free.out'].add_filename_to_getllm_header(file_in) files_dict['getIPy_free.out'].add_filename_to_getllm_header(file_in) files_dict['getIPx_free2.out'].add_filename_to_getllm_header(file_in) files_dict['getIPy_free2.out'].add_filename_to_getllm_header(file_in) files_dict['getIPfromphase_free.out'].add_filename_to_getllm_header(file_in) files_dict['getIPfromphase_free2.out'].add_filename_to_getllm_header(file_in) if getllm_d.with_ac_calc: files_dict['getphasex_free.out'].add_filename_to_getllm_header(file_x) files_dict['getphasex_free2.out'].add_filename_to_getllm_header(file_x) files_dict['getphasetotx_free.out'].add_filename_to_getllm_header(file_x) files_dict['getphasetotx_free2.out'].add_filename_to_getllm_header(file_x) files_dict['getbetax_free.out'].add_filename_to_getllm_header(file_x) files_dict['getbetax_free2.out'].add_filename_to_getllm_header(file_x) files_dict['getampbetax_free.out'].add_filename_to_getllm_header(file_x) files_dict['getampbetax_free2.out'].add_filename_to_getllm_header(file_x) files_dict['getcouple_free.out'].add_filename_to_getllm_header(file_in) files_dict['getcouple_free2.out'].add_filename_to_getllm_header(file_in) else: twiss_d.non_zero_dpp_x.append(twiss_file_x) files_dict['getNDx.out'].add_filename_to_getllm_header(file_x) files_dict['getDx.out'].add_filename_to_getllm_header(file_x) # y file if file_in.endswith(".gz"): file_y = file_in.replace(".gz", suffix_y + ".gz") else: file_y = file_in + suffix_y if not os.path.exists(file_y): file_y = file_in + '.liny' twiss_file_y = None try: twiss_file_y = Python_Classes4MAD.metaclass.twiss(file_y) if twiss_file_y.has_no_bpm_data(): print >> sys.stderr, "Ignoring empty file:", twiss_file_y.filename twiss_file_y = None except IOError: print 'Warning: There seems no ' + str(file_y) + ' file in the specified directory.' except ValueError: pass # Information printed by metaclass already if None != twiss_file_y: if use_average: twiss_file_y.MUY = twiss_file_y.AVG_MUY if calibration_twiss is not None: twiss_file_y.AMPY, twiss_file_y.ERRAMPY, twiss_file_y.CALIBRATION, twiss_file_y.ERROR_CALIBRATION, twiss_file_y.NATURAL_TUNE, twiss_file_y.NATURAL_TUNE_RMS, twiss_file_y.TUNE, twiss_file_y.TUNE_RMS = _get_calibrated_amplitudes(twiss_file_y, calibration_twiss, "Y") try: dppi = getattr(twiss_file_y, "DPP", 0.0) except AttributeError: dppi = 0.0 if type(dppi) != float: print >> sys.stderr, 'Warning: DPP may not be given as a number in ', file_y, '...trying to forcibly cast it as a number' try: dppi = float(dppi) print 'dppi= ', dppi except ValueError: print >> sys.stderr, 'but failing. DPP in ', file_y, ' is something wrong. String? --- leaving GetLLM' print >> sys.stderr, traceback.format_exc() sys.exit(1) if dppi == 0.0: twiss_d.zero_dpp_y.append(twiss_file_y) files_dict['getphasey.out'].add_filename_to_getllm_header(file_y) files_dict['getphasetoty.out'].add_filename_to_getllm_header(file_y) files_dict['getbetay.out'].add_filename_to_getllm_header(file_y) files_dict['getampbetay.out'].add_filename_to_getllm_header(file_y) files_dict['getCOy.out'].add_filename_to_getllm_header(file_y) files_dict['getDy.out'].add_filename_to_getllm_header(file_y) if getllm_d.with_ac_calc: files_dict['getphasey_free.out'].add_filename_to_getllm_header(file_y) files_dict['getphasey_free2.out'].add_filename_to_getllm_header(file_y) files_dict['getphasetoty_free.out'].add_filename_to_getllm_header(file_y) files_dict['getphasetoty_free2.out'].add_filename_to_getllm_header(file_y) files_dict['getbetay_free.out'].add_filename_to_getllm_header(file_y) files_dict['getbetay_free2.out'].add_filename_to_getllm_header(file_y) files_dict['getampbetay_free.out'].add_filename_to_getllm_header(file_y) files_dict['getampbetay_free2.out'].add_filename_to_getllm_header(file_y) else: twiss_d.non_zero_dpp_y.append(twiss_file_y) files_dict['getDy.out'].add_filename_to_getllm_header(file_y) if not twiss_d.has_zero_dpp_x(): print 'Warning: you are running GetLLM without "linx of dp/p=0". Are you sure?' if twiss_d.has_non_zero_dpp_x(): twiss_d.zero_dpp_x = twiss_d.non_zero_dpp_x twiss_d.zero_dpp_y = twiss_d.non_zero_dpp_y twiss_d.non_zero_dpp_x = [] twiss_d.non_zero_dpp_y = [] print "Previous warning suppressed, running in chromatic mode" files_dict['getphasex.out'].add_filename_to_getllm_header("chrommode") files_dict['getbetax.out'].add_filename_to_getllm_header("chrommode") files_dict['getampbetax.out'].add_filename_to_getllm_header("chrommode") files_dict['getCOx.out'].add_filename_to_getllm_header("chrommode") files_dict['getNDx.out'].add_filename_to_getllm_header("chrommode") files_dict['getDx.out'].add_filename_to_getllm_header("chrommode") files_dict['getcouple.out'].add_filename_to_getllm_header("chrommode") if getllm_d.with_ac_calc: files_dict['getcouple_free.out'].add_filename_to_getllm_header("chrommode") files_dict['getcouple_free2.out'].add_filename_to_getllm_header("chrommode") files_dict['getphasey.out'].add_filename_to_getllm_header("chrommode") files_dict['getbetay.out'].add_filename_to_getllm_header("chrommode") files_dict['getampbetay.out'].add_filename_to_getllm_header("chrommode") files_dict['getCOx.out'].add_filename_to_getllm_header("chrommode") files_dict['getDy.out'].add_filename_to_getllm_header("chrommode") if twiss_d.has_no_input_files(): print >> sys.stderr, "No parsed input files" sys.exit(1) return twiss_d, files_dict # END _analyse_src_files ---------------------------------------------------------------------------- def _check_bpm_compatibility(twiss_d, mad_twiss): ''' Checks the monitor compatibility between data and model. If a monitor will not be found in the model, a message will be print to sys.stderr. ''' all_twiss_files = twiss_d.non_zero_dpp_x + twiss_d.zero_dpp_x + twiss_d.non_zero_dpp_y + twiss_d.zero_dpp_y for twiss_file in all_twiss_files: for bpm_name in twiss_file.NAME: try: mad_twiss.NAME[mad_twiss.indx[bpm_name]] except KeyError: try: mad_twiss.NAME[mad_twiss.indx[str.upper(bpm_name)]] except KeyError: print >> sys.stderr, 'Monitor ' + bpm_name + ' cannot be found in the model!' def _calculate_orbit(getllm_d, twiss_d, tune_d, mad_twiss, files_dict): ''' Calculates orbit and fills the following TfsFiles: - getCOx.out - getCOy.out - getCOx_dpp_' + str(k + 1) + '.out - getCOy_dpp_' + str(k + 1) + '.out :param _GetllmData getllm_d: accel is used(In-param, values will only be read) :param _TwissData twiss_d: Holds twiss instances of the src files. (In-param, values will only be read) :param _TuneData tune_d: Holds tunes and phase advances (In-param, values will only be read) :returns: (list, list, dict) - an list of dictionairies from horizontal computations - an list of dictionairies from vertical computations - the same dict as param files_dict to indicate that dict will be extended here. ''' print 'Calculating orbit' list_of_co_x = [] if twiss_d.has_zero_dpp_x(): [cox, bpms] = algorithms.helper.calculate_orbit(mad_twiss, twiss_d.zero_dpp_x) # The output file can be directly used for orbit correction with MADX tfs_file = files_dict['getCOx.out'] tfs_file.add_string_descriptor("TABLE", 'ORBIT') tfs_file.add_string_descriptor("TYPE", 'ORBIT') tfs_file.add_string_descriptor("SEQUENCE", getllm_d.accel) tfs_file.add_float_descriptor("Q1", tune_d.q1) tfs_file.add_float_descriptor("Q2", tune_d.q2) tfs_file.add_column_names(["NAME", "S", "COUNT", "X", "STDX", "XMDL", "MUXMDL"]) tfs_file.add_column_datatypes(["%s", "%le", "%le", "%le", "%le", "%le", "%le"]) for i in range(0, len(bpms)): bn1 = str.upper(bpms[i][1]) bns1 = bpms[i][0] list_row_entries = ['"' + bn1 + '"', bns1, len(twiss_d.zero_dpp_x), cox[bn1][0], cox[bn1][1], mad_twiss.X[mad_twiss.indx[bn1]], mad_twiss.MUX[mad_twiss.indx[bn1]]] tfs_file.add_table_row(list_row_entries) list_of_co_x.append(cox) list_of_co_y = [] if twiss_d.has_zero_dpp_y(): [coy, bpms] = algorithms.helper.calculate_orbit(mad_twiss, twiss_d.zero_dpp_y) # The output file can be directly used for orbit correction with MADX tfs_file = files_dict['getCOy.out'] tfs_file.add_string_descriptor("TABLE", 'ORBIT') tfs_file.add_string_descriptor("TYPE", 'ORBIT') tfs_file.add_string_descriptor("SEQUENCE", getllm_d.accel) tfs_file.add_float_descriptor("Q1", tune_d.q1) tfs_file.add_float_descriptor("Q2", tune_d.q2) tfs_file.add_column_names(["NAME", "S", "COUNT", "Y", "STDY", "YMDL", "MUYMDL"]) tfs_file.add_column_datatypes(["%s", "%le", "%le", "%le", "%le", "%le", "%le"]) for i in range(0, len(bpms)): bn1 = str.upper(bpms[i][1]) bns1 = bpms[i][0] list_row_entries = ['"' + bn1 + '"', bns1, len(twiss_d.zero_dpp_y), coy[bn1][0], coy[bn1][1], mad_twiss.Y[mad_twiss.indx[bn1]], mad_twiss.MUY[mad_twiss.indx[bn1]]] tfs_file.add_table_row(list_row_entries) list_of_co_y.append(coy) #-------- Orbit for non-zero DPP if twiss_d.has_non_zero_dpp_x(): k = 0 for twiss_file in twiss_d.non_zero_dpp_x: list_with_single_twiss = [] list_with_single_twiss.append(twiss_file) filename = 'getCOx_dpp_' + str(k + 1) + '.out' files_dict[filename] = GetllmTfsFile(filename) tfs_file = files_dict[filename] tfs_file.add_filename_to_getllm_header(twiss_file.filename) tfs_file.add_float_descriptor("DPP", float(twiss_file.DPP)) tfs_file.add_float_descriptor("Q1", tune_d.q1) tfs_file.add_float_descriptor("Q2", tune_d.q2) [codpp, bpms] = algorithms.helper.calculate_orbit(mad_twiss, list_with_single_twiss) tfs_file.add_column_names(["NAME", "S", "COUNT", "X", "STDX", "XMDL", "MUXMDL"]) tfs_file.add_column_datatypes(["%s", "%le", "%le", "%le", "%le", "%le", "%le"]) for i in range(0, len(bpms)): bn1 = str.upper(bpms[i][1]) bns1 = bpms[i][0] list_row_entries = ['"' + bn1 + '"', bns1, len(twiss_d.zero_dpp_x), codpp[bn1][0], codpp[bn1][1], mad_twiss.X[mad_twiss.indx[bn1]], mad_twiss.MUX[mad_twiss.indx[bn1]]] tfs_file.add_table_row(list_row_entries) list_of_co_x.append(codpp) k += 1 if twiss_d.has_non_zero_dpp_y(): k = 0 for twiss_file in twiss_d.non_zero_dpp_y: list_with_single_twiss = [] list_with_single_twiss.append(twiss_file) filename = 'getCOy_dpp_' + str(k + 1) + '.out' files_dict[filename] = GetllmTfsFile(filename) tfs_file = files_dict[filename] tfs_file.add_filename_to_getllm_header(twiss_file.filename) tfs_file.add_float_descriptor("DPP", float(twiss_file.DPP)) tfs_file.add_float_descriptor("Q1", tune_d.q1) tfs_file.add_float_descriptor("Q2", tune_d.q2) [codpp, bpms] = algorithms.helper.calculate_orbit(mad_twiss, list_with_single_twiss) tfs_file.add_column_names(["NAME", "S", "COUNT", "Y", "STDY", "YMDL", "MUYMDL"]) tfs_file.add_column_datatypes(["%s", "%le", "%le", "%le", "%le", "%le", "%le"]) for i in range(0, len(bpms)): bn1 = str.upper(bpms[i][1]) bns1 = bpms[i][0] #TODO: why twiss_d.zero_dpp_y.. above used twiss_d.non_zero_dpp_y(vimaier) list_row_entries = ['"' + bn1 + '"', bns1, len(twiss_d.zero_dpp_y), codpp[bn1][0], codpp[bn1][1], mad_twiss.Y[mad_twiss.indx[bn1]], mad_twiss.MUY[mad_twiss.indx[bn1]]] tfs_file.add_table_row(list_row_entries) list_of_co_y.append(codpp) k += 1 return list_of_co_x, list_of_co_y, files_dict # END _calculate_orbit ------------------------------------------------------------------------------ def _calculate_getsextupoles(twiss_d, phase_d, mad_twiss, files_dict, q1f): ''' Fills the following TfsFiles: - getsex3000.out :returns: dict string --> GetllmTfsFile -- The same instace of files_dict to indicate that the dict was extended. ''' print "Calculating getsextupoles" # For getsex1200.out andgetsex2100.out take a look at older revisions. (vimaier) htot, afactor, pfactor = algorithms.helper.Getsextupole(mad_twiss, twiss_d.zero_dpp_x, phase_d.ph_x, q1f, 3, 0) tfs_file = files_dict["getsex3000.out"] tfs_file.add_float_descriptor("f2h_factor", afactor) tfs_file.add_float_descriptor("p_f2h_factor", pfactor) tfs_file.add_column_names(["NAME", "S", "AMP_20", "AMP_20std", "PHASE_20", "PHASE_20std", "f3000", "f3000std", "phase_f_3000", "phase_f_3000std", "h3000", "h3000_std", "phase_h_3000", "phase_h_3000_std"]) tfs_file.add_column_datatypes(["%s", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le"]) for bpm_key in htot: li = htot[bpm_key] list_row_entries = [li[0], li[1], li[2], li[3], li[4], li[5], li[6], li[7], li[8], li[9], li[10], li[11], li[12], li[13]] tfs_file.add_table_row(list_row_entries) return files_dict # END _calculate_getsextupoles ---------------------------------------------------------------------- def _calculate_kick(kick_times, getllm_d, twiss_d, phase_d, beta_d, mad_twiss, mad_ac, files_dict, bbthreshold, errthreshold): ''' Fills the following TfsFiles: - getkick.out - getkickac.out :returns: dict string --> GetllmTfsFile -- The same instace of files_dict to indicate that the dict was extended ''' print "Calculating kick" files = [twiss_d.zero_dpp_x + twiss_d.non_zero_dpp_x, twiss_d.zero_dpp_y + twiss_d.non_zero_dpp_y] meansqrt_2jx = {} meansqrt_2jy = {} bpmrejx = {} bpmrejy = {} [tunes, dpp] = algorithms.compensate_ac_effect.get_tunes(files) action_data_ac_dipole_phase_x,action_data_ac_dipole_model_x = algorithms.get_action.get_action(mad_twiss,beta_d.x_phase, twiss_d.zero_dpp_x + twiss_d.non_zero_dpp_x, "H",getllm_d.beam_direction,getllm_d.accel) action_data_ac_dipole_phase_y,action_data_ac_dipole_model_y = algorithms.get_action.get_action(mad_twiss,beta_d.y_phase, twiss_d.zero_dpp_y + twiss_d.non_zero_dpp_y, "V",getllm_d.beam_direction,getllm_d.accel) tfs_file_model = files_dict['getkick.out'] tfs_file_model.add_comment("Calculates the kick from the model beta function") column_names_list = ["TIME", "DPP", "QX", "QXRMS", "QY", "QYRMS", "NATQX", "NATQXRMS", "NATQY", "NATQYRMS", "sqrt2JX", "sqrt2JXSTD", "sqrt2JY", "sqrt2JYSTD", "2JX", "2JXSTD", "2JY", "2JYSTD"] column_types_list = ["%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le"] tfs_file_model.add_column_names(column_names_list) tfs_file_model.add_column_datatypes(column_types_list) for i in range(0, len(action_data_ac_dipole_model_x[0])): list_row_entries = [kick_times[i], dpp[i], tunes[0][i], tunes[1][i], tunes[2][i], tunes[3][i], tunes[4][i], tunes[5][i], tunes[6][i], tunes[7][i], action_data_ac_dipole_model_x[0][i]**0.5, 0.5*action_data_ac_dipole_model_x[1][i]/action_data_ac_dipole_model_x[0][i]**0.5, action_data_ac_dipole_model_y[0][i]**0.5, 0.5*action_data_ac_dipole_model_y[0][i]/action_data_ac_dipole_model_y[0][i]**0.5, action_data_ac_dipole_model_x[0][i], action_data_ac_dipole_model_x[1][i], action_data_ac_dipole_model_y[0][i], action_data_ac_dipole_model_y[1][i]] tfs_file_model.add_table_row(list_row_entries) actions_x, actions_y = action_data_ac_dipole_phase_x,action_data_ac_dipole_phase_y tfs_file_phase = files_dict['getkickphase.out'] tfs_file_phase.add_float_descriptor("Threshold_for_abs(beta_d-beta_m)/beta_m", bbthreshold) tfs_file_phase.add_float_descriptor("Threshold_for_uncert(beta_d)/beta_d", errthreshold) tfs_file_phase.add_column_names(column_names_list) tfs_file_phase.add_column_datatypes(column_types_list) for i in range(0, len(dpp)): list_row_entries = [kick_times[i], dpp[i], tunes[0][i], tunes[1][i], tunes[2][i], tunes[3][i], tunes[4][i], tunes[5][i], tunes[6][i], tunes[7][i], action_data_ac_dipole_phase_x[0][i]**0.5, 0.5*action_data_ac_dipole_phase_x[1][i]/action_data_ac_dipole_phase_x[0][i]**0.5, action_data_ac_dipole_phase_y[0][i]**0.5, 0.5*action_data_ac_dipole_phase_y[0][i]/action_data_ac_dipole_phase_y[0][i]**0.5, action_data_ac_dipole_phase_x[0][i], action_data_ac_dipole_phase_x[1][i], action_data_ac_dipole_phase_y[0][i], action_data_ac_dipole_phase_y[1][i]] tfs_file_phase.add_table_row(list_row_entries) if getllm_d.with_ac_calc: action_data_ac_dipole_phase_x,action_data_ac_dipole_model_x = algorithms.get_action.get_action(mad_ac,beta_d.x_phase_f, twiss_d.zero_dpp_x + twiss_d.non_zero_dpp_x, "H",getllm_d.beam_direction,getllm_d.accel) action_data_ac_dipole_phase_y,action_data_ac_dipole_model_y = algorithms.get_action.get_action(mad_ac,beta_d.y_phase_f, twiss_d.zero_dpp_y + twiss_d.non_zero_dpp_y, "V",getllm_d.beam_direction,getllm_d.accel) tfs_file = files_dict['getkickac.out'] tfs_file.add_float_descriptor("RescalingFactor_for_X", beta_d.x_ratio_f) tfs_file.add_float_descriptor("RescalingFactor_for_Y", beta_d.y_ratio_f) tfs_file.add_column_names(column_names_list + ["sqrt2JXMOD", "sqrt2JXSTDMOD", "sqrt2JYMOD", "sqrt2JYSTDMOD", "2JXMOD", "2JXSTDMOD", "2JYMOD", "2JYSTDMOD"]) tfs_file.add_column_datatypes(column_types_list + ["%le", "%le", "%le", "%le", "%le", "%le", "%le", "%le"]) [tunes, dpp] = algorithms.compensate_ac_effect.get_tunes(files) for i in range(0, len(dpp)): #TODO: in table will be the ratio without f(beta_d.x_ratio) used but rescaling factor is f version(beta_d.x_ratio_f). Check it (vimaier) list_row_entries = [kick_times[i], dpp[i], tunes[0][i], tunes[1][i], tunes[2][i], tunes[3][i], tunes[4][i], tunes[5][i], tunes[6][i], tunes[7][i], action_data_ac_dipole_phase_x[0][i]**0.5, 0.5*action_data_ac_dipole_phase_x[1][i]/action_data_ac_dipole_phase_x[0][i]**0.5, action_data_ac_dipole_phase_y[0][i]**0.5, 0.5*action_data_ac_dipole_phase_y[0][i]/action_data_ac_dipole_phase_y[0][i]**0.5, action_data_ac_dipole_phase_x[0][i], action_data_ac_dipole_phase_x[1][i], action_data_ac_dipole_model_y[0][i], action_data_ac_dipole_model_y[1][i], action_data_ac_dipole_model_x[0][i]**0.5, 0.5*action_data_ac_dipole_model_x[1][i]/action_data_ac_dipole_model_x[0][i]**0.5, action_data_ac_dipole_model_y[0][i]**0.5, 0.5*action_data_ac_dipole_model_y[0][i]/action_data_ac_dipole_model_y[0][i]**0.5, action_data_ac_dipole_model_x[0][i], action_data_ac_dipole_model_x[1][i], action_data_ac_dipole_model_y[0][i], action_data_ac_dipole_model_y[1][i]] tfs_file.add_table_row(list_row_entries) actions_x, actions_y = action_data_ac_dipole_phase_x,action_data_ac_dipole_phase_y return files_dict, actions_x, actions_y # END _calculate_kick ------------------------------------------------------------------------------- def _get_calibrated_amplitudes(drive_file, calibration_twiss, plane): calibration_file = calibration_twiss[plane] cal_amplitudes = [] err_cal_amplitudes = [] calibration_value = [] calibration_error = [] if plane == "X": tune = "Q1" tune_rms = "Q1RMS" natural_tune = "NATQ1" natural_tune_rms = "NATQ1RMS" elif plane == "Y": tune = "Q2" tune_rms = "Q2RMS" natural_tune = "NATQ2" natural_tune_rms = "NATQ2RMS" tune_value = getattr(drive_file,tune) tune_value_rms = getattr(drive_file,tune_rms) natural_tune_value = getattr(drive_file,natural_tune_rms) natural_tune_value_rms = getattr(drive_file,natural_tune_rms) for bpm_name in drive_file.NAME: drive_index = drive_file.indx[bpm_name] cal_amplitude = getattr(drive_file, "AMP" + plane)[drive_index] err_cal_amplitude = 0. if bpm_name in calibration_file.NAME: cal_index = calibration_file.indx[bpm_name] cal_amplitude = cal_amplitude * calibration_file.CALIBRATION[cal_index] err_cal_amplitude = cal_amplitude * calibration_file.ERROR_CALIBRATION[cal_index] calibration_value.append(calibration_file.CALIBRATION[cal_index]) calibration_error.append(calibration_file.ERROR_CALIBRATION[cal_index]) else: calibration_value.append(1.) calibration_error.append(0.) cal_amplitudes.append(cal_amplitude) err_cal_amplitudes.append(err_cal_amplitude) return array(cal_amplitudes), array(err_cal_amplitudes),array(calibration_value),array(calibration_error),array(natural_tune_value),array(natural_tune_value_rms),array(tune_value),array(tune_value_rms) # END _get_calibrated_amplitudes -------------------------------------------------------------------- def _copy_calibration_files(output_path, calibration_dir_path): calibration_twiss = {} if calibration_dir_path is not None: original_cal_file_path_x = os.path.join(calibration_dir_path, "calibration_x.out") original_cal_file_path_y = os.path.join(calibration_dir_path, "calibration_y.out") cal_file_path_x = os.path.join(output_path, "calibration_x.out") cal_file_path_y = os.path.join(output_path, "calibration_y.out") utils.iotools.copy_item(original_cal_file_path_x, cal_file_path_x) utils.iotools.copy_item(original_cal_file_path_y, cal_file_path_y) calibration_twiss["X"] = Python_Classes4MAD.metaclass.twiss(cal_file_path_x) calibration_twiss["Y"] = Python_Classes4MAD.metaclass.twiss(cal_file_path_y) return calibration_twiss else: return None # END _copy_calibration_files -------------------------------------------------------------------- #=================================================================================================== # helper classes for data structures #=================================================================================================== class _GetllmData(object): ''' Holds some data from parameters of main function. ''' def __init__(self): '''Constructor''' self.outputpath = "" self.list_of_input_files = [] self.accel = "" self.beam_direction = 0 self.lhc_phase = "" self.bpm_unit = "" self.cut_for_closed_orbit = 0 self.num_bpms_for_coupling = 0 self.use_only_three_bpms_for_beta_from_phase = True self.number_of_bpms = 0 self.range_of_bpms = 0 self.errordefspath = "" self.parallel = False self.nprocesses = 1 self.onlycoupling = 0 self.with_ac_calc = False self.acdipole = "None" self.important_pairs = {} def set_outputpath(self, outputpath): ''' Sets the outputpath and creates directories if they not exist. :param string outputpath: Path to output dir. If dir(s) to output do(es) not exist, it/they will be created. ''' utils.iotools.create_dirs(outputpath) self.outputpath = outputpath def set_bpmu_and_cut_for_closed_orbit(self, cut_co, bpm_unit): ''' Calculates and sets the cut and bpm unit. :param int cut_co: Cut in um(micrometer). :param string bpm_unit: Indicates used unit. um, mm, cm or m ''' self.bpm_unit = bpm_unit if bpm_unit == 'um': self.cut_for_closed_orbit = cut_co elif bpm_unit == 'mm': self.cut_for_closed_orbit = cut_co / 1.0e3 elif bpm_unit == 'cm': self.cut_for_closed_orbit = cut_co / 1.0e4 elif bpm_unit == 'm': self.cut_for_closed_orbit = cut_co / 1.0e6 else: print >> sys.stderr, "Wrong BPM unit:", bpm_unit class _TwissData(object): ''' Holds twiss instances of all src files. ''' def __init__(self): '''Constructor''' self.zero_dpp_x = [] # List of src files which have dpp==0.0 self.non_zero_dpp_x = [] # List of src files which have dpp!=0.0 self.zero_dpp_y = [] # List of src files which have dpp==0.0 self.non_zero_dpp_y = [] # List of src files which have dpp!=0.0 def has_zero_dpp_x(self): ''' Returns True if _linx file(s) exist(s) with dpp==0 ''' return 0 != len(self.zero_dpp_x) def has_non_zero_dpp_x(self): ''' Returns True if _linx file(s) exist(s) with dpp!=0 ''' return 0 != len(self.non_zero_dpp_x) def has_zero_dpp_y(self): ''' Returns True if _liny file(s) exist(s) with dpp==0 ''' return 0 != len(self.zero_dpp_y) def has_non_zero_dpp_y(self): ''' Returns True if _liny file(s) exist(s) with dpp!=0 ''' return 0 != len(self.non_zero_dpp_y) def has_no_input_files(self): return not self.has_zero_dpp_x() and not self.has_zero_dpp_y() and not self.has_non_zero_dpp_x() and not self.has_non_zero_dpp_y() class _TuneData(object): ''' Used as data structure to hold tunes and phase advances. ''' def __init__(self): '''Constructor''' self.q1 = 0.0 # Driven horizontal tune self.q2 = 0.0 # Driven vertical tune self.mux = 0.0 # Driven horizontal phase advance self.muy = 0.0 # Driven vertical phase advance # Free is from analytic equation self.q1f = 0.0 # Free horizontal tune self.q2f = 0.0 # Free vertical tune self.muxf = 0.0 # Free horizontal phase advance self.muyf = 0.0 # Free vertical phase advance # Free2 is using the effective model self.muxf2 = 0.0 # Free2 horizontal phase advance self.muyf2 = 0.0 # Free2 vertical phase advance self.delta1 = None # Used later to calculate free Q1. Only if with ac calculation. self.delta2 = None # Used later to calculate free Q2. Only if with ac calculation. def initialize_tunes(self, with_ac_calc, mad_twiss, mad_ac, twiss_d): ''' Calculates and sets the initial tunes. ''' if with_ac_calc: # Get fractional part: frac(62.23) = 0.23; 62.23 % 1 ==> 0.23 (vimaier) self.q1f = abs(mad_twiss.Q1) % 1 # -- Free Q1 (tempolarlly, overwritten later) self.q2f = abs(mad_twiss.Q2) % 1 # -- Free Q2 (tempolarlly, overwritten later) self.q1 = abs(mad_ac.Q1) % 1 # -- Drive Q1 (tempolarlly, overwritten later) self.q2 = abs(mad_ac.Q2) % 1 # -- Drive Q2 (tempolarlly, overwritten later) self.delta1 = self.q1 - self.q1f # -- Used later to calculate free Q1 self.delta2 = self.q2 - self.q2f # -- Used later to calculate free Q2 else: try: self.q1f = twiss_d.zero_dpp_x[0].Q1 self.q2f = twiss_d.zero_dpp_y[0].Q2 except IndexError: pass def _disable_these_loggers(): # Disable logging_tools.getLogger('tfs_files.tfs_file_writer').setLevel(logging_tools.ERROR) #=================================================================================================== # main invocation #=================================================================================================== def _start(): ''' Starter function to avoid polluting global namespace with variables options,args. Before the following code was after 'if __name__=="__main__":' ''' options = _parse_args() main(outputpath=options.output, dict_file=options.dict, files_to_analyse=options.files, model_filename=options.Twiss, accel=options.ACCEL, lhcphase=options.lhcphase, bpmu=options.BPMUNIT, cocut=float(options.COcut), nbcpl=int(options.NBcpl), nonlinear=options.nonlinear, tbtana=options.TBTana, bbthreshold=options.bbthreshold, errthreshold=options.errthreshold, use_only_three_bpms_for_beta_from_phase=options.use_only_three_bpms_for_beta_from_phase, number_of_bpms=options.number_of_bpms, range_of_bpms=options.range_of_bpms, use_average=options.use_average, calibration_dir_path=options.calibration_dir_path, errordefspath=options.errordefspath, nprocesses=options.nprocesses, onlycoupling=options.onlycoupling, use_error_of_mean=options.use_error_of_mean) if __name__ == "__main__": # This is to enable debug to GetLLM.log file only if sys.flags.debug is True with logging_tools.DebugMode(active=sys.flags.debug, log_file="GetLLM.log",add_date_to_fname=False) as dm: if dm.active: #disable DEBUG level on the console (== INFO and above to console) dm.console_h.setLevel(logging_tools.INFO) LOGGER.debug("The command: %s ", sys.argv) _disable_these_loggers() _start()