Ejemplo n.º 1
0
    def __init__(self,
                 pos,
                 dirn,
                 wavelength=None,
                 intensity=1.0,
                 index=AirIndex()):
        """
        Constructor for to set parameters

        """
        if isinstance(pos, ParaxialRay):
            Ray.__init__(self, pos.wavelength, pos.intensity,
                         pos.refractiveindex)
            self.position = Vector3d(0.0, pos.h, pos.z)
            self.director = Unit3d(Angle(pos.u))
        else:
            if isinstance(pos, SourcePoint):
                intensity = pos.spectrum
            Ray.__init__(self, wavelength, intensity,
                         index)  # Set wavelnegth intensity and index in super
            self.position = Vector3d(
                pos
            )  # Make localcopy of Position and Director (since they get updated)
            self.director = Unit3d(dirn)
        self.pathlength = None  # Set opl to none (not calculated)
Ejemplo n.º 2
0
def getAngleDegrees(prompt, default=None):
    """
    Read a Angle in theta/psi from the terminal in Degrees with checking.

    Format from terminal may be theta,psi   OR   '[theta,psi]',  also each componet will be evaluated.

    :param prompt: the prompt to be displayed
    :type prompt: str
    :param default: the default value (may be None), this is assumes to be in radians.
    :type default: Angle
    :return: the Angle (note will always return an Angle in radians)

    Note: input values are in degrees but the returned Angle values are in radians.

    """
    if default != None and isinstance(default, Angle):    # Convert to degree for default
        default = default.getDegrees()
    while True:
        val = __getInput(prompt, default)
        try:
            if isinstance(val, str):          # Its a string
                val = eval(val)              # Eval list

            return Angle().setDegrees(val)
        except (ValueError, NameError, ZeroDivisionError, SyntaxError):
            logger.error("Conversion of '{0:s}' to Angle failed.".format(str(val)))
Ejemplo n.º 3
0
def main():

    angle = Angle().setDegrees(30,
                               80)  # Angle with theta = 30 , psi = 80 degrees
    tprint("Angle is : ",
           angle)  # print, note tprint() automaticall take str()
    u = Unit3d(angle)  # Convert to Unit3d
    tprint(repr(u))  # print using repr()

    angle = u.getAngle()  # get angle from Unit3d
    theta, psi = angle.getDegrees()  # get the angle as a list in degrees
    tprint("Theta is : ", theta, " and psi is : ", psi)  # print it

    angle = getAngleDegrees("Get angle in degtrees")
    tprint(repr(angle))
    u = Unit3d(angle)  # Convert to Unit3d
    tprint(repr(u))  # print using repr()
Ejemplo n.º 4
0
 def getAngle(self):
     """
     Get the director an an Angle
     :return: Angle if valid, else None
     """
     if self.isValid():
         return Angle(self.director)
     else:
         return None
Ejemplo n.º 5
0
    def getWavePointSet(self,source,wave = None,nrays = 10,refopt = 1):
        """
        Get the WavePointSet for collimated beam in the exitpupil of the lens

        :param source: source of input beeam, either SourcePoint, Unit3d or angle.
        :type source: SourcePoint, Unit3d, Angle or float
        :param wave: analysis wavelength
        :type wave: float
        :param nrays: number of raays across input aperture, (Default = 10)
        :type nrays: int
        :param refopt: reference point option, 0 = paraxial, 1 = centre of PSF in image plane, 2 = optimal area PSF
        :type refopt: int
        """
        #       Sort out angle
        if isinstance(source,SourcePoint):
            u = Vector3d(source)
        elif isinstance(source,float) or isinstance(source,int):
            u = Unit3d(Angle(source))
        else:
            u = Unit3d(source)

        #      Make pencil with array and record path, and propagate through lens
        pencil = RayPencil().addBeam(self.lens,u,"array",nrays=nrays,wavelength=wave,path=True)
        pencil *= self.lens

        #        Get image point of object
        self.refpt = self.lens.imagePoint(u,self.design)    # Paraxial point location
        pt = self.lens.getPoint()
        self.ip = OpticalPlane(Vector3d(pt.x,pt.y,self.refpt.z))

        if refopt == 0:       # got what we need aready
            None
        elif refopt == 1:
            self.refpt = Psf().setWithRays(pencil,self.ip)              # Centre of PSF in image plane
        elif refopt == 2:
            self.refpt = Psf().optimalArea(pencil,self.ip)              # Optimal area PSF, not in image plane
        else:
            print("Illegal ref type")

        ep = self.lens.exitPupil(self.design)         # Exit pupil of lens

        #     Form the wavefront
        wf = WavePointSet(ep.getRadius()).setWithRays(pencil,ep,self.refpt)
        return wf
