def reflection(xvals, p):
    #position=p[0];  intensity=p[1]; slit=p[2];  stth=p[3];  background=p[4];  thickness=p[5];  absorption=p[6]
    x0 = p[0]
    i0 = p[1]
    w = p[2]
    theta = p[3]
    ib = p[4]
    thick = p[5]
    u = p[6]
    th = np.deg2rad(theta)
    p0 = w * np.sin(th) / np.sin(2 * th)
    out = []
    for x in xvals:
        if x < (x0 - p0):
            val = ib
        elif ((x >= (x0 - p0)) and (x < x0)):
            val = i0 * ((x - x0 + p0) / u) - i0 * (np.sin(th) /
                                                   (2 * u * u)) * (1 - np.exp(
                                                       (-2 * u / np.sin(th)) *
                                                       (x - x0 + p0))) + ib
        elif ((x >= x0) and (x < (x0 + p0))):
            val = i0 * (np.sin(th) / (2 * u * u)) * (np.exp(
                (-2 * u / np.sin(th)) * (x - x0 + p0)) - 2 * np.exp(
                    (-2 * u / np.sin(th)) *
                    (x - x0)) + 1) + i0 * ((x0 + p0 - x) / u) + ib
        elif (x >= (x0 + p0)):
            val = i0 * np.sin(th) / (
                2 * u * u) * (np.exp(-2 * u * (x - x0 + p0) / np.sin(th)) -
                              2 * np.exp(-2 * u * (x - x0) / np.sin(th)) +
                              np.exp(-2 * u * (x - x0 - p0) / np.sin(th))) + ib
        out = out + [val]
    return np.array(out)
def wall(xvals, parms):
    #position=p[0];  intensity=p[1]; slit=p[2];  stth=p[3];  background=p[4];  thickness=p[5];  absorption=p[6]
    midpoint = parms[0]
    i0 = parms[1]
    w = parms[2]
    theta = parms[3]
    ib = parms[4]
    thick = parms[5]
    u = parms[6]
    midpoint = parms[0]
    x0 = midpoint - thick / 2.0
    th = np.deg2rad(theta)
    p = w * np.cos(th)
    Atot = w * w / np.sin(2.0 * th)
    out = []
    for x in xvals:
        if (x <= (x0 - p)):
            val = ib
        #elif ((x0-p) >= (x-thick)) and ((x0+p) >= x):         #Gauge volume is smaller than thickness
        if ((x > (x0 - p)) and (x0 - p > (x - thick)) and (x <= x0)):
            val = ib + i0 * ((x - (x0 - p)) * ((x -
                                                (x0 - p)) * np.tan(th))) / Atot
        elif ((x > x0) and (x <= x0 + p) and (x0 - p > (x - thick))):
            val = ib + i0 * (Atot - (x0 + p - x) *
                             (x0 + p - x) * np.tan(th)) / Atot
        elif (x0 - p > (x - thick)
              and (x0 + p < x)):  #Gauge volume is smaller than thickness
            val = ib + i0
        elif (x0 - p < (x - thick)
              and (x0 + p > x)):  #Gauge volume is larger than thickness
            A2 = (x0 + p - x) * (x0 + p - x) * np.tan(th)
            A3 = ((x - thick) - (x0 - p)) * (((x - thick) -
                                              (x0 - p)) * np.tan(th))
            val = ib + i0 * (Atot - A2 - A3) / Atot
        elif ((x0 - p) < (x - thick)) and ((x0 + p) < x) and (x0 >=
                                                              (x - thick)):
            A3 = ((x - thick) - (x0 - p)) * (((x - thick) -
                                              (x0 - p)) * np.tan(th))
            val = ib + i0 * (Atot - A3) / Atot
        elif (x0 < (x - thick) and ((x0 + p >= (x - thick)))):
            A2 = (x0 + p - (x - thick)) * ((x0 + p) - (x - thick)) * np.tan(th)
            val = ib + i0 * (A2 / Atot)
        elif (x0 + p < (x - thick)):
            val = ib

        #elif ((x0-p) < (x-thick)) and ((x0+p) >= x):         #Gauge volume is larger than thickness
        #    A2 = (x0+p-x)*(x0+p-x)*np.tan(th)
        #    A3 = ((x-thick)-(x0-p))*(((x-thick)-(x0-p))*np.tan(th))
        #    val = ib + i0*(Atot-A2-A3)/Atot

        out = out + [val]
    return np.array(out)
