Beispiel #1
0
    def __init__(self,
                 radius=50.,
                 thickness=10,
                 curvature_s1=1. / 200,
                 curvature_s2=1. / 200,
                 *args,
                 **kwargs):
        Component.__init__(self, *args, **kwargs)
        self.radius = radius
        self.thickness = thickness
        self.curvature_s1 = curvature_s1
        self.curvature_s2 = curvature_s2

        if self.curvature_s1 != 0.:
            __a_surf = Spherical(shape=Circular(radius=self.radius),
                                 curvature=self.curvature_s1)
        else:
            __a_surf = Plane(shape=Circular(radius=self.radius))

        if self.curvature_s2 != 0:
            __p_surf = Spherical(shape=Circular(radius=self.radius),
                                 curvature=self.curvature_s2)
        else:
            __p_surf = Plane(shape=Circular(radius=self.radius))

        self.surflist["S1"] = (__a_surf, (0, 0, -self.thickness / 2), (0, 0,
                                                                       0))
        self.surflist["S2"] = (__p_surf, (0, 0, self.thickness / 2), (0, 0, 0))

        if self.curvature_s1 != 0:
            r_a = 1. / self.curvature_s1
            s_a = absolute(r_a) - sqrt(r_a * r_a - self.radius * self.radius)
            if (r_a) < 0: s_a = -s_a
        else:
            s_a = 0.

        if self.curvature_s2 != 0:
            r_p = 1. / self.curvature_s2
            s_p = absolute(r_p) - sqrt(r_p * r_p - self.radius * self.radius)
            if (r_p) > 0: s_p = -s_p
        else:
            s_p = 0.

        #Ojo, falta verificar si la lente es fisicamente posible es decir th1>0
        th1 = self.thickness - s_a - s_p

        zp = float(-self.thickness / 2 + s_a + th1 / 2.)
        __c_surf_1 = Cylindrical(shape=Rectangular(size=(2. * self.radius,
                                                         th1)),
                                 curvature=1. / self.radius)

        __c_surf_2 = Cylindrical(shape=Rectangular(size=(2 * self.radius,
                                                         th1)),
                                 curvature=1. / self.radius)

        self.surflist["B1"] = (__c_surf_1, (-self.radius, 0, zp), (pi / 2., 0,
                                                                   pi / 2))

        self.surflist["B2"] = (__c_surf_2, (self.radius, 0, zp), (-pi / 2., 0,
                                                                  pi / 2))
    def __init__(self,
                 size=(20, 20),
                 thickness=10,
                 curvature_s1=1. / 200,
                 curvature_s2=1. / 200,
                 *args,
                 **kwargs):
        Component.__init__(self, *args, **kwargs)
        self.size = size
        w, h = self.size
        self.thickness = thickness
        self.curvature_s1 = curvature_s1
        self.curvature_s2 = curvature_s2

        if self.curvature_s1 != 0.:
            __a_surf = Cylindrical(shape=Rectangular(size=(w, h)),
                                   curvature=self.curvature_s1)
        else:
            __a_surf = Plane(shape=Rectangular(size=(w, h)))

        if self.curvature_s2 != 0:
            __p_surf = Cylindrical(shape=Rectangular(size=(w, h)),
                                   curvature=self.curvature_s2)
        else:
            __p_surf = Plane(shape=Rectangular(size=(w, h)))

        self.surflist["S1"] = (__a_surf, (0, 0, -self.thickness / 2), (0, 0,
                                                                       0))
        self.surflist["S2"] = (__p_surf, (0, 0, self.thickness / 2), (0, 0, 0))
Beispiel #3
0
    def __init__(self,
                 radius=50.,
                 thickness=10,
                 reflectivity=0.5,
                 *args,
                 **kwargs):
        Component.__init__(self, *args, **kwargs)
        __a_surf = Plane(shape=Circular(radius=radius),
                         reflectivity=reflectivity)
        __p_surf = Plane(shape=Circular(radius=radius))

        self.surflist["S1"] = (__a_surf, (0, 0, 0), (0, 0, 0))
        self.surflist["S2"] = (__p_surf, (0, 0, thickness), (0, 0, 0))

        __c_surf_1 = Cylindrical(shape=Rectangular(size=(2. * radius,
                                                         thickness)),
                                 curvature=1. / radius)
        __c_surf_2 = Cylindrical(shape=Rectangular(size=(2 * radius,
                                                         thickness)),
                                 curvature=1. / radius)

        self.surflist["B1"] = (__c_surf_1, (-radius, 0, thickness / 2.),
                               (pi / 2., 0, pi / 2))
        self.surflist["B2"] = (__c_surf_2, (radius, 0, thickness / 2.),
                               (-pi / 2., 0, pi / 2))
