# Path: sloth/utils/logging.py
# def getLogger(name, level='INFO'):
#     """Utility function to get the logger with customization
# 
#     .. warning:: NOT WORKING AS EXPECTED -> FIXME!!!
# 
#     Parameters
#     ----------
#     name : str
#         name of the logger
#     level : str (optional)
#         logging level ['INFO']
#     """
#     if not _log:
#         logging_basicConfig(level=level)
#     logger = logging.getLogger(name)
#     logger.setLevel(_levels[level])
# 
#     if (logger.hasHandlers()):
#         logger.handlers.clear()
#         logger.debug("custom logger setup > clear handlers")
#     logger.addHandler(getConsoleHandler())
#     """Clear existing handlers and add current one"""
# 
#     logger.propagate = False
#     logger.debug("custom logger setup > finished")
# 
#     return logger
# 
# Path: sloth/utils/bragg.py
# def bragg_ev(theta, d, n=1):
#     """return the Bragg energy (eV) for a given d-spacing (\AA) and angle (deg)"""
#     return wlen2ev((2 * d * np.sin(np.deg2rad(theta))) / n)
# 
# Path: sloth/raytracing/shadow_utils.py
# def get_src_hdiv(oe_xhw, oe_ydist):
#     """get source horizontal divergence
# 
#     :param oe_xhw: optical element X half width
#     :param oe_ydist: optical element distance from source
# 
#     """
#     return math.atan(oe_xhw / oe_ydist)
# 
# def get_src_vdiv(oe_yhw, oe_ydist, oe_th):
#     """get source vertical divergence
# 
#     :param oe_yhw: optical element Y half width
#     :param oe_ydist: optical element distance from source
#     :param oe_th: optical element grazing angle in degrees (e.g. Bragg angle)
# 
#     """
#     _rth = math.radians(oe_th)
#     _h = oe_yhw * math.sin(_rth)
#     _d = oe_ydist + oe_yhw * math.cos(_rth)
#     return math.atan(_h / _d)
# 
# def rotate_rays(rays, angle, axis):
#     """rotate rays
# 
#         Parameters
#         ----------
#         rays : array of floats
#             Shadow rays
#         angle : float
#             Rotation angle in degrees
#         axis : int
#             Rotation axis number (Shadow's column)
#             1: X, 2: Y, 3: Z
# 
#         Returns
#         -------
#         array
#             Rotated rays
#         """
#     a1 = rays.copy()
#     rangle = np.deg2rad(angle)
#     if axis == 1:
#         torot = [2, 3]
#     elif axis == 2:
#         torot = [1, 3]
#     elif axis == 3:
#         torot = [1, 2]
#     else:
#         raise NameError("Wrong axis")
#     costh = np.cos(rangle)
#     sinth = np.sin(rangle)
#     tstart = np.array([1, 4, 7, 16])
#     for i in range(len(tstart)):
#         newaxis = axis + tstart[i] - 1
#         newaxisi = newaxis - 1
#         newtorot = torot + tstart[i] - 1
#         newtoroti = newtorot - 1
#         rays[:, newtoroti[0]] = (
#             a1[:, newtoroti[0]] * costh + a1[:, newtoroti[1]] * sinth
#         )
#         rays[:, newtoroti[1]] = (
#             -a1[:, newtoroti[0]] * sinth + a1[:, newtoroti[1]] * costh
#         )
#         rays[:, newaxisi] = a1[:, newaxisi]
#     return rays


import math
    import Shadow
from sloth.utils.logging import getLogger
from sloth.utils.bragg import bragg_ev
from sloth.raytracing.shadow_utils import get_src_hdiv, get_src_vdiv, rotate_rays
        oe.X_ROT = move[3]
        oe.Y_ROT = move[4]
        oe.Z_ROT = move[5]
        if not src_rot:
            # adjust src divergence -> EMPIRICAL ADJUSTMENTS!!!
            hdiv1 = get_src_hdiv(1.05 * move[0] + aw / 2, p) + 7 * src_ovf
            hdiv2 = -1 * (get_src_hdiv(1.05 * move[0] - aw / 2, p) - 5 * src_ovf)
            vdiv1 = get_src_vdiv(2.5 * move[2] + ah / 2.0, p, theta0) + 5 * src_ovf
            vdiv2 = get_src_vdiv(0.5 * move[2] + ah / 2.0, p, theta0) + src_ovf
            src.HDIV1 = hdiv1
            src.HDIV2 = hdiv2
            src.VDIV1 = vdiv1
            src.VDIV2 = vdiv2
            # src.CONE_MAX = hdiv1
            # rotate source -> NOT WORKING!!!
        oe.FSTAT = 0
    if run:
        # Run SHADOW to create the source
        if iwrite:
            src.write("start.00")
        beam.genSource(src)
        if (move is not None) and src_rot:
            rays = beam.rays.copy()
            # rays_ry = rotate_rays(rays, move[4], 2)
            _rz = math.atan(move[0] / p)
            rz = math.degrees(_rz) * 0.5  # empirical factor to reduce!!!
            rays_rz = rotate_rays(rays, rz, 3)
            p1 = p / math.cos(_rz)
            _rx = math.atan(move[5] / p1)
            rx = -1 * math.degrees(_rx) * 0.9  # empirical factor to reduce!!!

