Implementation of Object Oriented Optical Element Class for python Optical Simulation

  • 2021-12-11 07:43:37
  • OfStack

Optical element class

The plane mirror is a very simple model, because we only need to consider one plane. But other optical elements can become somewhat complicated: We must consider the behavior of light on the incident plane and the exit plane.

This is certainly a nonsense, and we also have a preliminary solution: split the optical components into front surface and back surface. If light needs to be reflected many times in the optical element, then the optical element can be split into the number of surfaces that need to be reflected many times, which is perfect and mindless.

This shows that we are familiar with programmers' thinking, and the world in our eyes is no longer a WYSIWYG world, but the performance of abstract parts. But don't panic, programmers and normal people may not be very different, because we can not only disassemble the world, but also reconstruct the disassembled parts back to the world.

Try to make the problem more complicated. There are many optical elements in the optical system. Light will pass through each optical element many times, and every time the incident point and the exit point will have a definite deviation. Because the optical element may absorb the energy of light, it causes heat. Moreover, each time the incident point and exit point are different, the heating position is different. Because heating will cause the optical element to deform, the effect of the next light and the optical element will also change.

That is to say, for each optical element, besides the fixed front surface and back surface, there are constantly changing parameters such as incident point, exit point, heating and deformation. Such a practical problem urges us to construct a data type that is closer to reality. In other words, we want to create an object that can encapsulate various variables and functions. If we enter a parameter, the state of this object will change accordingly.

This is called object-oriented.


class Opti():
    def __init__(self,edge1,edge2):
        self.edge1 = edge1
        self.edge2 = edge2

In the above example, we define a class of optical elements, which have two surfaces, which can be either planar or cambered. In this way, we create a class. Among them, __init__ To initialize the method, self Represents the class we created itself. 1 Generally speaking, if the methods in the class do not have modifiers, you must set the self As the first parameter.

self.edge1 Indicates this Opti Class, there is one member named edge1 . When this class is initialized, we can assign values to it.

Some components may have only one surface, such as an all-reflective mirror; Some may have multiple surfaces, such as polarization cubes. Moreover, when we do experiments, we also need to compare different optical elements to get the best experimental results. So, what should we do if we want to change the optical components that have been built?

In fact, it is very simple, as long as you add 1 method, so that you can insert or delete new surfaces.


# Documents Opti.py
class Opti():
    def __init__(self,edges=[[(0,-1),(0,1)],[(0,1),(0,-1),(1/2,0)]]):
        self.edges = [{'index':i,'dots':edges[i]}
                      for i in range(len(edges))]
    #edge Format is (dot1,dot2,...)
    def insertEdge(self,edge,albedo=0):
        self.edges.append(
            {'index':len(self.edges),'dots':edge})
    # Acceptable number and point set 
    def delEdge(self,edge):
        try:
            if isinstance(edge,list):   # If edge The type of is list
                for edg in self.edges:
                    if edg['dots']==edge:
                        edge = edg['index']
            del self.edges[edge]
        except:
            print("no this edge")

In the above code, you can see that the initialization function is preset by 1 value, which is no different from the ordinary function. We can see that the two surfaces inserted by default are planes [(0,-1),(0,1)] And cambered surface [(0,1),(0,-1),(1/2,0)] You can see that 1 plano-convex mirror is generated by default.

Member variable self.edges That is, the list of optical surfaces. Each optical surface has two parameters, which are indexes index Sum point set self0 . From the previous optical abstraction, it can be seen that when there are two points in the point pair, it represents a plane; When there are three points, it represents the arc surface.

Method insertEdge To insert an optical surface, where the optical surface is numbered in self.edges The index number in; delEdge As the name implies, it deletes an optical surface. If the incoming edge Is a list, it means that a surface determined by a parameter is passed in, and at this time, it is passed through traversing self.edges Find this surface and get its index.

If the parameter passed in is a single value, it means that the index number is passed in, so it can be deleted directly.

In this method, a new code block is used try:...except... This is an exception mechanism that attempts to run try: Block, if the run fails, executes the code in the except . If we fail to implement it successfully, delEdge It means that the surface we input is not in this optical element, so the output "no this edge" .

This seems to be the first time I have seen it print What about this command? 1 Generally speaking, this should be the first function to come into contact with. After all, for most programmers, the first line of code typed is


print("hello world")
print('hello world')

At the same time, besides numeric types, we know another data type, that is, characters. In python, a single character or string can be represented by double quotation marks or single quotation marks. That is, in the above hello world code, both lines are correct, and there is no difference.

Now that we have written a class, we can create an object and type:


>>> from Opti import Opti
>>> Opti.__name__   # What the hell 
'Opti'
>>> x = Opti()      # Create an object, which is the default value because no parameters are entered 
>>> x.edges         # Reality class member 
[{'index': 0, 'dots': [(0, -1), (0, 1)]}, {'index': 1, 'dots': [(0, 1), (0, -1), (0.5, 0)]}]
>>> x.delEdge(1)    # Calling class methods 
>>> x.edges         # Sure enough, there are fewer 1 A side 
[{'index': 0, 'dots': [(0, -1), (0, 1)]}]
>>> x.delEdge(1)    # It is impossible to delete edges that do not exist 
no this edge
>>>

First of all, from Opti import Opti The two Opti of are not identical, the former stands for package ` Opti. py ', and the latter stands for class' Opti 'in Opti. py, which can be called after import.

Then there is a paradoxical thing. We don't define it in the class __name__ However, a value is generated after the call.

Please don't panic, it's an old acquaintance. You can set the __name__ Understood as a built-in attribute inside python, when we directly execute a 1. py file, this __name__ The value of is __main__ Otherwise, it is the name of the class. So, by this time, it seems that we should be able to understand the true meaning of the entry function.

Keep going down, and almost everything will be unexpected.

The above is the python optical simulation object-oriented optical element class implementation details, more about the python optical element class implementation information please pay attention to other related articles on this site!


Related articles: