<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
This module defines all kinds of magnet components/elements.

Author      : <NAME>
Created     : 2016-03-22
Last updated: 2016-03-24
"""

import json

import epics
import matplotlib.patches as patches
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.path import Path


class MagBlock(object):
    objcnt = 0  # object counter
    comminfo = {}  # common information
    __styleconfig_dict = {
        'quad':
            {'h': 1.00, 'color': 'red', 'alpha': 0.50},
        'bend':
            {'h': 0.5, 'color': 'blue', 'alpha': 0.50},
        'drift':
            {'linewidth': 2, 'color': 'black', 'alpha': 0.75},
    }  # global configuration for element style, dict
    __styleconfig_json = json.dumps(__styleconfig_dict)

    def __init__(self, name=None):
        MagBlock.objcnt += 1
        self._name = name     # element name
        self.typename = None  # element type name
        self.comminfo = {k: v for k, v in MagBlock.comminfo.items()}  # common information

        self.simuinfo = {}  # simulation information
        self.ctrlinfo = {}  # control information
        self.miscinfo = {}  # other information

        self.simukeys = []  # keywords of simulation information
        self.ctrlkeys = []  # keywords of control information
        self.misckeys = []  # keywords of other information
        self.transfun = None  # unit translation function

        self.setConfDict = {'simu': self._setSimuConf,
                            'ctrl': self._setCtrlConf,
                            'misc': self._setMiscConf}

        self.prtConfigDict = {'simu': self._printSimuConf,
                              'ctrl': self._printCtrlConf,
                              'misc': self._printMiscConf,
                              'comm': self._printCommConf,
                              'all': self._printAllConf}

        self.dumpConfigDict = {'simu': self._dumpSimuConf,
                               'ctrl': self._dumpCtrlConf,
                               'misc': self._dumpMiscConf,
                               'comm': self._dumpCommConf,
                               'all': self._dumpAllConf,
                               'online': self._dumpOnlineConf}

        self.styledict = {}  # style dict
        self._patches = []   # patches list, empty
        self.next_inc_angle = 0  # for visualization, initial incremental angle

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name

    @staticmethod
    def rot(input, theta=0, pc=(0, 0)):
        """ rotate input array with angle of theta
            :param input: input array or list,
                e.g. np.array([[0,0],[0,1],[0,2]]) or [[0,0],[0,1],[0,2]]
            :param theta: rotation angle in degree
            :param pc: central point coords (x,y) regarding to rotation
            :return: rotated numpy array
        """
        if not isinstance(input, np.ndarray):
            input = np.array(input)

        if not isinstance(pc, np.ndarray):
            pc = np.array(pc)

        theta = theta/180.0*np.pi  # degree to rad
        mr = np.array([
                [np.cos(theta), -np.sin(theta)],
                [np.sin(theta),  np.cos(theta)],
                ])
        return np.dot(mr, (input-pc).transpose()).transpose() + pc.transpose()

    @staticmethod
    def sumObjNum():
        return MagBlock.objcnt

    @staticmethod
    def setCommInfo(infostr):
        """ set common information, to dict: info
            input parameter:
            :param infostr:
                1 infostr is a dict
                2 infostr with format like: "k1=v1, k2=v2"
        """
        if isinstance(infostr, dict):
            for k, v in infostr.items():
                MagBlock.comminfo[k] = v
        elif isinstance(infostr, str):
            for k, v in MagBlock.str2dict(infostr).items():
                MagBlock.comminfo[k] = v
        else:
            print("Information string ERROR.")

    @staticmethod
    def str2dict(istr):
        if 'lattice' not in istr.lower():
            tmpstr = istr.replace(',', '=').split('=')
        else:
            tmpstr = istr.split('=')
        k = [i.strip() for i in tmpstr[0::2]]
        v = [i.strip() for i in tmpstr[1::2]]
        return dict(zip(k, v))

    @staticmethod
    def setStyleConfig(config=None, help=False):
        """ set/update global style configurations for magblock elements
            update Magblock._styleconfig_dict and _styleconfig_json
        :param config: configuration dict or json
        :param help: if True, print help information, default is False
        :return: new style config dict
        """
        if help:
            print("The input configuration string should be with the format like:")
            print(MagBlock._MagBlock__styleconfig_json)
            print("with all or part of new properties, e.g.")
            print(json.dumps({'quad': {'color': 'blue'}}))
        else:
            if config is None:
                config = MagBlock._MagBlock__styleconfig_dict
            if isinstance(config, dict):
                for k in set(config.keys()) & set(MagBlock._MagBlock__styleconfig_dict.keys()):
                    for k1 in set(config[k].keys()) & set(MagBlock._MagBlock__styleconfig_dict[k].keys()):
                        MagBlock._MagBlock__styleconfig_dict[k][k1] = config[k][k1]
                MagBlock._MagBlock__styleconfig_json = json.dumps(MagBlock._MagBlock__styleconfig_dict)
            elif isinstance(config, str):
                config = json.loads(config)
                for k in set(config.keys()) & set(MagBlock._MagBlock__styleconfig_dict.keys()):
                    for k1 in set(config[k].keys()) & set(MagBlock._MagBlock__styleconfig_dict[k].keys()):
                        MagBlock._MagBlock__styleconfig_dict[k][k1] = config[k][k1]
                MagBlock._MagBlock__styleconfig_json = json.dumps(MagBlock._MagBlock__styleconfig_dict)
            else:
                print("Information string ERROR.")

            return MagBlock._MagBlock__styleconfig_dict

    def setConf(self, conf, type='simu'):
        """ set information for different type dict,
            :param conf: configuration information, str or dict
            :param type: simu, ctrl, misc
        """
        if conf is None:
            return
        else:
            if isinstance(conf, str):
                conf = MagBlock.str2dict(conf)
            self.setConfDict[type](conf)

    def setStyle(self, **style):
        """ set element style configuration
            :param style: dict of keys: 'color', 'h', 'alpha'
        """
        pass

    def setDraw(self, p0=(0, 0), angle=0):
        """ set element visualization drawing
        :param p0: start drawing point coords, (x, y)
        """
        self.next_p0 = p0

    def printConfig(self, type='simu'):
        """ print information about element
            :param type: comm, simu, ctrl, misc, all
        """
        print("{s1}{s2:^22s}{s1}".format(s1="-" * 10, s2="Configuration START"))
        print("class name: " + self.__class__.__name__)
        self.prtConfigDict[type]()
        print("{s1}{s2:^22s}{s1}".format(s1="-" * 10, s2="Configuration END"))

    def dumpConfig(self, type='online', format='elegant'):
        """ dump element configuration to given format,
            inpurt parameters:
            :param type: comm, simu, ctrl, misc, all, online (default)
            :param format: elegant/mad, elegant by default
        """
        return self.dumpConfigDict[type](format)

    def getConfig(self, type='online', format='elegant'):
        """ only dump configuration part, dict
            :param type: comm, simu, ctrl, misc, all, online (default)
            :param format: elegant/mad, elegant by default
        """
        return self.dumpConfigDict[type](format).values()[0].values()[0]

    def _setSimuConf(self, conf):
        self.simuinfo.update(conf)<commit_msg>change input paramter name of rot method<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
This module defines all kinds of magnet components/elements.

Author      : <NAME>
Created     : 2016-03-22
Last updated: 2016-03-24
"""