Beispiel #4
0
    def __init__(self, s, l, *args, **kwargs):
        #s alto o profundidad del prisma
        #l Longitud del lado mas largo del prisma

        #La referencia del prisma de dove esta en el centro del prisma

        Component.__init__(self, *args, **kwargs)

        d = 1.4142135623730951 * s

        #Diagonales del prisma

        s1 = Plane(shape=Rectangular(size=(d, s)))
        s2 = Plane(shape=Rectangular(size=(d, s)))

        #Lado largo del prisma
        s3 = Plane(shape=Rectangular(size=(l, s)))
        #lado corto del prisma
        s4 = Plane(shape=Rectangular(size=(l - 2 * s, s)))

        sp1 = (l - s) / 2.
        self.surflist["S1"] = (s1, (-sp1, 0, 0), (0, -pi / 4, 0))
        self.surflist["S2"] = (s2, (sp1, 0, 0), (0, pi / 4, 0))
        self.surflist["S3"] = (s3, (0, 0, -s / 2.), (0, 0, 0))
        self.surflist["S4"] = (s4, (0, 0, s / 2.), (0, 0, 0))
Beispiel #5
0
 def __init__(self, sides=3, height=3, inner_radius=10, **traits):
     if sides < 3:
         raise Exception("Polygon should have at least 3 sides.")
     side_length = 2 * inner_radius * np.tan(np.pi / sides)
     Component.__init__(self, **traits)
     # create a side base shape
     side = Plane(shape=Rectangular(size=(side_length, height)))
     for i in range(sides):
         angle = 2 * np.pi / sides * i
         center = inner_radius * np.array([np.cos(angle), np.sin(angle)])
         self.surflist[f"S{i}"] = (side, (center[0], center[1], 0),
                                   (np.pi / 2, 0, angle + np.pi / 2))
     # create a top/bottom base shape
     triangle = Plane(shape=Triangular(((0, 0), (-inner_radius,
                                                 -side_length / 2),
                                        (-inner_radius, side_length / 2))))
     for i in ['bottom', 'height']:
         surface = len(self.surflist)
         if i == 'bottom':
             offset = -height / 2
         else:
             offset = height / 2
         for i in range(sides):
             angle = 2 * np.pi / sides * i
             if sides % 2:
                 offset = 2 * np.pi / (sides * 2)
             else:
                 offset = 0
             self.surflist[f"S{i+surface}"] = (triangle, (0, 0, offset),
                                               (0, 0, angle + offset))
Beispiel #6
0
    def __init__(self, width=50, height=10., reflectivity=0, *args, **kwargs):

        Component.__init__(self, *args, **kwargs)

        self.width = width
        self.height = height
        self.reflectivity = reflectivity

        __a_face = Plane(shape=Rectangular(size=(self.width, self.height)))
        __b_face = Plane(shape=Rectangular(size=(self.width, self.height)))

        h = sqrt(2.) * self.width

        __h_face = Plane(shape=Rectangular(size=(h, self.height)),
                         reflectivity=self.reflectivity)

        w2 = self.width / 2.
        __e1 = Plane(shape=Triangular(((-w2, w2), (-w2, -w2), (w2, -w2))))
        __e2 = Plane(shape=Triangular(((-w2, w2), (-w2, -w2), (w2, -w2))))

        self.surflist["S1"] = (__a_face, (0, 0, -self.width / 2), (0, 0, 0))
        self.surflist["S2"] = (__b_face, (self.width / 2, 0, 0), (0, pi / 2,
                                                                  0))
        self.surflist["S3"] = (__h_face, (0, 0, 0), (0, -pi / 4, 0))
        self.surflist["S4"] = (__e1, (0, self.height / 2, 0), (pi / 2, -pi / 2,
                                                               0))
        self.surflist["S5"] = (__e2, (0, -self.height / 2, 0), (pi / 2,
                                                                -pi / 2, 0))
