def add(self, target, y=None): """ Add a target, or list of targets. :param target: target or list of to be added. :param y: y component if target is x,y pair """ if isinstance(target, ray.RayPencil): # Deal with ray pencil for r in target: if r: self.add(r) elif isinstance(target, list): for t in target: self.add(t) elif isinstance(target, ray.IntensityRay): # Deal with ray self.wavelength = target.wavelength v = target.pointInPlane(self) self.targets.append(v) elif isinstance(target, Vector2d): self.targets.append(Vector2d(target)) elif isinstance(target, float): # Assume x,y given self.tragets.append(Vector2d(target, y)) else: raise TypeError("analysis.TargetPlane.illegal type") return self
def getVector2d(prompt, default = None, maxabs = None): """ Read a Vector2d from the terminal with default and checking for the abs maximum. Format from terminal may be 'x,y' OR '[x,y]', 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: Vector2d :param maxabs: maximum absolutle value of the Vector2d, (defaults to None) :type maxabs: float :return: a Vector2d in specified range. Note: strings will be evaluated to try and form a Vector2d. """ # if maxabs == None: maxabs = float("Inf") while True: val = __getInput(prompt,default) try: if isinstance(val,str): # Its a string val = eval(val) # Eval list vec = Vector2d(val) if abs(vec) <= maxabs: return vec # Success else: logger.error("Abs value of '{0:s}' greater than '{1:6.3e}'".\ format(repr(vec),maxabs)) except (ValueError,NameError,ZeroDivisionError,SyntaxError): logger.error("Conversion of '{0:s}' to Vector2d failed.".format(str(val)))
def addGrid(self, xn, yn=0, radius=float("inf")): """ Fill the TargetPlace with a set regular set of targets :param xn: number of targets across horizontal :param yn: numbers of tarets across if 0 or negative, n will be set to that the targets are on a square grid :param radius: float, have targets only in a masked of specified radius. Note: number of targets will be rounded to ensure an odd number across array so there will always be one at (0,0) """ dx = self.xsize / (xn - 1 + 0.1) # dx = 0.5*self.xsize/(xn/2 + 0.1) if yn > 0: dy = self.ysize / (yn - 1 + 0.1) # dy = 0.5*self.ysize/(yn/2 + 0.1) else: dy = dx yn = int(round(self.ysize / dy)) for j in range(-yn // 2, yn // 2 + 1): for i in range(-xn // 2, xn // 2 + 1): y = dy * j x = dx * i if x*x + y*y < radius*radius and \ abs(x) < self.xsize/2 and abs(y) < self.ysize/2: self.add(Vector2d(x, y)) return self
def main(): # Read in a wavefront wf = WaveFront().fromFile() tprint(repr(wf)) wf.plot() # Make vertical + horizontal plot radius = wf.getRadius() yscan = np.linspace(-radius,radius,11) # x/y positions of points xscan = np.linspace(-radius,radius,11) ws = WavePointSet(radius) # Start with blanks set of points # Make grid of points for y in yscan: for x in xscan: if x*x + y*y <= radius*radius: # Inside circle pt = Vector2d(x,y) wp = WavePoint(wavelength = 0.65).setWithWaveFront(wf,pt) ws.add(wp) # Add to wavepoint set # Fit zernike to 4th orders zw = ws.fitZernike(4) tprint(repr(zw)) tprint("Error is : ",str(ws.zerr)) # Show the fitting error for each component zw.plot() # Plot to same graph #ws.plot() plt.show() # Show the final plot
def centroid(self): """ Get the centriod of the moments as a Vector2d. :return: centroid as a Vector2d """ return Vector2d(self.m10 / self.m00, self.m01 / self.m00)
def pointInPlane(self, plane): """ Method to calcualte where the ray will striked a specified optical surface This does NOT alter the current ray. :param plane: the OpticalPlane. :type plane: :class:`optics.surface.OpticalPlane` or float :return: :class:`vector.Vector2d`, the point in the plane relative to the plane reference point. """ pt = plane.getPoint() if self: d = plane.getDistance(self.position, self.director) return Vector2d(self.position.x + d*self.director.x - pt.x,\ self.position.y + d*self.director.y - pt.y) else: return Vector2d().setInvalid()
def __init__(self, pt, index, coef): """ param pt, two dimensional point giving the location of the origin, param index, the base refrative index param coef the for radial polynomial if form 1,r^2,r^4 .... as a list of floats. """ self.point = Vector2d(pt) self.index = index self.coef = list(coef)
def surfaceVector(self,pos): """ Method to get the Vector2d in the plane for a specified point, assumed to be in the plane. :param pos: three dimensional point in global coordinates. :type pos: Vector3d :return: Vector2d point on plane in local coordinates. """ p = pos - self.getPoint() return Vector2d(p.x,p.y)
def __init__(self,pt = Vector2d() ,pathlength = 0.0 , wavelength = None): """ Basic constructor for a wavepoint :param pt: point in the plane :type pt: Vector2d :param pathlength : the pathlength (default = 0.0) :type pathlength : float :param wavelength : the wavelength (default = wavelength.Default) :type wavelength :float """ self.set(pt) self.pathlength = pathlength self.wavelength = getDefaultWavelength(wavelength)
def draw(self, colour="k"): """ Draw the psf as an ellipse to the current plot axis. :param colour: The colour (Default = "k") :type colour: str or valid Color. """ n = 20 dtheta = 2 * math.pi / n xval = [] yval = [] for i in range(0, n + 1): theta = i * dtheta v = Vector2d(self.major * math.cos(theta), self.minor * math.sin(theta)) v.rotate(-self.alpha) v += Vector2d(self.x, self.y) xval.append(v.x) yval.append(v.y) plot(xval, yval, color=colour) plot([self.x], [self.y], color=colour, marker='x')
def __str__(self): return "{0:s} wl : {1:7.4f} : pl : {2:8.5e}".format(Vector2d.__str__(self),self.wavelength,self.pathlength)
def centroid(self): m = self.get(0, 0) return Vector2d(self.get(1, 0) / m, self.get(0, 1) / m)