# Path: sloth/utils/logging.py
# def getLogger(name, level='INFO'):
#     """Utility function to get the logger with customization
# 
#     .. warning:: NOT WORKING AS EXPECTED -> FIXME!!!
# 
#     Parameters
#     ----------
#     name : str
#         name of the logger
#     level : str (optional)
#         logging level ['INFO']
#     """
#     if not _log:
#         logging_basicConfig(level=level)
#     logger = logging.getLogger(name)
#     logger.setLevel(_levels[level])
# 
#     if (logger.hasHandlers()):
#         logger.handlers.clear()
#         logger.debug("custom logger setup > clear handlers")
#     logger.addHandler(getConsoleHandler())
#     """Clear existing handlers and add current one"""
# 
#     logger.propagate = False
#     logger.debug("custom logger setup > finished")
# 
#     return logger
# 
# Path: sloth/utils/bragg.py
# def bragg_ev(theta, d, n=1):
#     """return the Bragg energy (eV) for a given d-spacing (\AA) and angle (deg)"""
#     return wlen2ev((2 * d * np.sin(np.deg2rad(theta))) / n)
# 
# Path: sloth/raytracing/shadow_utils.py
# def get_src_hdiv(oe_xhw, oe_ydist):
#     """get source horizontal divergence
# 
#     :param oe_xhw: optical element X half width
#     :param oe_ydist: optical element distance from source
# 
#     """
#     return math.atan(oe_xhw / oe_ydist)
# 
# def get_src_vdiv(oe_yhw, oe_ydist, oe_th):
#     """get source vertical divergence
# 
#     :param oe_yhw: optical element Y half width
#     :param oe_ydist: optical element distance from source
#     :param oe_th: optical element grazing angle in degrees (e.g. Bragg angle)
# 
#     """
#     _rth = math.radians(oe_th)
#     _h = oe_yhw * math.sin(_rth)
#     _d = oe_ydist + oe_yhw * math.cos(_rth)
#     return math.atan(_h / _d)
# 
# def rotate_rays(rays, angle, axis):
#     """rotate rays
# 
#         Parameters
#         ----------
#         rays : array of floats
#             Shadow rays
#         angle : float
#             Rotation angle in degrees
#         axis : int
#             Rotation axis number (Shadow's column)
#             1: X, 2: Y, 3: Z
# 
#         Returns
#         -------
#         array
#             Rotated rays
#         """
#     a1 = rays.copy()
#     rangle = np.deg2rad(angle)
#     if axis == 1:
#         torot = [2, 3]
#     elif axis == 2:
#         torot = [1, 3]
#     elif axis == 3:
#         torot = [1, 2]
#     else:
#         raise NameError("Wrong axis")
#     costh = np.cos(rangle)
#     sinth = np.sin(rangle)
#     tstart = np.array([1, 4, 7, 16])
#     for i in range(len(tstart)):
#         newaxis = axis + tstart[i] - 1
#         newaxisi = newaxis - 1
#         newtorot = torot + tstart[i] - 1
#         newtoroti = newtorot - 1
#         rays[:, newtoroti[0]] = (
#             a1[:, newtoroti[0]] * costh + a1[:, newtoroti[1]] * sinth
#         )
#         rays[:, newtoroti[1]] = (
#             -a1[:, newtoroti[0]] * sinth + a1[:, newtoroti[1]] * costh
#         )
#         rays[:, newaxisi] = a1[:, newaxisi]
#     return rays


# Path: sloth/raytracing/shadow_jscyl.py
import math
    import Shadow
from sloth.utils.logging import getLogger
from sloth.utils.bragg import bragg_ev
from sloth.raytracing.shadow_utils import get_src_hdiv, get_src_vdiv, rotate_rays

        oe.X_ROT = move[3]
        oe.Y_ROT = move[4]
        oe.Z_ROT = move[5]
        if not src_rot:
            # adjust src divergence -> EMPIRICAL ADJUSTMENTS!!!
            hdiv1 = get_src_hdiv(1.05 * move[0] + aw / 2, p) + 7 * src_ovf
            hdiv2 = -1 * (get_src_hdiv(1.05 * move[0] - aw / 2, p) - 5 * src_ovf)
            vdiv1 = get_src_vdiv(2.5 * move[2] + ah / 2.0, p, theta0) + 5 * src_ovf
            vdiv2 = get_src_vdiv(0.5 * move[2] + ah / 2.0, p, theta0) + src_ovf
            src.HDIV1 = hdiv1
            src.HDIV2 = hdiv2
            src.VDIV1 = vdiv1
            src.VDIV2 = vdiv2
            # src.CONE_MAX = hdiv1
            # rotate source -> NOT WORKING!!!
        oe.FSTAT = 0
    if run:
        # Run SHADOW to create the source
        if iwrite:
            src.write("start.00")
        beam.genSource(src)
        if (move is not None) and src_rot:
            rays = beam.rays.copy()
            # rays_ry = rotate_rays(rays, move[4], 2)
            _rz = math.atan(move[0] / p)
            rz = math.degrees(_rz) * 0.5  # empirical factor to reduce!!!
            rays_rz = rotate_rays(rays, rz, 3)
            p1 = p / math.cos(_rz)
            _rx = math.atan(move[5] / p1)
            rx = -1 * math.degrees(_rx) * 0.9  # empirical factor to reduce!!!

            rays_rzrx = rotate_rays(rays_rz, rx, 1)