Beispiel #7
0
    def __init__(self,
                 size=(50.0, 50.0, 10.0),
                 reflectivity=0.0,
                 lpmm=600,
                 angle=0,
                 M=[1],
                 *args,
                 **kwargs):
        Component.__init__(self, *args, **kwargs)
        self.size = size
        w, h, l = self.size
        lpmmx = lpmm * cos(angle)
        lpmmy = lpmm * sin(angle)
        phf = poly2d([0, 2 * pi * lpmmx, 2 * pi * lpmmy])
        __a_surf = RPPMask(shape=Rectangular(size=(w, h)),
                           phm=phf,
                           reflectivity=reflectivity,
                           M=M)
        __p_surf = Plane(shape=Rectangular(size=(w, h)))

        __u_surf = Plane(shape=Rectangular(size=(w, l)))
        __l_surf = Plane(shape=Rectangular(size=(w, l)))

        __lf_surf = Plane(shape=Rectangular(size=(l, h)))
        __rg_surf = Plane(shape=Rectangular(size=(l, h)))

        self.surflist["S1"] = (__a_surf, (0, 0, 0), (0, 0, 0))
        self.surflist["S2"] = (__p_surf, (0, 0, l), (0, 0, 0))

        self.surflist["S3"] = (__u_surf, (0, h / 2, l / 2.0), (pi / 2, 0, 0))
        self.surflist["S4"] = (__l_surf, (0, -h / 2, l / 2.0), (pi / 2, 0, 0))

        self.surflist["S5"] = (__lf_surf, (-w / 2, 0, l / 2.0), (0, pi / 2, 0))
        self.surflist["S6"] = (__rg_surf, (w / 2, 0, l / 2.0), (0, pi / 2, 0))
Beispiel #8
0
 def __init__(self, size=(10, 10), transparent=True, *args, **kwargs):
     Component.__init__(self, *args, **kwargs)
     self.__d_surf = Plane(
         shape=Rectangular(size=size)
     )  #ArrayDetector (size=self.size, transparent=self.transparent)
     self.size = size
     self.surflist["S1"] = (self.__d_surf, (0, 0, 0), (0, 0, 0))
     self.material = 1.
Beispiel #9
0
    def __init__(self,
                 radius=4.445,
                 thickness=7.62,
                 K=-4.302,
                 R=3.00,
                 *args,
                 **kwargs):
        Component.__init__(self, *args, **kwargs)
        self.radius = radius
        self.thickness = thickness
        self.K = K
        self.R = R

        __a_surf = Aspherical(shape=Circular(radius=self.radius),
                              Ax=0,
                              Ay=self.R,
                              Kx=-1,
                              Ky=self.K,
                              poly=poly2d((0, 0)))

        self.surflist["S1"] = (__a_surf, (0, 0, 0), (0, 0, 0))

        __p_surf = Plane(shape=Circular(radius=(self.radius)))

        self.surflist["B1"] = (__p_surf, (0, 0, self.thickness), (0, 0, 0))
Beispiel #10
0
    def __init__(self, s, *args, **kwargs):

        Component.__init__(self, *args, **kwargs)

        s1 = Plane(shape=Rectangular(size=(s, s)))
        s2 = Plane(shape=Rectangular(size=(s, s)))
        d = s / cos(radians(22.5))
        s3 = Plane(shape=Rectangular(size=(d, s)), reflectivity=1)
        s4 = Plane(shape=Rectangular(size=(d, s)), reflectivity=1)
        d1 = d * sin(radians(22.5) / 2.)
        s5 = Plane(shape=Rectangular(size=(2 * sqrt(2) * d1, s)))

        self.surflist["S1"] = (s1, (0, 0, -s / 2.), (0, 0, 0))
        self.surflist["S2"] = (s2, (s / 2., 0, 0), (0, pi / 2, 0))
        self.surflist["S3"] = (s3, (0, 0, s / 2. + d1), (0, pi / 8, 0))
        self.surflist["S4"] = (s4, (-s / 2. - d1, 0, 0), (0, 3 * pi / 8, 0))
        self.surflist["S5"] = (s5, (-s / 2. - d1, 0, s / 2. + d1), (0, -pi / 4,
                                                                    0))