import json

import epics
import matplotlib.patches as patches
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.path import Path


class MagBlock(object):
    objcnt = 0  # object counter
    comminfo = {}  # common information
    __styleconfig_dict = {
        'quad':
            {'h': 1.00, 'color': 'red', 'alpha': 0.50},
        'bend':
            {'h': 0.5, 'color': 'blue', 'alpha': 0.50},
        'drift':
            {'linewidth': 2, 'color': 'black', 'alpha': 0.75},
    }  # global configuration for element style, dict
    __styleconfig_json = json.dumps(__styleconfig_dict)

    def __init__(self, name=None):
        MagBlock.objcnt += 1
        self._name = name     # element name
        self.typename = None  # element type name
        self.comminfo = {k: v for k, v in MagBlock.comminfo.items()}  # common information

        self.simuinfo = {}  # simulation information
        self.ctrlinfo = {}  # control information
        self.miscinfo = {}  # other information

        self.simukeys = []  # keywords of simulation information
        self.ctrlkeys = []  # keywords of control information
        self.misckeys = []  # keywords of other information
        self.transfun = None  # unit translation function

        self.setConfDict = {'simu': self._setSimuConf,
                            'ctrl': self._setCtrlConf,
                            'misc': self._setMiscConf}

        self.prtConfigDict = {'simu': self._printSimuConf,
                              'ctrl': self._printCtrlConf,
                              'misc': self._printMiscConf,
                              'comm': self._printCommConf,
                              'all': self._printAllConf}

        self.dumpConfigDict = {'simu': self._dumpSimuConf,
                               'ctrl': self._dumpCtrlConf,
                               'misc': self._dumpMiscConf,
                               'comm': self._dumpCommConf,
                               'all': self._dumpAllConf,
                               'online': self._dumpOnlineConf}

        self.styledict = {}  # style dict
        self._patches = []   # patches list, empty
        self.next_inc_angle = 0  # for visualization, initial incremental angle

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name

    @staticmethod
    def rot(inputArray, theta=0, pc=(0, 0)):
        """ rotate input array with angle of theta
            :param inputArray: input array or list,
                e.g. np.array([[0,0],[0,1],[0,2]]) or [[0,0],[0,1],[0,2]]
            :param theta: rotation angle in degree
            :param pc: central point coords (x,y) regarding to rotation
            :return: rotated numpy array
        """
        if not isinstance(inputArray, np.ndarray):
            inputArray = np.array(inputArray)

        if not isinstance(pc, np.ndarray):
            pc = np.array(pc)

        theta = theta/180.0*np.pi  # degree to rad
        mr = np.array([
                [np.cos(theta), -np.sin(theta)],
                [np.sin(theta),  np.cos(theta)],
                ])
        return np.dot(mr, (inputArray-pc).transpose()).transpose() + pc.transpose()

    @staticmethod
    def sumObjNum():
        return MagBlock.objcnt

    @staticmethod
    def setCommInfo(infostr):
        """ set common information, to dict: info
            input parameter:
            :param infostr:
                1 infostr is a dict
                2 infostr with format like: "k1=v1, k2=v2"
        """
        if isinstance(infostr, dict):
            for k, v in infostr.items():
                MagBlock.comminfo[k] = v
        elif isinstance(infostr, str):
            for k, v in MagBlock.str2dict(infostr).items():
                MagBlock.comminfo[k] = v
        else:
            print("Information string ERROR.")

    @staticmethod
    def str2dict(istr):
        if 'lattice' not in istr.lower():
            tmpstr = istr.replace(',', '=').split('=')
        else:
            tmpstr = istr.split('=')
        k = [i.strip() for i in tmpstr[0::2]]
        v = [i.strip() for i in tmpstr[1::2]]
        return dict(zip(k, v))

    @staticmethod
    def setStyleConfig(config=None, showhelp=False):
        """ set/update global style configurations for magblock elements
            update Magblock._styleconfig_dict and _styleconfig_json
        :param config: configuration dict or json
        :param showhelp: if True, print showhelp information, default is False
        :return: new style config dict
        """
        if showhelp:
            print("The input configuration string should be with the format like:")
            print(MagBlock._MagBlock__styleconfig_json)
            print("with all or part of new properties, e.g.")
            print(json.dumps({'quad': {'color': 'blue'}}))
        else:
            if config is None:
                config = MagBlock._MagBlock__styleconfig_dict
            if isinstance(config, dict):
                for k in set(config.keys()) & set(MagBlock._MagBlock__styleconfig_dict.keys()):
                    for k1 in set(config[k].keys()) & set(MagBlock._MagBlock__styleconfig_dict[k].keys()):
                        MagBlock._MagBlock__styleconfig_dict[k][k1] = config[k][k1]
                MagBlock._MagBlock__styleconfig_json = json.dumps(MagBlock._MagBlock__styleconfig_dict)
            elif isinstance(config, str):
                config = json.loads(config)
                for k in set(config.keys()) & set(MagBlock._MagBlock__styleconfig_dict.keys()):
                    for k1 in set(config[k].keys()) & set(MagBlock._MagBlock__styleconfig_dict[k].keys()):
                        MagBlock._MagBlock__styleconfig_dict[k][k1] = config[k][k1]
                MagBlock._MagBlock__styleconfig_json = json.dumps(MagBlock._MagBlock__styleconfig_dict)
            else:
                print("Information string ERROR.")

            return MagBlock._MagBlock__styleconfig_dict

    def setConf(self, conf, type='simu'):
        """ set information for different type dict,
            :param conf: configuration information, str or dict
            :param type: simu, ctrl, misc
        """
        if conf is None:
            return
        else:
            if isinstance(conf, str):
                conf = MagBlock.str2dict(conf)
            self.setConfDict[type](conf)

    def setStyle(self, **style):
        """ set element style configuration
            :param style: dict of keys: 'color', 'h', 'alpha'
        """
        pass

    def setDraw(self, p0=(0, 0), angle=0):
        """ set element visualization drawing
        :param angle: rotation angle
        :param p0: start drawing point coords, (x, y)
        """
        self.next_p0 = p0

    def printConfig(self, type='simu'):
        """ print information about element
            :param type: comm, simu, ctrl, misc, all
        """
        print("{s1}{s2:^22s}{s1}".format(s1="-" * 10, s2="Configuration START"))
        print("class name: " + self.__class__.__name__)
        self.prtConfigDict[type]()
        print("{s1}{s2:^22s}{s1}".format(s1="-" * 10, s2="Configuration END"))

    def dumpConfig(self, type='online', format='elegant'):
        """ dump element configuration to given format,
            inpurt parameters:
            :param type: comm, simu, ctrl, misc, all, online (default)
            :param format: elegant/mad, elegant by default
        """
        return self.dumpConfigDict[type](format)

    def getConfig(self, type='online', format='elegant'):
        """ only dump configuration part, dict
            :param type: comm, simu, ctrl, misc, all, online (default)
            :param format: elegant/mad, elegant by default
        """
        return self.dumpConfigDict[type](format).values()[0].values()[0]

    def _setSimuConf(self, conf):
        self.simuinfo.update(conf)
{'fraction_non_alphanumeric': 0.11786417322834646, 'fraction_numerical': 0.012303149606299213, 'mean_word_length': 1.9856749311294766, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '765138', 'n_tokens_mistral': 4752, 'n_tokens_neox': 4546, 'n_words': 1213}