Ejemplo n.º 6
0
def main():

    #      Get lens from database
    lens = DataBaseLens()

    #           Get angle of beam and wavelnegth
    angle = getFloat("Angle in degrees", 0.0, 0.0, 15.0)
    u = Unit3d(Angle().setDegrees(angle))  # Angle as unit vectr
    w = getFloat("Wavelength", Default)

    #    Make two ray pencils, one for spot diagram and one for display (vertical only)
    pencil = RayPencil().addBeam(lens, u, "array", wavelength=w)
    vpencil = RayPencil().addBeam(lens, u, "vl",
                                  wavelength=w).addMonitor(RayPath())
    bf = lens.backFocalPlane()

    #            Propagate through lens to back focal plane
    pencil *= lens

    vpencil *= lens
    vpencil *= bf

    #            Get optimal area psf and create a SpotDiagram
    sd = SpotDiagram(pencil)

    #             Go round loop plotting the sopt diagram as various zplane positions

    while True:
        zp = getFloat("Zplane", bf.getPoint().z)
        plane = OpticalPlane(zp)
        plt.subplot(2, 1, 1)
        lens.draw()
        vpencil.draw()
        plt.axis("equal")
        plt.title("Lens " + lens.title)

        plt.subplot(2, 1, 2)
        sd.draw(plane, True)
        plt.title("Spot diagram")
        plt.show(block=True)
Ejemplo n.º 7
0
    def __init__(self, lens, source, refopt=0, wave=Default, design=None):
        """
        The constrcutor
        """

        self.lens = lens
        if isinstance(source, ray.SourcePoint):  # From a sourcepoint
            self.source = source
        elif isinstance(source, float):
            self.source = Unit3d(Angle(source))  # Infinite Object
        else:
            self.source = Unit3d(source)

        self.setReference(refopt)
        self.wavelength = float(wave)
        if design == None:
            self.design = self.wavelength
        else:
            self.design = float(design)

        # Set up a basic knife edge aperture at 0,0,0 with default knife distance, angle and shift
        self.knife = KnifeAperture(0.0, self.lens.exitAperture().maxRadius)
Ejemplo n.º 8
0
def main():

    #      Get the materail type and make a prism of default angle, size and location
    n = MaterialIndex()
    prism = Prism(index=n)
    tprint(repr(prism))

    #      Get input point on prism and min deviation at Mercury_i line
    pt = prism.getInputPoint()
    dev = prism.minDeviation(Mercury_e)
    tprint("Min deviation : ", math.degrees(dev), " at : ", Mercury_e)
    tprint("Max resolutions is ", prism.maxResolution(Mercury_e))
    tprint("Resolution with 20 mm diameter beam : ",
           prism.resolution(10, Mercury_e))

    u = Unit3d().parseAngle(dev /
                            2)  # Set ray input angle at half min deviation

    #      Form np array of wavelength and angle
    wavelengths = np.linspace(Mercury_i, Helium_r, 50)
    angle = np.zeros(wavelengths.size)

    #      Go through each wavelength, make a ray and trace it
    for i, wave in enumerate(wavelengths):
        ray = r.IntensityRay(pt, u, wave)
        ray *= prism
        #      Extract angle of ray in degrees
        angle[i] = math.degrees(Angle(ray.director).theta)

    # Do the plotting

    plt.plot(wavelengths, angle)
    plt.title("Spectrometer Output angle")
    plt.xlabel("Wavelength in microns")
    plt.ylabel("Output angle in degrees")
    plt.grid()

    plt.show()
Ejemplo n.º 9
0
def main():

    #      Get lens from database
    lens = DataBaseLens()

    #           Get angle of beam and wavelnegth
    angle = getFloat("Angle in degrees", 0.0, 0.0, 15.0)
    u = Unit3d(Angle().setDegrees(angle))  # Angle as unit vectr
    wave = getFloat("Wavelength", getDefaultWavelength())

    #            Get optimal area psf and create a SpotDiagram
    sd = SpotAnalysis(lens, u, 0, wavelength=wave)

    #             Go round loop plotting the sopt diagram as various zplane positions

    while True:
        zp = getFloat("Delta", 0.0)

        sd.draw(zp, True)
        pos = sd.plane.getPoint().z
        print("Plane pos " + str(pos))
        plt.title("Spot diagram")
        plt.show(block=True)
Ejemplo n.º 10
0
    def __init__(self,
                 lens,
                 source=0.0,
                 refopt=0,
                 wavelength=None,
                 design=None):
        """
        The constrcutor
        """

        #      Sort out source
        if isinstance(source, ray.SourcePoint):  # From a sourcepoint
            self.source = source
        elif isinstance(source, float):
            self.source = Unit3d(Angle(source))  # Infinite Object
        else:
            self.source = Unit3d(source)

        wave = getDefaultWavelength(wavelength)
        design = getDesignWavelength(design)

        #    Make raypencil (this is used in draw())
        self.raypencil = ray.RayPencil().addBeam(lens,
                                                 source,
                                                 "array",
                                                 wavelength=wave)
        self.raypencil *= lens  # Propagate through lens

        self.pt = lens.imagePoint(source, design)

        if refopt == 1:
            self.pt = Psf().setWithRays(
                self.raypencil, self.pt.z)  # Centre of PSF in image plane
        if refopt == 2:
            self.pt = Psf().optimalArea(
                self.raypencil,
                self.pt.z)  # Optimal area PSF, not in image plane