Beispiel #11
0
    def __init__(self,
                 size=(50., 50., 10.),
                 reflectivity=0.5,
                 *args,
                 **kwargs):
        Component.__init__(self, *args, **kwargs)
        self.size = size
        w, h, l = self.size
        __a_surf = Plane(shape=Rectangular(size=(w, h)),
                         reflectivity=reflectivity)
        __p_surf = Plane(shape=Rectangular(size=(w, h)))

        __u_surf = Plane(shape=Rectangular(size=(w, l)))
        __l_surf = Plane(shape=Rectangular(size=(w, l)))

        __lf_surf = Plane(shape=Rectangular(size=(l, h)))
        __rg_surf = Plane(shape=Rectangular(size=(l, h)))

        self.surflist["S1"] = (__a_surf, (0, 0, 0), (0, 0, 0))
        self.surflist["S2"] = (__p_surf, (0, 0, l), (0, 0, 0))

        self.surflist["S3"] = (__u_surf, (0, h / 2, l / 2.), (pi / 2, 0, 0))
        self.surflist["S4"] = (__l_surf, (0, -h / 2, l / 2.), (pi / 2, 0, 0))

        self.surflist["S5"] = (__lf_surf, (-w / 2, 0, l / 2.), (0, pi / 2, 0))
        self.surflist["S6"] = (__rg_surf, (w / 2, 0, l / 2.), (0, pi / 2, 0))
Beispiel #12
0
    def __init__(self, s, *args, **kwargs):
        """
        :param s: alto y base de las entradas del pentaprisma
        :param args:
        :param kwargs:
        :return:
        """

        s1 = Plane(shape=Rectangular(size=(s, s)))
        s2 = Plane(shape=Rectangular(size=(s, s)))
        d = s / cos(radians(22.5))
        s3 = Plane(shape=Rectangular(size=(d, s)), reflectivity=1)
        s4 = Plane(shape=Rectangular(size=(d, s)), reflectivity=1)
        d1 = d * sin(radians(22.5) / 2.)
        s5 = Plane(shape=Rectangular(size=(2 * sqrt(2) * d1, s)))

        self.surflist["S1"] = (s1, (0, 0, -s / 2.), (0, 0, 0))
        self.surflist["S2"] = (s2, (s / 2., 0, 0), (0, pi / 2, 0))
        self.surflist["S3"] = (s3, (0, 0, s / 2. + d1), (0, pi / 8, 0))
        self.surflist["S4"] = (s4, (-s / 2. - d1, 0, 0), (0, 3 * pi / 8, 0))
        self.surflist["S5"] = (s5, (-s / 2. - d1, 0, s / 2. + d1), (0, -pi / 4,
                                                                    0))
Beispiel #13
0
    def __init__(self, size=(10, 10, 10), **traits):
        Component.__init__(self, **traits)
        self.size = size
        w, h, l = self.size
        __a_surf = Plane(shape=Rectangular(size=(w, h)))
        __p_surf = Plane(shape=Rectangular(size=(w, h)))

        __u_surf = Plane(shape=Rectangular(size=(w, l)))
        __l_surf = Plane(shape=Rectangular(size=(w, l)))

        __lf_surf = Plane(shape=Rectangular(size=(l, h)))
        __rg_surf = Plane(shape=Rectangular(size=(l, h)))

        self.surflist["S1"] = (__a_surf, (0, 0, -l / 2), (0, 0, 0))
        self.surflist["S2"] = (__p_surf, (0, 0, l / 2), (0, 0, 0))

        self.surflist["S3"] = (__u_surf, (0, h / 2, 0), (pi / 2, 0, 0))
        self.surflist["S4"] = (__l_surf, (0, -h / 2, 0), (pi / 2, 0, 0))

        self.surflist["S5"] = (__lf_surf, (-w / 2, 0, 0), (0, pi / 2, 0))
        self.surflist["S6"] = (__rg_surf, (w / 2, 0, 0), (0, pi / 2, 0))