def transmission(xvals, parms):
    #position=p[0];  intensity=p[1]; slit=p[2];  stth=p[3];  background=p[4];  thickness=p[5];  absorption=p[6]
    #x0=p[0];        i0=p[1];        w=p[2];     theta=p[3];  ib=p[4];    thick=p[5];   u=p[6];
    #th = np.deg2rad(theta)
    #p0 = w * np.cos(th)/np.cos(2*th)
    #out = []
    #for x in xvals:
    #    if x < (x0 - p0):
    #        val = ib
    #    elif ((x>=x0-p0) and (x < x0)):
    #        val = i0*(x-x0+p0)*(x-x0+p0)+ib
    #    elif ((x>=x0) and (x<(x0+p0))):
    #        val = i0*(2.0*p0*p0-(x0+p0-x)*(x0+p0-x))+ib
    #    elif (x>=x0+p0):
    #        val=2*i0*p0*p0 +ib
    #    out = out + [val]
    x0 = parms[0]
    i0 = parms[1]
    w = parms[2]
    theta = parms[3]
    ib = parms[4]
    thick = parms[5]
    u = parms[6]
    th = np.deg2rad(theta)
    p = w * np.cos(th)
    Atot = w * w / np.sin(2.0 * th)
    out = []
    for x in xvals:
        if (x <= (x0 - p)):
            val = ib
        elif ((x > (x0 - p)) and (x <= x0)):
            val = ib + i0 * ((x - (x0 - p)) * ((x -
                                                (x0 - p)) * np.tan(th))) / Atot
        elif ((x > x0) and (x <= x0 + p)):
            val = ib + i0 * (Atot - (x0 + p - x) *
                             (x0 + p - x) * np.tan(th)) / Atot
        elif (x > x0 + p):
            val = ib + i0
        out = out + [val]
    return np.array(out)
def reflection1(xvals, parms):
    #position=p[0];  intensity=p[1]; slit=p[2];  stth=p[3];  background=p[4];  thickness=p[5];  absorption=p[6]
    x0 = parms[0]
    i0 = parms[1]
    w = parms[2]
    theta = parms[3]
    ib = parms[4]
    thick = parms[5]
    u = parms[6]
    th = np.deg2rad(theta)
    p = w * np.sin(th)
    Atot = w * w / np.sin(2.0 * th)
    out = []
    ni = 5
    irng = np.array(range(1, ni + 1))

    for x in xvals:
        if x < (x0 - p):
            val = ib
        elif ((x0 - p) < x and x0 > x):
            l1 = x - (x0 - p)
            nrleft = int(np.ceil(l1 / (2 * p) * ni))
            if nrleft < 1: nrleft = 1
            irngleft = np.array(range(1, nrleft + 1))
            dl1 = l1 / float(nrleft)
            dl = irngleft * dl1
            triA = dl * dl / np.tan(th)  #triangle areas
            secA = [triA[0]
                    ] + [triA[i] - triA[i - 1]
                         for i in range(1, nrleft)]  #section areas
            secA = np.array(secA)
            m1 = np.linspace(
                x0 - p + dl1 / 2.0, x - dl1 / 2.0, nrleft
            )  #section midpoint position - path length calculated from this
            plen = np.abs(2 * m1 / np.sin(th))
            val = ib + np.sum(i0 * secA * np.exp(-u * plen))

        elif (x0 <= x) and (x0 + p >= x):
            l1 = p
            nrleft = int(np.ceil(l1 / (2 * p) * ni))
            if nrleft < 1: nrleft = 1
            irngleft = np.array(range(1, nrleft + 1))
            dl1left = l1 / float(nrleft)
            dlleft = irngleft * dl1left
            triAleft = dlleft * dlleft / np.tan(th)  #triangle areas
            secAleft = [triAleft[0]] + [
                triAleft[i] - triAleft[i - 1] for i in range(1, nrleft)
            ]  #section areas
            secAleft = np.array(secAleft)
            m1left = np.linspace(x0 - p + dl1left / 2.0, x0 - dl1left / 2.0,
                                 nrleft) + (x - x0)
            plenleft = np.abs(2 * m1left / np.sin(th))
            valleft = np.sum(i0 * secAleft * np.exp(-u * plenleft))

            l2 = x - x0
            nrright = int(np.ceil(x - x0 / (2 * p) * ni))
            if nrright < 1: nrright = 1
            irngright = np.array(range(1, nrright + 1))
            dl1right = l2 / float(nrright)
            dlright = p - np.append(0.0, dl1right * irngright)
            triAright = dlright * dlright / np.tan(th)
            secAright = [
                triAright[i] - triAright[i + 1] for i in range(nrright)
            ]
            secAright = np.array(secAright)
            m1right = np.linspace(x - x0 - dl1right / 2.0, dl1right / 2.0,
                                  nrright)
            plenright = np.abs(2 * m1right / np.sin(th))
            valright = np.sum(i0 * secAright * np.exp(-u * plenright))

            val = ib + valleft + valright

        elif (x > x0 + p):
            l1 = p
            #nrleft = int(np.ceil(l1/(x-(x0-p))*ni));
            nrleft = int(np.ceil(l1 / (2 * p) * ni))
            if nrleft < 1: nrleft = 1
            irngleft = np.array(range(1, nrleft + 1))
            dl1left = l1 / float(nrleft)
            dlleft = irngleft * dl1left
            triAleft = dlleft * dlleft / np.tan(th)  #triangle areas
            secAleft = [triAleft[0]] + [
                triAleft[i] - triAleft[i - 1] for i in range(1, nrleft)
            ]  #section areas
            secAleft = np.array(secAleft)
            m1left = np.linspace(x0 - p + dl1left / 2.0, x0 - dl1left / 2.0,
                                 nrleft) + (x - x0)
            plenleft = np.abs(2 * m1left / np.sin(th))
            valleft = np.sum(i0 * secAleft * np.exp(-u * plenleft))

            l2 = p
            nrright = int(np.ceil(l2 / (2 * p) * ni))
            if nrright < 1: nrright = 1
            irngright = np.array(range(1, nrright + 1))
            dl1right = l2 / float(nrright)
            dlright = p - np.append(0.0, dl1right * irngright)
            triAright = dlright * dlright / np.tan(th)
            secAright = [
                triAright[i] - triAright[i + 1] for i in range(nrright)
            ]
            secAright = np.array(secAright)
            m1right = np.linspace(dlright[0] - dl1right / 2.0, dlright[-1] +
                                  dl1right / 2.0, nrright) + (x - (x0 + p))
            plenright = np.abs(2 * m1right / np.sin(th))
            valright = np.sum(i0 * secAright * np.exp(-u * plenright))

            val = ib + valleft + valright

        out = out + [val]
    return np.array(out)