Ejemplo n.º 11
0
def getAngle(prompt, default=None):
    """
    Read a Angle in theta/psi fromat  the terminal with checking.

    Format from terminal may be 'theta,psi'   OR   '[theta,psi]',  also each componet will be evaluated.

    :param prompt: the prompt to be displayed
    :type prompt: str
    :param  default: the default value (may be None)
    :type default: Angle
    :return: the Angle (note will always return an Angle)

    Note: input values are in radians.

    """
    while True:
        val = __getInput(prompt, default)
        try:
            if isinstance(val, str):          # Its a string
                val = eval(val)              # Eval list

            return Angle(val)
        except (ValueError, NameError, ZeroDivisionError, SyntaxError):
            logger.error("Conversion of '{0:s}' to Angle failed.".format(str(val)))
Ejemplo n.º 12
0
def getWavelength(prism, inAngle, outAngle, wavelengths=[0.25, 1.0]):

    #        Get prism point and angle of input at Unit3d
    #
    pt = prism.getInputPoint()
    u = Unit3d(Angle(inAngle))

    #         Guess at initial wavelngth
    wave = (wavelengths[1] - wavelengths[0]) / 2
    #         Make input ray at guess wavelength
    ray = IntensityRay(pt, u, wave)

    #       Parameters for seaerch
    delta = 0.1
    forward = True
    na = float("inf")  # New angle

    while abs(na - outAngle) > 1.0e-9 / abs(outAngle):
        nray = ray * prism  #      New Ray through prism
        na = nray.getAngle()
        na = na.theta * math.cos(na.psi)  # In radians
        if na < outAngle:  # Less that target
            wave += delta
            forward = True
        else:
            if forward:  # Half step
                delta *= 0.5
            forward = False
            wave -= delta
        if wave < wavelengths[0] or wave > wavelengths[1]:
            print("Out of wavelength range :")
            return float("nan")

        ray.wavelength = wave  # Update wavelength of ray

    return ray.getWavelength()  # End of loop, so success
Ejemplo n.º 13
0
    def drawAberrationPlot(self,angle,wavelength = None ,colour=["r","g","b"],legend = "lower left"):
        """
        Form and draw the plots at specified angle

        :param angle: the ray angle
        :type angle: float or Angle or Unit3d
        :param colour: line colours is three elemnts list, Default = ["r","g","b"])
        :param legend: location of ledgend, (Default = "lower left")
        :type legend: str
        """
        if isinstance(angle,float):
            u = Unit3d(Angle(angle))                     # direction of beam
        else:
            u = Unit3d(angle)
            angle = Angle(u).theta

        wavelength = getDefaultWavelength(wavelength)
        ref = self.lens.imagePoint(u,self.design)    # Get image point at design wavelength
        ip = OpticalPlane(ref)                        # Image plane

        nrays = 50
        ca = self.lens.entranceAperture()


        #         Make list for plots
        mvals = []                # Meridional
        svalsx = []               # Sagittal x
        svalsy = []               # Sagittal y


        #              Start of loop to make rays
        rscan = np.linspace(-ca.maxRadius,ca.maxRadius,nrays + 1)
        for r in rscan:
            # Make two rays
            mray = IntensityRay(ca.point + Vector3d(0.0, r, 0.0), u, wavelength)
            sray = IntensityRay(ca.point + Vector3d(r, 0.0, 0.0), u, wavelength)

            #       Add to pencil and propagate both back to clear lens
            pencil = RayPencil(mray,sray).propagate(-ca.maxRadius)
            #         propagate through lens to image surafce
            pencil *= self.lens
            pencil *= ip

            #            If rays valid (so not blocked), abberations to list
            if mray:
                mpos = mray.position - ref
                mvals.append(mpos.y)
            else:
                mvals.append(float("nan"))
            if sray:
                spos = sray.position - ref
                svalsx.append(spos.x)
                svalsy.append(spos.y)
            else:
                svalsx.append(float("nan"))
                svalsy.append(float("nan"))


        # plots with suitable labels to the current axis.

        plt.plot(rscan,mvals, color = colour[0], label="Meridional")
        plt.plot(rscan,svalsx,color = colour[1], label="Sagittal x")
        plt.plot(rscan,svalsy,color = colour[2], label="Sagittal y")
        plt.title("{0:s}: a: {1:4.2f} w: {2:4.2f} d: {3:4.2f}".\
                  format(self.lens.title,math.degrees(angle),wavelength,\
                  self.design))
        plt.legend(loc=legend,fontsize="small")
        plt.grid()