Beispiel #14
0
class CCD(Component):
    '''Class to define a CCD like detector

    :param size: Tuple with the phisical size (sx,sy)  of the CCD chip
    :type size: tuple(float, float)
    :param transparent: Boolean to set the detector transparent characteristic. 
        Not implemented
    :type transparent: bool
    
    Using the same CCD, images of different resolutions can be simulated. See
    the im_show and spot_diagram methods
    '''

    # Geometrical size of the CCD chip
    #size = Tuple(Float(5),Float(5))

    # Setting this attribute to *False*, make the CCD detector opaque
    #transparent=Bool(True)

    # Private attributes

    # detector surface

    #__d_surf = Instance(ArrayDetector)
    #__d_surf = Instance(Plane)

    def _get_hitlist(self):
        return tuple(self.__d_surf.hit_list)

    hit_list = property(_get_hitlist)
    """List containing a tuple for each ray hitting the CCD. The first component
    of the tuple is the coordinates of intersection of the ray with the CCD 
    (in its coordinate system). The second component of each tuple points to the
    :class:`~pyoptools.raytrace.ray.Ray` that intersected the CCD.
    """

    def __init__(self, size=(10, 10), transparent=True, *args, **kwargs):
        Component.__init__(self, *args, **kwargs)
        self.__d_surf = Plane(
            shape=Rectangular(size=size)
        )  #ArrayDetector (size=self.size, transparent=self.transparent)
        self.size = size
        self.surflist["S1"] = (self.__d_surf, (0, 0, 0), (0, 0, 0))
        self.material = 1.

    #~ def __reduce__(self):
    #~ args=() #self.intensity,self.wavelength,self.n ,self.label,self.parent,self.pop,self.orig_surf)
    #~ return(type(self),args,self.__getstate__())
    #~
    #~
    #~ #TODO: Check if there is a better way to do this, because we are
    #~ #rewriting the constructor values here
    #~
    #~ def __getstate__(self):
    #~ return self.__d_surf,self.size,self.surflist,self.material
    #~
    #~ def __setstate__(self,state):
    #~ self.__d_surf,self.size,self.surflist,self.material=state

    def get_image(self, size=(256, 256)):
        """
        Returns the ccd hit_list as a grayscale PIL image
        
        :param size: Tuple (dx,dy) containing the image size in pixels. Use this 
            a ttribute to set the simulated resolution.
        """
        data = self.__d_surf.get_histogram(size)
        return (fromarray(data))

    def get_color_image(self, size=(256, 256)):
        """
        Returns the CCD hit_list as a color image, using the rays wavelength.
        
        :param size: Tuple (dx,dy) containing the image size in pixels. Use this 
            attribute to set the simulated resolution.
        """

        data = self.__d_surf.get_color_histogram(size)
        return (fromarray(data, high=255, low=0))

    #~ def im_show(self,fig=None, size=(256,256),cmap=cm.gray,title='Image',color=False):
    #~ """Shows a simulated image