def walltransmission(xvals, parms):
    #position=p[0];  intensity=p[1]; slit=p[2];  stth=p[3];  background=p[4];  thickness=p[5];  absorption=p[6]
    midpoint = parms[0]
    i0 = parms[1]
    w = parms[2]
    theta = parms[3]
    ib = parms[4]
    thick = parms[5]
    u = parms[6]
    midpoint = parms[0]
    x0 = midpoint - thick / 2.0
    th = np.deg2rad(theta)
    p = w * np.cos(th)
    t = thick
    Atot1 = w * w / np.sin(2.0 * th)
    Atot = 2 * w * np.sin(th) * w * np.cos(th)
    out = []

    baselength = 2 * p
    Gvol_area = 2 * w * w * np.sin(th) * np.cos(th)
    if baselength > thick:
        Ar = 0.5 * (p - thick / 2.0) * (p - thick / 2.0) * np.tan(th)
        maxbeam = Gvol_area - 4.0 * Ar
    else:
        maxbeam = Gvol_area

    for x in xvals:
        x1 = x
        x2 = x - thick

        if (x1 <= (x0 - p)) and (x2 <= x0 - p):
            val = ib
        elif (x0 - p) >= x2 and (x0 - p <= x1) and (x0 > x1):
            A = (x1 - (x0 - p))
            val = ib + A * A * np.tan(th) / maxbeam * i0
        elif (x0 - p <= x2) and (x0 >= x1):
            C = (x1 - (x0 - p))
            B = (x2 - (x0 - p))
            val = ib + (C * C * np.tan(th) - B * B * np.tan(th)) / maxbeam * i0
        elif (x2 <= (x0 - p)) and (x0 >= x2) and (x0 <= x1) and (x1 <=
                                                                 (x0 + p)):
            A = (x1 - (x0 + p))
            val = ib + (Gvol_area - A * A * np.tan(th)) / maxbeam * i0
        elif (x2 <= (x0 - p)) and (x0 >= x2) and (x0 <= x1) and (x1 >=
                                                                 (x0 + p)):
            val = ib + i0
        elif (x2 >= (x0 - p)) and (x0 >= x2) and (x0 <= x1) and (x1 <=
                                                                 (x0 + p)):
            A = (x1 - (x0 + p))
            B = (x2 - (x0 - p))
            val = ib + (Gvol_area - A * A * np.tan(th) -
                        B * B * np.tan(th)) / maxbeam * i0
        elif (x2 >= (x0 - p)) and (x0 >= x2) and (x0 <= x1) and (x1 >=
                                                                 (x0 + p)):
            B = (x2 - (x0 - p))
            val = ib + (Gvol_area - B * B * np.tan(th)) / maxbeam * i0
        elif (x0 + p >= x1) and (x0 <= x2):
            A = (x1 - (x0 + p))
            C = (x2 - (x0 + p))
            val = ib + (C * C * np.tan(th) - A * A * np.tan(th)) / maxbeam * i0
        elif (x2 >= (x0 - p)) and (x0 <= x2) and (x0 <= x1) and (
                x1 >= (x0 + p)) and (x2 <= (x0 + p)):
            A = (x0 + p - x2)
            val = ib + A * A * np.tan(th) / maxbeam * i0
        elif (x0 - p) >= x2 and (x0 + p) <= x2:
            val = ib
        out = out + [val]
    return np.array(out)