#~
#~ *Attributes:*
#~
#~ *size*
#~ Tuple (dx,dy) containing the image size in pixels. Use this
#~ attribute to set the simulated resolution.
#~ *cmap*
#~ Color map to use in the image simulation. See the matplotlib.cm
#~ module for information about colormaps.
#~ *fig*
#~ Pylab figure where the plot will be made. If set to None
#~ a new figure will be created.
#~ """
#~ if fig == None:
#~ fig=figure()
#~
#~ self.__d_surf.im_show(size,cmap,title,color)
#~
#~
#~ def spot_diagram(self,fig=None, style="o",  label=None):
#~ '''Plot a spot diagram in a pylab figure
#~
#~ Method that plots a spot diagram of the rays hitting the CCD.
#~
#~ *Attributes:*
#~
#~ *fig*
#~ Pylab figure where the plot will be made. If set to None
#~ a new figure will be created.
#~
#~ *style*
#~ Symbol to be used to represent the spot. See the pylab plot
#~ documentation for more information.
#~
#~ *label*
#~ String containing the label to show in the figure for this spot diagram.
#~ Can be used to identify different spot diagrams on the same figure.
#~ '''
#~
#~ if fig == None:
#~ fig=figure()
#~ X=[]
#~ Y=[]
#~ COL=[]
#~ if len(self.__d_surf._hit_list) >0:
#~ for i in self.__d_surf._hit_list:
#~ p=i[0]
#~ # Hitlist[1] points to the incident ray
#~ col=wavelength2RGB(i[1].wavelength)
#~ X.append(p[0])
#~ Y.append(p[1])
#~ COL.append(col)
#~ if label== None:
#~ plot(X, Y, style,  figure=fig)
#~ else:
#~ plot(X, Y, style,label=label,figure=fig)
#~ legend()
#~ return fig

    def get_optical_path_map(self, size=(20, 20), mask=None):
        """Return the optical path of the rays hitting the detector.
        
        This method uses the optical path of the rays hitting the surface to 
        create a optical path map. The returned value is an interpolation of the
        values obtained by the rays.
        
        .. warning:: 
 
            If the rays hitting the surface are produced by more than one 
            optical source, the returned map might not be valid.  
        
        :param size: Tuple (nx,ny) containing the number of samples of the 
            returned map. The map size will be the same as the CCD
        :param mask: :class:`~pyoptools.raytrace.shape.Shape`
            instance containing the mask of the aperture. If not given, 
            the mask will be automatically calculated.
        
        :return: A masked array as defined in the numpy.ma module, containing 
            the optical paths
        """

        X, Y, Z = self.get_optical_path_data()

        rv = bisplrep(X, Y, Z)
        nx, ny = size
        xs, ys = self.size
        xi = -xs / 2.
        xf = -xi
        yi = -ys / 2.
        yf = -yi

        xd = linspace(xi, xf, nx)
        yd = linspace(yi, yf, ny)
        data = bisplev(xd, yd, rv)

        if mask != None:
            assert (isinstance(mask, Shape))
            X, Y = meshgrid(xd, yd)
            m = ~mask.hit((X, Y, 0))
            retval = ma.array(data, mask=m)
        else:
            retval = data
        return retval

    def get_optical_path_map_lsq(self, order=10):
        """Return a 2D polinomial describing the the optical path of the 
           rays hitting the detector.
        

        :param order: Order of the polynomial used to fit the data
        
        :return: tuple (e, p) where e es the rms error of the data when compared
           with the returned polynomial, and p is a 
           :class:`~pyoptools.misc.Poly2D.poly2d` instance.
        """

        X, Y, Z = self.get_optical_path_data()
        e, p = polyfit2d(X, Y, Z, order=order)
        return e, p

    def get_optical_path_data(self):
        """Return the optical path of the rays hitting the detector.
        
        This method returns a tuple X,Y,D, containing the X,Y hit points, and 
        D containing the optical path data
        
        .. warning::
 
            If the rays hitting the surface are produced by more than one 
            optical source, the information may not be valid.  
               
        """

        X = []
        Y = []
        Z = []
        for ip, r in self.hit_list:
            x, y, z = ip
            d = r.optical_path()
            X.append(x)
            Y.append(y)
            Z.append(d)

        return X, Y, Z
Beispiel #15
0
    def __init__(
            self,
            outer_diameter=8.0,
            thickness=3.0,
            material=1.5,
            origin="center",
            s1={
                "diameter": 6.0,
                "roc": 3.0,
                "k": -1.5,
                "polycoefficents": (0, 0, 0, 0, 3e-3, 0, -10e-6),
                "max_thickness": None,
            },
            s2=None,
            *args,
            **kwargs):
        Component.__init__(self, *args, **kwargs)

        self.material = material
        self.thickness = thickness
        self.outer_diameter = outer_diameter

        # Fill defaults and put surface definitions into namespaces
        if not "max_thickness" in s1:
            s1["max_thickness"] = None
        if s2 is not None and not "max_thickness" in s2:
            s2["max_thickness"] = None

        s1_defn = SimpleNamespace(**s1)
        if s2 is not None:
            s2_defn = SimpleNamespace(**s2)
        else:
            s2_defn = None
        self.s1_defn, self.s2_defn = (s1_defn, s2_defn)

        # Auto select outer diameter if None
        if self.outer_diameter is None:
            candidates = [s1_defn.diameter]
            if s2 is not None:
                candidates.append(s2_defn.diameter)
            self.outer_diameter = max(candidates)

        # Start side thickness calculation, surfaces will be subtracted from this
        side_thickness = thickness

        # First surface
        s1_surf = Aspherical(
            shape=Circular(radius=0.5 * s1_defn.diameter),
            Ax=1.0 / s1_defn.roc,
            Ay=1.0 / s1_defn.roc,
            Kx=s1_defn.k,
            Ky=s1_defn.k,
            poly=poly1Drot(s1_defn.polycoefficents),
        )
        if s1_defn.max_thickness is None:
            s1_defn.max_thickness = s1_surf.topo(s1_defn.diameter / 2.0, 0)
        side_thickness -= s1_defn.max_thickness
        self.surflist.append((s1_surf, (0, 0, 0), (0, 0, pi / 2)))

        # Second surface
        if s2_defn is None:
            s2_surf = Plane(shape=Circular(radius=0.5 * self.outer_diameter))
        else:
            s2_surf = Aspherical(
                shape=Circular(radius=0.5 * s2_defn.diameter),
                Ax=1.0 / s2_defn.roc,
                Ay=1.0 / s2_defn.roc,
                Kx=s2_defn.k,
                Ky=s2_defn.k,
                poly=poly1Drot(s2_defn.polycoefficents),
            )
            if s2_defn.max_thickness is None:
                s2_defn.max_thickness = s2_surf.topo(s2_defn.diameter / 2.0, 0)
            side_thickness -= s2_defn.max_thickness
        self.surflist.append((s2_surf, (0, 0, thickness), (0, pi, pi / 2)))

        # Outer edge
        if side_thickness > 0:
            outer_edge = Cylinder(radius=self.outer_diameter / 2,
                                  length=side_thickness)
            self.surflist.append((
                outer_edge,
                (0, 0, s1_defn.max_thickness + 0.5 * side_thickness),
                (0, 0, pi / 2),
            ))
        elif side_thickness < 0:
            raise InvalidGeometryException(
                "Lens is not thick enough to support surfaces.")

        # Brim
        self._add_brim(s1_defn, s1_defn.max_thickness)
        if s2_defn is not None:
            self._add_brim(s2_defn, thickness - s2_defn.max_thickness)

        # Apply offset
        self._translate_origin(origin)
Beispiel #16
0
 def __init__(self, size=(10,10), transparent=True,*args,**kwargs):
     Component.__init__(self, *args, **kwargs)
     self.__d_surf= Plane(shape=Rectangular(size=size))#ArrayDetector (size=self.size, transparent=self.transparent)
     self.size=size
     self.surflist["S1"]=(self.__d_surf,(0,0,0),(0,0,0))
     self.material=1.
Beispiel #17
0
class CCD(Component):
    '''**Class to define a CCD like detector**

    *Attributes:*

    *size*
        Tuple with the phisical size of the CCD chip
    *transparent*
        Boolean to set the detector transparent characteristic. Not implemented
    
    Using the same CCD, images of different resolutions can be simulated. See
    the im_show and spot_diagram methods
    '''

    # Geometrical size of the CCD chip
    #size = Tuple(Float(5),Float(5))
    
    # Setting this attribute to *False*, make the CCD detector opaque
    #transparent=Bool(True)

    # Private attributes

    # detector surface

    #__d_surf = Instance(ArrayDetector)
    #__d_surf = Instance(Plane)

    def _get_hitlist(self):
        return tuple(self.__d_surf.hit_list)

    hit_list=property(_get_hitlist)

    def __init__(self, size=(10,10), transparent=True,*args,**kwargs):
        Component.__init__(self, *args, **kwargs)
        self.__d_surf= Plane(shape=Rectangular(size=size))#ArrayDetector (size=self.size, transparent=self.transparent)
        self.size=size
        self.surflist["S1"]=(self.__d_surf,(0,0,0),(0,0,0))
        self.material=1.

    #~ def __reduce__(self):
        #~ args=() #self.intensity,self.wavelength,self.n ,self.label,self.parent,self.pop,self.orig_surf)
        #~ return(type(self),args,self.__getstate__())
    #~ 
    #~ 
    #~ #TODO: Check if there is a better way to do this, because we are 
    #~ #rewriting the constructor values here
    #~ 
    #~ def __getstate__(self):
        #~ return self.__d_surf,self.size,self.surflist,self.material 
        #~ 
    #~ def __setstate__(self,state):
        #~ self.__d_surf,self.size,self.surflist,self.material=state
    
    def get_image(self,size=(256,256)):
        """
        Returns the ccd hit_list as a grayscale PIL image
        
        *Attributes:*
        
        *size*    
                Tuple (dx,dy) containing the image size in pixels. Use this 
                attribute to set the simulated resolution.
        """
        data= self.__d_surf.get_histogram(size)
        return(toimage(data, high=255, low=0,cmin=0,cmax=data.max()))
    
    def get_color_image(self, size=(256,256)):
        """
        Returns the CCD hit_list as a color image, using the rays wavelenght.
        
        *Attributes*
        
        *size*    
                Tuple (dx,dy) containing the image size in pixels. Use this 
                attribute to set the simulated resolution.
        """
        
        data= self.__d_surf.get_color_histogram(size)
        return(toimage(data, high=255, low=0))
        
        
    #~ def im_show(self,fig=None, size=(256,256),cmap=cm.gray,title='Image',color=False):
        #~ """Shows a simulated image
#~ 
        #~ *Attributes:*
        #~ 
        #~ *size*    
                #~ Tuple (dx,dy) containing the image size in pixels. Use this 
                #~ attribute to set the simulated resolution.
        #~ *cmap*    
                #~ Color map to use in the image simulation. See the matplotlib.cm
                #~ module for information about colormaps.
        #~ *fig*
                #~ Pylab figure where the plot will be made. If set to None
                #~ a new figure will be created.
        #~ """
        #~ if fig == None:
            #~ fig=figure()
        #~ 
        #~ self.__d_surf.im_show(size,cmap,title,color)
#~ 
#~ 
    #~ def spot_diagram(self,fig=None, style="o",  label=None):
        #~ '''Plot a spot diagram in a pylab figure
        #~ 
        #~ Method that plots a spot diagram of the rays hitting the CCD.
        #~ 
        #~ *Attributes:*
        #~ 
        #~ *fig*
            #~ Pylab figure where the plot will be made. If set to None
            #~ a new figure will be created.
        #~ 
        #~ *style*
            #~ Symbol to be used to represent the spot. See the pylab plot 
            #~ documentation for more information.
        #~ 
        #~ *label*
            #~ String containig the label to show in the figure for this spot diagram.
            #~ Can be used to identify diferent spot diagrams on the same figure.
        #~ '''
        #~ 
        #~ if fig == None:
            #~ fig=figure()
        #~ X=[]
        #~ Y=[]
        #~ COL=[]
        #~ if len(self.__d_surf._hit_list) >0:
            #~ for i in self.__d_surf._hit_list:
                #~ p=i[0]
                #~ # Hitlist[1] points to the incident ray
                #~ col=wavelength2RGB(i[1].wavelength)
                #~ X.append(p[0])
                #~ Y.append(p[1])
                #~ COL.append(col)
        #~ if label== None:
            #~ plot(X, Y, style,  figure=fig)
        #~ else:
            #~ plot(X, Y, style,label=label,figure=fig)
            #~ legend()
        #~ return fig
        
    def get_optical_path_map(self,size=(20, 20),  mask=None):
        """Return the optical path of the rays hitting the detector.
        
        This method uses the optical path of the rays hitting the surface, to 
        create a optical path map. The returned value is an interpolation of the
        values obtained by the rays.
        
        Warning: 
            If the rays hitting the surface are produced by more than one 
            optical source, the returned map migth not be valid.  
        
        *Atributes*
        
        *size*
            Tuple (nx,ny) containing the number of samples of the returned map.
            The map size will be the same as the CCD
        
        *mask*
            Shape instance containig the mask of the apperture. If not given, 
            the mask will be automatically calculated.
        
        *Return value*
        
        A masked array as defined in the numpy.ma module, containig the optical paths
        """
        
        X,Y,Z=self.get_optical_path_data()    
    
        rv=bisplrep(X,Y,Z)
        nx, ny=size
        xs, ys=self.size
        xi=-xs/2.
        xf=-xi
        yi=-ys/2.
        yf=-yi
        
        xd=linspace(xi, xf,nx)
        yd=linspace(yi, yf,ny)
        data=bisplev(xd,yd,rv)
        
        if mask!=None:
            assert(isinstance(mask, Shape))
            X, Y=meshgrid(xd, yd)
            m= ~mask.hit((X, Y, 0))
            retval= ma.array(data, mask=m)
        else:
            retval=data
        return retval


    def get_optical_path_map_lsq(self,order=10):
        """Return the optical path of the rays hitting the detector.
        
        *Atributes*
        
           """
        
        X,Y,Z=self.get_optical_path_data()    
        e,p=polyfit2d(X, Y, Z, order=order)
        return e,p

    def get_optical_path_data(self):
        """Return the optical path of the rays hitting the detector.
        
        This method returns a tuple X,Y,D, containing the X,Y hit points, and 
        D containing tha optical path data
        
        Warning: 
            If the rays hitting the surface are produced by more than one 
            optical source, the information may not be valid.  
               
        """
        
        X=[]
        Y=[]
        Z=[]
        for ip,r in self.hit_list:
            x,y,z= ip
            d= r.optical_path()
            X.append(x)
            Y.append(y)
            Z.append(d)
               
        return X,Y,Z