{ "info": { "author": "Daniel Cote", "author_email": "dccote@cervo.ulaval.ca", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Education", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.7", "Topic :: Education", "Topic :: Scientific/Engineering :: Physics", "Topic :: Scientific/Engineering :: Visualization" ], "description": "# RayTracing\n\nby [Daniel C\u00f4t\u00e9](mailto:dccote@cervo.ulaval.ca?subject=Raytracing python\u00a0module)\n\n\n\nThis code aims to provide a simple ray tracing module for calculating various properties of optical paths (object, image, aperture stops, field stops). It makes use of ABCD matrices and does not consider aberrations (spherical or chromatic). Since it uses the ABCD formalism (or Ray matrices, or Gauss matrices) it can perform tracing of rays but also gaussian laser beams. \n\nIt is not a package to do \"Rendering in 3D with raytracing\". \n\nThe code has been developed first for teaching purposes and is used in my \"[Optique](https://itunes.apple.com/ca/book/optique/id949326768?mt=11)\" Study Notes (french only), but also for actual use in my research. I have made no attempts at making high performance code. **Readability** and **simplicity of usage** are the key here. It is a module with only a few files, and only `matplotlib` as a dependent module.\n\nThe module defines `Ray` , `Matrix`, `MatrixGroup` and `ImagingPath` as the main elements for tracing rays. `Matrix` and `MatrixGroup` are either one or a sequence of many matrices into which `Ray` will propagate. `ImagingPath` is also a sequence of elements, with an object at the front edge. Specific subclasses of `Matrix` exists: `Space`, `Lens`, `ThicklLens`, and `Aperture`. Finally, a ray fan is a collection of rays, originating from a given point with a range of angles.\n\nIf you want to perform calculations with coherent laser beams, then you use `GaussianBeam` and `LaserPath`. Everything is essentially the same, except that the formalism does not allow for the gaussian beam to be \"blocked\", hence any calculation of stops with aperture are not available in `LaserPath`.\n\n## Installing and upgrading\n\nYou need `matplotlib`, which is a fairly standard Python module. If you do not have it, installing [Anaconda](https://www.anaconda.com/download/) is your best option. You should choose Python 3.7 or later. There are several ways to install the module:\n\n1. Simplest: `pip install raytracing` or `pip install --upgrade raytracing`\n2. If you download the [source](https://pypi.org/project/raytracing/) of the module, then you can type: `python setup.py install`\n3. From GitHub, you can get the latest version (including bugs) and then type `python setup.py install`\n4. If you are completely lost, copying the folder `raytracing` (the one that includes `__init__.py`) from the source file into the same directory as your own script will work.\n\n## Getting started\n\nThe simplest way to import the package in your own scripts after installing it:\n\n```python\nfrom raytracing import *\n```\n\nThis will import `Ray` , `GaussianBeam`, and several `Matrix` elements such as `Space`, `Lens`, `ThickLens`, `Aperture`, `DielectricInterface`, but also `MatrixGroup` (to group elements together), `ImagingPath` (to ray trace with an object at the front edge), `LaserPath` (to trace a gaussian laser beam from the front edge) and a few predefined other such as `Objective` (to create a very thick lens that mimicks an objective).\n\nYou create an `ImagingPath` or a `LaserPath`, which you then populate with optical elements such as `Space`, `Lens` or `Aperture` or vendor lenses. You can then adjust the path properties (object height in `ImagingPath` for instance or inputBeam for `LaserPath`) and display in matplotlib. You can create a group of elements with `MatrixGroup` for instance a telescope, a retrofocus or any group of optical elements you would like to treat as a \"group\". The Thorlabs and Edmund optics lenses, for instance, are defined as `MatrixGroups`.\n\nThis will show you a few examples of things you can do:\n\n```shell\npython -m raytracing\n```\n\nor request help with:\n\n```\npython -m raytracing -h\n```\n\nIn your code, (such as the `test.py` or `demo.py` files included in the [source](https://pypi.org/project/raytracing/)), you would do this:\n\n```python\nfrom raytracing import *\n\npath = ImagingPath()\npath.append(Space(d=100))\npath.append(Lens(f=50, diameter=25))\npath.append(Space(d=120))\npath.append(Lens(f=70))\npath.append(Space(d=100))\npath.display()\n```\n\nYou can also call display() on an element to see the cardinal points, principal planes, BFL and FFL. You can do it with any single `Matrix` element but also with `MatrixGroup`.\n\n```\nfrom raytracing import *\n\nthorlabs.AC254_050_A().display()\neo.PN_33_921().display()\n```\n\n## Documentation\n\nThe class hierarchy for optical elements (with parameters and defaults) is:\n\n![image-20190511230415520](assets/image-20190511230415520.png)\n\nDocumentation is sparse at best. You may obtain help by:\n\n1. Reading an automatically generated documentation from the code (not that good-looking, but at least it is *some* documentation):\n 1. Core: \n 1. [`Ray`](http://htmlpreview.github.io/?https://github.com/DCC-Lab/RayTracing/blob/master/docs/raytracing.ray.html): a ray for geometrical optics with a height and angle $y$ and $\\theta$.\n 2. [`GaussianBeam`](http://htmlpreview.github.io/?https://github.com/DCC-Lab/RayTracing/blob/master/docs/raytracing.gaussianbeam.html): a gaussian laser beam with complex radius of curvature $q$.\n 3. [`Matrix`](http://htmlpreview.github.io/?https://github.com/DCC-Lab/RayTracing/blob/master/docs/raytracing.matrix.html): any 2x2 matrix.\n 4. [`MatrixGroup`](http://htmlpreview.github.io/?https://github.com/DCC-Lab/RayTracing/blob/master/docs/raytracing.matrixgroup.html): treats a group of matrix as a unit (draws it as a unit too)\n 5. [`ImagingPath`](http://htmlpreview.github.io/?https://github.com/DCC-Lab/RayTracing/blob/master/docs/raytracing.imagingpath.html): A `MatrixGroup` with an object at the front for geometrical optics \n 6. [`LaserPath`](http://htmlpreview.github.io/?https://github.com/DCC-Lab/RayTracing/blob/master/docs/raytracing.laserpath.html): A `MatrixGroup` with a laser beam input at the front or a Resonator.\n 2. [Optical elements:](http://htmlpreview.github.io/?https://github.com/DCC-Lab/RayTracing/blob/master/docs/raytracing.matrix.html) `Aperture`, `Space`, `Lens`, `DielectricInterface`, `DielectricSlab`, `ThickLens`\n 3. [Specialty lenses:](http://htmlpreview.github.io/?https://github.com/DCC-Lab/RayTracing/blob/master/docs/raytracing.specialtylenses.html) Defines a general achromat and objective lens\n 4. [Thorlabs lenses:](http://htmlpreview.github.io/?https://github.com/DCC-Lab/RayTracing/blob/master/docs/raytracing.thorlabs.html) Achromat doublet lenses from Thorlabs.\n 5. [Edmund Optics lenses:](http://htmlpreview.github.io/?https://github.com/DCC-Lab/RayTracing/blob/master/docs/raytracing.eo.html) Achromat doublet lenses from Edmund Optics\n 6. [Olympus objectives:](http://htmlpreview.github.io/?https://github.com/DCC-Lab/RayTracing/blob/master/docs/raytracing.olympus.html) A few objectives from Olympus.\n 7. [Glasses:](http://htmlpreview.github.io/?https://github.com/DCC-Lab/RayTracing/blob/master/docs/raytracing.materials.html) A few glasses used by Thorlabs to make achromatic doublets. They all have a single function n(wavelength) that returns the index at that wavelength. All data obtained from http://refractiveindex.info.\n2. typing (interactively): `help(Matrix)`,`help(MatrixGroup)` `help(Ray)`,`help(ImagingPath)` to get the API, \n3. look at the examples with `python -m raytracing` \n4. simply look at the code.\n\n```python\npython\n>>> help(Matrix)\nHelp on class Matrix in module raytracing.abcd:\n\nclass Matrix(builtins.object)\n | Matrix(A, B, C, D, physicalLength=0, apertureDiameter=inf, label='')\n | \n | A matrix and an optical element that can transform a ray or another\n | matrix.\n | \n | The general properties (A,B,C,D) are defined here. The operator \"*\" is\n | overloaded to allow simple statements such as:\n | \n | ray2 = M1 * ray\n | or\n | M3 = M2 * M1\n | \n | The physical length is included in the matrix to allow simple management of\n | the ray tracing. IF two matrices are multiplied, the resulting matrice\n | will have a physical length that is the sum of both matrices.\n | \n | In addition finite apertures are considered: if the apertureDiameter\n | is not infinite (default), then the object is assumed to limit the\n | ray height to plus or minus apertureDiameter/2 from the front edge to the back\n | edge of the element.\n | \n | Methods defined here:\n | \n | __init__(self, A, B, C, D, physicalLength=0, apertureDiameter=inf, label='')\n | Initialize self. See help(type(self)) for accurate signature.\n | \n | __mul__(self, rightSide)\n | Operator overloading allowing easy to read matrix multiplication\n | \n | For instance, with M1 = Matrix() and M2 = Matrix(), one can write\n | M3 = M1*M2. With r = Ray(), one can apply the M1 transform to a ray\n | with r = M1*r\n | \n | __str__(self)\n | String description that allows the use of print(Matrix())\n | \n | backwardConjugate(self)\n | With an image at the back edge of the element,\n | where is the object ? Distance before the element by\n | which a ray must travel to reach the conjugate plane at\n | the back of the element. A positive distance means the\n | object is \"distance\" in front of the element (or to the\n | left, or before).\n | \n | M2 = M1*Space(distance)\n | # M2.isImaging == True\n\n```\n\n## Examples\n\nIn the [examples](https://github.com/DCC-Lab/RayTracing/tree/master/examples) directory, you can run `demo.py` to see a variety of systems, `illuminator.py` to see a Kohler illuminator, and `invariant.py` to see an example of the role of lens diameters to determine the field of view. However, you can also run the module directly with `python -m raytracing`, which will run the following code (`__main__.py`) to give you a flavour of what is possible:\n\n```python\nfrom .imagingpath import *\nfrom .laserpath import *\n\nfrom .specialtylenses import *\nfrom .axicon import *\nimport raytracing.thorlabs as thorlabs\nimport raytracing.eo as eo\nimport raytracing.olympus as olympus\n\nimport argparse\nap = argparse.ArgumentParser(prog='python -m raytracing')\nap.add_argument(\"-e\", \"--examples\", required=False, default='all', help=\"Specific example numbers, separated by a comma\")\n\nargs = vars(ap.parse_args())\nexamples = args['examples']\n\nif examples == 'all':\n examples = range(1,30)\nelse:\n examples = [ int(y) for y in examples.split(',')]\n\nif 1 in examples:\n path = ImagingPath()\n path.label = \"Demo #1: lens f = 5cm, infinite diameter\"\n path.append(Space(d=10))\n path.append(Lens(f=5))\n path.append(Space(d=10))\n path.display(comments= \"\"\"Demo #1: lens with f=5 cm, infinite diameter\n\n An object at z=0 (front edge) is used. It is shown in blue. The image (or any intermediate images) are shown in red.\\n\\\n This will use the default objectHeight and fanAngle but they can be changed with:\n path.objectHeight = 1.0\n path.fanAngle = 0.5\n path.fanNumber = 5\n path.rayNumber = 3\n\n Code:\n path = ImagingPath()\n path.label = \"Demo #1: lens f = 5cm, infinite diameter\"\n path.append(Space(d=10))\n path.append(Lens(f=5))\n path.append(Space(d=10))\n path.display()\n \"\"\")\n\nif 2 in examples:\n path = ImagingPath()\n path.label = \"Demo #2: Two lenses, infinite diameters\"\n path.append(Space(d=10))\n path.append(Lens(f=5))\n path.append(Space(d=20))\n path.append(Lens(f=5))\n path.append(Space(d=10))\n path.display(comments=\"\"\"Demo #2: Two lenses, infinite diameters\n An object at z=0 (front edge) is used with default properties (see Demo #1).\n\n Code:\n path = ImagingPath()\n path.label = \"Demo #2: Two lenses, infinite diameters\"\n path.append(Space(d=10))\n path.append(Lens(f=5))\n path.append(Space(d=20))\n path.append(Lens(f=5))\n path.append(Space(d=10))\n path.display()\n \"\"\")\n # or\n #path.save(\"Figure 2.pdf\")\n\nif 3 in examples:\n path = ImagingPath()\n path.label = \"Demo #3: Finite lens\"\n path.append(Space(d=10))\n path.append(Lens(f=5, diameter=2.5))\n path.append(Space(d=3))\n path.append(Space(d=17))\n path.display(comments=\"\"\"Demo #3: A finite lens\n An object at z=0 (front edge) is used with default properties (see Demo #1). Notice the aperture stop (AS)\n identified at the lens which blocks the cone of light. There is no field stop to restrict the field of view,\n which is why we must use the default object and cannot restrict the field of view. Notice how the default\n rays are blocked.\n\n path = ImagingPath()\n path.objectHeight = 1.0 # object height (full).\n path.objectPosition = 0.0 # always at z=0 for now.\n path.fanAngle = 0.5 # full fan angle for rays\n path.fanNumber = 9 # number of rays in fan\n path.rayNumber = 3 # number of points on object\n path.label = \"Demo #3: Finite lens\"\n path.append(Space(d=10))\n path.append(Lens(f=5, diameter=2.5))\n path.append(Space(d=3))\n path.append(Space(d=17))\n path.display()\n \"\"\")\nif 4 in examples:\n path = ImagingPath()\n path.label = \"Demo #4: Aperture behind lens\"\n path.append(Space(d=10))\n path.append(Lens(f=5, diameter=3))\n path.append(Space(d=3))\n path.append(Aperture(diameter=3))\n path.append(Space(d=17))\n path.display(comments=\"\"\"Demo #4: Aperture behind lens\n\n Notice the aperture stop (AS) identified after the lens, not at the lens. Again, since there is no field stop,\n we cannot restrict the object to the field of view because it is infinite.\n\n Code:\n path = ImagingPath()\n path.label = \"Demo #4: Aperture behind lens\"\n path.append(Space(d=10))\n path.append(Lens(f=5, diameter=3))\n path.append(Space(d=3))\n path.append(Aperture(diameter=3))\n path.append(Space(d=17))\n path.display()\n \"\"\")\nif 5 in examples:\n path = ImagingPath()\n path.label = \"Demo #5: Simple microscope system\"\n path.fanAngle = 0.1 # full fan angle for rays\n path.fanNumber = 5 # number of rays in fan\n path.rayNumber = 5 # number of points on object\n path.append(Space(d=4))\n path.append(Lens(f=4, diameter=0.8, label='Obj'))\n path.append(Space(d=4 + 18))\n path.append(Lens(f=18, diameter=5.0, label='Tube Lens'))\n path.append(Space(d=18))\n path.display(limitObjectToFieldOfView=True, comments=\"\"\"# Demo #5: Simple microscope system\n The aperture stop (AS) is at the entrance of the objective lens, and the tube lens, in this particular microscope, is\n the field stop (FS) and limits the field of view. Because the field stop exists, we can use limitObjectToFieldOfView=True\n when displaying, which will set the objectHeight to the field of view, but will still trace all the rays using our parameters.\n\n path = ImagingPath()\n path.label = \"Demo #5: Simple microscope system\"\n path.fanAngle = 0.1 # full fan angle for rays\n path.fanNumber = 5 # number of rays in fan\n path.rayNumber = 5 # number of points on object\n path.append(Space(d=4))\n path.append(Lens(f=4, diameter=0.8, label='Obj'))\n path.append(Space(d=4 + 18))\n path.append(Lens(f=18, diameter=5.0, label='Tube Lens'))\n path.append(Space(d=18))\n path.display()\n \"\"\")\nif 6 in examples:\n path = ImagingPath()\n path.label = \"Demo #6: Simple microscope system, only principal rays\"\n path.append(Space(d=4))\n path.append(Lens(f=4, diameter=0.8, label='Obj'))\n path.append(Space(d=4 + 18))\n path.append(Lens(f=18, diameter=5.0, label='Tube Lens'))\n path.append(Space(d=18))\n path.display(limitObjectToFieldOfView=True, onlyChiefAndMarginalRays=True,\n comments=\"\"\"# Demo #6: Simple microscope system, only principal rays\n The aperture stop (AS) is at the entrance of the objective lens, and the tube lens, in this particular microscope, is\n the field stop (FS) and limits the field of view. Because the field stop exists, we can use limitObjectToFieldOfView=True\n when displaying, which will set the objectHeight to the field of view. We can also require that only the principal rays are drawn: chief ray\n marginal ray (or axial ray).\n\n path = ImagingPath()\n path.label = \"Demo #6: Simple microscope system, only principal rays\"\n path.append(Space(d=4))\n path.append(Lens(f=4, diameter=0.8, label='Obj'))\n path.append(Space(d=4 + 18))\n path.append(Lens(f=18, diameter=5.0, label='Tube Lens'))\n path.append(Space(d=18))\n path.display()\n \"\"\")\nif 7 in examples:\n path = ImagingPath()\n path.label = \"Demo #7: Focussing through a dielectric slab\"\n path.append(Space(d=10))\n path.append(Lens(f=5))\n path.append(Space(d=3))\n path.append(DielectricSlab(n=1.5, thickness=4))\n path.append(Space(d=10))\n path.display(comments=path.label+\"\"\"\\n\n path = ImagingPath()\n path.label = \"Demo #7: Focussing through a dielectric slab\"\n path.append(Space(d=10))\n path.append(Lens(f=5))\n path.append(Space(d=3))\n path.append(DielectricSlab(n=1.5, thickness=4))\n path.append(Space(d=10))\"\"\"\n )\nif 8 in examples:\n # Demo #8: Virtual image\n path = ImagingPath()\n path.label = \"Demo #8: Virtual image at -2f with object at f/2\"\n path.append(Space(d=2.5))\n path.append(Lens(f=5))\n path.append(Space(d=10))\n path.display(comments=path.label+\"\"\"\\n\n path = ImagingPath()\n path.label = \"Demo #8: Virtual image at -2f with object at f/2\"\n path.append(Space(d=2.5))\n path.append(Lens(f=5))\n path.append(Space(d=10))\n path.display()\"\"\")\nif 9 in examples:\n # Demo #9: Infinite telecentric 4f telescope\n path = ImagingPath()\n path.label = \"Demo #9: Infinite telecentric 4f telescope\"\n path.append(Space(d=5))\n path.append(Lens(f=5))\n path.append(Space(d=10))\n path.append(Lens(f=5))\n path.append(Space(d=5))\n path.display(comments=path.label+\"\"\"\\n\n path = ImagingPath()\n path.label = \"Demo #9: Infinite telecentric 4f telescope\"\n path.append(Space(d=5))\n path.append(Lens(f=5))\n path.append(Space(d=10))\n path.append(Lens(f=5))\n path.append(Space(d=5))\n \"\"\")\nif 10 in examples:\n path = ImagingPath()\n path.fanAngle = 0.05\n path.append(Space(d=20))\n path.append(Lens(f=-10, label='Div'))\n path.append(Space(d=7))\n path.append(Lens(f=10, label='Foc'))\n path.append(Space(d=40))\n (focal,focal) = path.effectiveFocalLengths()\n bfl = path.backFocalLength()\n path.label = \"Demo #10: Retrofocus $f_e$={0:.1f} cm, and BFL={1:.1f}\".format(focal, bfl)\n path.display(comments=path.label+\"\"\"\\n\n A retrofocus has a back focal length longer than the effective focal length. It comes from a diverging lens followed by a converging\n lens. We can always obtain the effective focal lengths and the back focal length of a system.\n\n path = ImagingPath()\n path.fanAngle = 0.05\n path.append(Space(d=20))\n path.append(Lens(f=-10, label='Div'))\n path.append(Space(d=7))\n path.append(Lens(f=10, label='Foc'))\n path.append(Space(d=40))\n (focal,focal) = path.effectiveFocalLengths()\n bfl = path.backFocalLength()\n path.label = \"Demo #10: Retrofocus $f_e$={0:.1f} cm, and BFL={1:.1f}\".format(focal, bfl)\n path.display()\n \"\"\")\nif 11 in examples:\n # Demo #11: Thick diverging lens\n path = ImagingPath()\n path.label = \"Demo #11: Thick diverging lens\"\n path.objectHeight = 20\n path.append(Space(d=50))\n path.append(ThickLens(R1=-20, R2=20, n=1.55, thickness=10, diameter=25, label='Lens'))\n path.append(Space(d=50))\n path.display(onlyChiefAndMarginalRays=True, comments=path.label+\"\"\"\\n\n path = ImagingPath()\n path.label = \"Demo #11: Thick diverging lens\"\n path.objectHeight = 20\n path.append(Space(d=50))\n path.append(ThickLens(R1=-20, R2=20, n=1.55, thickness=10, diameter=25, label='Lens'))\n path.append(Space(d=50))\n path.display()\"\"\")\nif 12 in examples:\n # Demo #12: Thick diverging lens built from individual elements\n path = ImagingPath()\n path.label = \"Demo #12: Thick diverging lens built from individual elements\"\n path.objectHeight = 20\n path.append(Space(d=50))\n path.append(DielectricInterface(R=-20, n1=1.0, n2=1.55, diameter=25, label='Front'))\n path.append(Space(d=10, diameter=25, label='Lens'))\n path.append(DielectricInterface(R=20, n1=1.55, n2=1.0, diameter=25, label='Back'))\n path.append(Space(d=50))\n path.display(onlyChiefAndMarginalRays=True, comments=path.label+\"\"\"\\n\n path = ImagingPath()\n path.label = \"Demo #12: Thick diverging lens built from individual elements\"\n path.objectHeight = 20\n path.append(Space(d=50))\n path.append(DielectricInterface(R=-20, n1=1.0, n2=1.55, diameter=25, label='Front'))\n path.append(Space(d=10, diameter=25, label='Lens'))\n path.append(DielectricInterface(R=20, n1=1.55, n2=1.0, diameter=25, label='Back'))\n path.append(Space(d=50))\n path.display()\"\"\")\n\nif 13 in examples:\n # Demo #13, forward and backward conjugates\n # We can obtain the position of the image for any matrix\n # by using forwardConjugate(): it calculates the distance\n # after the element where the image is, assuming an object\n # at the front surface.\n M1 = Space(d=10)\n M2 = Lens(f=5)\n M3 = M2*M1\n print(M3.forwardConjugate())\n print(M3.backwardConjugate())\nif 14 in examples:\n # Demo #14: Generic objectives\n obj = Objective(f=10, NA=0.8, focusToFocusLength=60, backAperture=18, workingDistance=2, label=\"Objective\")\n print(\"Focal distances: \", obj.focalDistances())\n print(\"Position of PP1 and PP2: \", obj.principalPlanePositions(z=0))\n print(\"Focal spots positions: \", obj.focusPositions(z=0))\n print(\"Distance between entrance and exit planes: \", obj.L)\n\n path = ImagingPath()\n path.fanAngle = 0.0\n path.fanNumber = 1\n path.rayNumber = 15\n path.objectHeight = 10.0\n path.label = \"Demo #14 Path with generic objective\"\n path.append(Space(180))\n path.append(obj)\n path.append(Space(10))\n path.display(comments=path.label+\"\"\"\n path = ImagingPath()\n path.fanAngle = 0.0\n path.fanNumber = 1\n path.rayNumber = 15\n path.objectHeight = 10.0\n path.label = \"Path with generic objective\"\n path.append(Space(180))\n path.append(obj)\n path.append(Space(10))\n path.display()\"\"\")\nif 15 in examples:\n # Demo #15: Olympus objective LUMPlanFL40X\n path = ImagingPath()\n path.fanAngle = 0.0\n path.fanNumber = 1\n path.rayNumber = 15\n path.objectHeight = 10.0\n path.label = \"Demo #15 Path with LUMPlanFL40X\"\n path.append(Space(180))\n path.append(olympus.LUMPlanFL40X())\n path.display(comments=path.label+\"\"\"\n path = ImagingPath()\n path.fanAngle = 0.0\n path.fanNumber = 1\n path.rayNumber = 15\n path.objectHeight = 10.0\n path.label = \"Path with LUMPlanFL40X\"\n path.append(Space(180))\n path.append(olympus.LUMPlanFL40X())\n path.append(Space(10))\n path.display()\"\"\")\nif 16 in examples:\n # Demo #16: Vendor lenses\n thorlabs.AC254_050_A().display()\n eo.PN_33_921().display()\nif 17 in examples:\n # Demo #17: Vendor lenses\n path = ImagingPath()\n path.label = \"Demo #17: Vendor Lenses\"\n path.append(Space(d=50))\n path.append(thorlabs.AC254_050_A())\n path.append(Space(d=50))\n path.append(thorlabs.AC254_050_A())\n path.append(Space(d=150))\n path.append(eo.PN_33_921())\n path.append(Space(d=50))\n path.append(eo.PN_88_593())\n path.append(Space(180))\n path.append(olympus.LUMPlanFL40X())\n path.append(Space(10))\n path.display(comments=path.label+\"\"\"\\n\n path = ImagingPath()\n path.label = \"Demo #17: Vendor Lenses\"\n path.append(Space(d=50))\n path.append(thorlabs.AC254_050_A())\n path.append(Space(d=50))\n path.append(thorlabs.AC254_050_A())\n path.append(Space(d=150))\n path.append(eo.PN_33_921())\n path.append(Space(d=50))\n path.append(eo.PN_88_593())\n path.append(Space(180))\n path.append(olympus.LUMPlanFL40X())\n path.append(Space(10))\n path.display()\"\"\")\nif 18 in examples:\n # Demo #18: Laser beam and vendor lenses\n path = LaserPath()\n path.label = \"Demo #18: Laser beam and vendor lenses\"\n path.append(Space(d=50))\n path.append(thorlabs.AC254_050_A())\n path.append(Space(d=50))\n path.append(thorlabs.AC254_050_A())\n path.append(Space(d=150))\n path.append(eo.PN_33_921())\n path.append(Space(d=50))\n path.append(eo.PN_88_593())\n path.append(Space(d=180))\n path.append(olympus.LUMPlanFL40X())\n path.append(Space(d=10))\n path.display(inputBeam=GaussianBeam(w=0.001), comments=\"\"\"\n path = LaserPath()\n path.label = \"Demo #18: Laser beam and vendor lenses\"\n path.append(Space(d=50))\n path.append(thorlabs.AC254_050_A())\n path.append(Space(d=50))\n path.append(thorlabs.AC254_050_A())\n path.append(Space(d=150))\n path.append(eo.PN_33_921())\n path.append(Space(d=50))\n path.append(eo.PN_88_593())\n path.append(Space(d=180))\n path.append(olympus.LUMPlanFL40X())\n path.append(Space(d=10))\n path.display()\"\"\")\nif 19 in examples:\n cavity = LaserPath(label=\"Laser cavity: round trip\\nCalculated laser modes\")\n cavity.isResonator = True\n cavity.append(Space(d=160))\n cavity.append(DielectricSlab(thickness=100, n=1.8))\n cavity.append(Space(d=160))\n cavity.append(CurvedMirror(R=400))\n cavity.append(Space(d=160))\n cavity.append(DielectricSlab(thickness=100, n=1.8))\n cavity.append(Space(d=160))\n\n # Calculate all self-replicating modes (i.e. eigenmodes)\n (q1,q2) = cavity.eigenModes()\n print(q1,q2)\n\n # Obtain all physical (i.e. finite) self-replicating modes\n qs = cavity.laserModes()\n for q in qs:\n print(q)\n\n # Show\n cavity.display()\n```\n\n\n\n![Figure1](assets/Figure1.png)\n![Microscope](assets/Microscope.png)\n![Illumination](assets/Illumination.png)\n\n## Known limitations\n\nThere are no known bugs in the actual calculations, but there are bugs or limitations in the display:\n\n1. It is not easy to put several labels on a graph without any overlap. I am still working on it.\n2. It is also not easy to figure out what \"the right size\" should be for an arrow head, the font, the position of a label, the size of the \"ticks\" on the aperture.\n3. Labelling focal points with appropriate secondary labels should be possible, maybe a superscript?\n4. The y-scale is not always set appropriately when the elements have infinite diameters: the rays will go beyond the element drawn on the figure.\n\n## Licence\n\nThis code is provided under the [MIT License](./LICENSE).\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/DCC-Lab/RayTracing", "keywords": "optics lenses ray matrices aperture field stop", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "raytracing", "package_url": "https://pypi.org/project/raytracing/", "platform": "", "project_url": "https://pypi.org/project/raytracing/", "project_urls": { "Homepage": "https://github.com/DCC-Lab/RayTracing" }, "release_url": "https://pypi.org/project/raytracing/1.1.11/", "requires_dist": [ "matplotlib" ], "requires_python": ">=3", "summary": "Simple optical ray tracing library to validate the design of an optical system (lenses positions and sizes, focal lengths).", "version": "1.1.11" }, "last_serial": 5946162, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "6f6ce343190210ab9d2cf11529f2a77e", "sha256": "1e843405cb5b19a045556ec206a9584a64a82e294a390cc872de0b23c327f1c2" }, "downloads": -1, "filename": "raytracing-1.0.0-py3.7.egg", "has_sig": false, "md5_digest": "6f6ce343190210ab9d2cf11529f2a77e", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": ">=3", "size": 38363, "upload_time": "2019-02-13T16:02:52", "url": "https://files.pythonhosted.org/packages/37/e0/969dadbc6c0cc6688baaa40a19989a86be3aa5fa398df9536eda0af3aba4/raytracing-1.0.0-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "5cc3764c58c446ecd51afb8b155e5e56", "sha256": "649d276e48ce1aa13e1ba1686ac0a72ede9fd1a986b0a9e42c0f108678911dba" }, "downloads": -1, "filename": "raytracing-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "5cc3764c58c446ecd51afb8b155e5e56", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 4119, "upload_time": "2019-02-13T04:06:10", "url": "https://files.pythonhosted.org/packages/df/9a/05189098a7cd897cdf2d90282d156363c98a45b37a026bee6cd01ac47edb/raytracing-1.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b53e42ea1458d26606330efe05cd73ba", "sha256": "fbe7fe3980e68af8b81b2a9006e06356a6e83dfdb079089f11dffcd8db071fd9" }, "downloads": -1, "filename": "raytracing-1.0.0.tar.gz", "has_sig": false, "md5_digest": "b53e42ea1458d26606330efe05cd73ba", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 17715, "upload_time": "2019-02-13T04:06:12", "url": "https://files.pythonhosted.org/packages/6b/d1/3b675c0b58f4dc406c14e686cfef8c652300a26dabe8f4e974a82105d046/raytracing-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "728c770085de1176124492afc4ffd63b", "sha256": "0cb0b8ccf1025c8c4b6252bcb2b019a9c7734017935ff516e0e27b59082fa0e0" }, "downloads": -1, "filename": "raytracing-1.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "728c770085de1176124492afc4ffd63b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 258354, "upload_time": "2019-02-13T06:25:55", "url": "https://files.pythonhosted.org/packages/98/3b/947c46f8906c740f0c600d8d651c3c2e40127ebc7a480540f0f24e61d0de/raytracing-1.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9007012e022092903368752386dfa9bb", "sha256": "44e78c39305fa57b295f31d278777239e12070439b5d7663d4013a0338b0c3aa" }, "downloads": -1, "filename": "raytracing-1.0.1.tar.gz", "has_sig": false, "md5_digest": "9007012e022092903368752386dfa9bb", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 530989, "upload_time": "2019-02-13T06:25:57", "url": "https://files.pythonhosted.org/packages/c6/b0/9567c441c3b1ed2ae59d31e725d64862a37321c8104ee60638d5e13bbc4d/raytracing-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "b98cff8818794f086baad0bfdf01f9f3", "sha256": "7439651ac04d4da606ccf67ad8fd830ba21b40730f4fa47b2c58ce929b754b31" }, "downloads": -1, "filename": "raytracing-1.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "b98cff8818794f086baad0bfdf01f9f3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 19529, "upload_time": "2019-02-13T16:02:50", "url": "https://files.pythonhosted.org/packages/21/a6/871078f6d8f951795761df5b6671f15aa3ed592e31f78604b5500cd8ce20/raytracing-1.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f1af5b36784ad2cbbaf9fddad1a2b4b4", "sha256": "0a8382244e2022827219190557c77603973c8becfe0357ac3130d1330c0bc630" }, "downloads": -1, "filename": "raytracing-1.0.2.tar.gz", "has_sig": false, "md5_digest": "f1af5b36784ad2cbbaf9fddad1a2b4b4", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 292342, "upload_time": "2019-02-13T16:02:54", "url": "https://files.pythonhosted.org/packages/55/c6/4c879aec2bb41144b5a059be30913cc326db8920509e5091240e3d5541c9/raytracing-1.0.2.tar.gz" } ], "1.0.3": [ { "comment_text": "", "digests": { "md5": "8075aa402aa68f2e55b393b40fbd6881", "sha256": "48d9e4d798ff6d2bbf0e261ef7144162b077d2e1e2ee44e6b6c7fcef5c6b2fa6" }, "downloads": -1, "filename": "raytracing-1.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "8075aa402aa68f2e55b393b40fbd6881", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 20584, "upload_time": "2019-02-14T04:38:39", "url": "https://files.pythonhosted.org/packages/b2/06/d79e91df584407c6eb8b9ccf34fcb069dbbae990b634f56c4750dc3d9c39/raytracing-1.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "699cfb85b783c5947f2e0093795c0c50", "sha256": "6a49591cc5315807dd2fb448938f672cd9db84306a397d1f1347ff0f2ccc9039" }, "downloads": -1, "filename": "raytracing-1.0.3.tar.gz", "has_sig": false, "md5_digest": "699cfb85b783c5947f2e0093795c0c50", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 838821, "upload_time": "2019-02-14T04:38:41", "url": "https://files.pythonhosted.org/packages/38/ef/b4397758a5904a53fb595d4ccec93923350bbdecc010ac546d04ecde42e7/raytracing-1.0.3.tar.gz" } ], "1.0.4": [ { "comment_text": "", "digests": { "md5": "20759daf091b66212e48f7f4866c6357", "sha256": "edb909a9a0d235bd598b05369f433699a5a4d58922f67f5cd54cb04e853c8830" }, "downloads": -1, "filename": "raytracing-1.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "20759daf091b66212e48f7f4866c6357", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 23280, "upload_time": "2019-02-14T16:35:39", "url": "https://files.pythonhosted.org/packages/da/f0/2a3b72759ad6ff7fb8159bb5bb203aa122a87764c29f1f72b2afd06232f5/raytracing-1.0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "de0240f912ce53088645cdf6b0028000", "sha256": "a84cd7feb86314fdaecfd7d7145f566005c4837ea04167046602bc94737b8269" }, "downloads": -1, "filename": "raytracing-1.0.4.tar.gz", "has_sig": false, "md5_digest": "de0240f912ce53088645cdf6b0028000", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 843709, "upload_time": "2019-02-14T16:35:41", "url": "https://files.pythonhosted.org/packages/ae/c8/bd838ef6a43acbb48ff803a9fc57205306cf40b1795ba081807c540fcefc/raytracing-1.0.4.tar.gz" } ], "1.0.5": [ { "comment_text": "", "digests": { "md5": "623300d45f71edee386edf1fbead5812", "sha256": "9cc33345ef3bcc3876f8d8bcba423e137ac36fc11571ea4d993b69c51c0b235a" }, "downloads": -1, "filename": "raytracing-1.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "623300d45f71edee386edf1fbead5812", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 23923, "upload_time": "2019-02-15T03:01:31", "url": "https://files.pythonhosted.org/packages/1d/97/82738a35e4c0e5f113e09b00c72cb49eaab3bd1a0a72990bfbdd186bc538/raytracing-1.0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e3bc2cdc1617a21a9ab563e9f39503d7", "sha256": "f469e523d09b3c6b91b11361bc179770e64f77660f6ce56d942aa194dabec93b" }, "downloads": -1, "filename": "raytracing-1.0.5.tar.gz", "has_sig": false, "md5_digest": "e3bc2cdc1617a21a9ab563e9f39503d7", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 844739, "upload_time": "2019-02-15T03:01:34", "url": "https://files.pythonhosted.org/packages/bb/f9/bf07765d7218901ff3810b038d28c5efe3fb3394e3213afe85a67f37654f/raytracing-1.0.5.tar.gz" } ], "1.0.6": [ { "comment_text": "", "digests": { "md5": "9bc0a777f2d776b2806c43bf1777d2c2", "sha256": "28b0a8cb2506023acd7b584399796ccceb6c09756c6b79dccf99288711bda957" }, "downloads": -1, "filename": "raytracing-1.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "9bc0a777f2d776b2806c43bf1777d2c2", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 23927, "upload_time": "2019-02-15T03:13:10", "url": "https://files.pythonhosted.org/packages/f8/09/dee7888517595653b9dee67346672fdbb2fcd911f6b52c73b5f0bbc1741c/raytracing-1.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "329031750865a319ce89721cf303a5af", "sha256": "f99ef81d4a4da72aed1bd458c717ccb20984d6d10c925003a21c53bddc4cf23a" }, "downloads": -1, "filename": "raytracing-1.0.6.tar.gz", "has_sig": false, "md5_digest": "329031750865a319ce89721cf303a5af", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 844757, "upload_time": "2019-02-15T03:13:12", "url": "https://files.pythonhosted.org/packages/29/00/e07c98277f21e84e60badeea9a5ebf7b41ba5b53f2a8a200ec2c178d4597/raytracing-1.0.6.tar.gz" } ], "1.0.7": [ { "comment_text": "", "digests": { "md5": "502084d908608cf48a9fd26bb7936789", "sha256": "ee5cd22729b82f1d851be1448270944a092cc45cfafa8948be4ad3eacae9efb9" }, "downloads": -1, "filename": "raytracing-1.0.7-py3.7.egg", "has_sig": false, "md5_digest": "502084d908608cf48a9fd26bb7936789", "packagetype": "bdist_egg", "python_version": "3.7", "requires_python": ">=3", "size": 57484, "upload_time": "2019-02-22T03:10:33", "url": "https://files.pythonhosted.org/packages/d5/bb/aafdb2fd22c47b153e081cb2e8b4e913c1b89f372a073db6508f6f33a87f/raytracing-1.0.7-py3.7.egg" }, { "comment_text": "", "digests": { "md5": "566ac94dd341323e7e4783b0b49cb61a", "sha256": "468caa12c86909865d2a0cdd3145e97318607ca173a0a1b054321b7abb142780" }, "downloads": -1, "filename": "raytracing-1.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "566ac94dd341323e7e4783b0b49cb61a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 28579, "upload_time": "2019-02-22T03:10:32", "url": "https://files.pythonhosted.org/packages/00/dc/15a58f5ac298fdf38a17a0dfc48f1dfd7a7786a2cebd96d86e6752ad7962/raytracing-1.0.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2532512a1e636909c3927996fb8b27b7", "sha256": "345e218df3a97e254692216fc25f6ca6d14fcb2ecb14b6e38cadc64db1b1c085" }, "downloads": -1, "filename": "raytracing-1.0.7.tar.gz", "has_sig": false, "md5_digest": "2532512a1e636909c3927996fb8b27b7", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 846755, "upload_time": "2019-02-22T03:10:35", "url": "https://files.pythonhosted.org/packages/18/79/b7bac27117b571c19fb85d0b10048050381deceafb35afb92f1f0f778ecb/raytracing-1.0.7.tar.gz" } ], "1.0.8": [ { "comment_text": "", "digests": { "md5": "2ac88d90009cced41c6afe70966e9ae4", "sha256": "dd1578b7b37844826883c132e6a3f713d121f7b1a20c3ce19ff59e3ee6052d17" }, "downloads": -1, "filename": "raytracing-1.0.8-py3-none-any.whl", "has_sig": false, "md5_digest": "2ac88d90009cced41c6afe70966e9ae4", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 28624, "upload_time": "2019-02-26T21:14:04", "url": "https://files.pythonhosted.org/packages/78/cb/f52a2d161d531e0702c55e47d67ad047608fffad0079a04af1402fc4512c/raytracing-1.0.8-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "eec33f891e48380ad05460123f26f93f", "sha256": "fd1f0cd27a2badedc2686dcd6e599b8c17f57e3bca89637f5b919adddcb2054e" }, "downloads": -1, "filename": "raytracing-1.0.8.tar.gz", "has_sig": false, "md5_digest": "eec33f891e48380ad05460123f26f93f", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 846832, "upload_time": "2019-02-26T21:14:06", "url": "https://files.pythonhosted.org/packages/ad/7b/690f9e8fda7ffc4c25642072767ac7b80b243be17173aaa8e19e9c794dde/raytracing-1.0.8.tar.gz" } ], "1.0.9": [ { "comment_text": "", "digests": { "md5": "aa73cb623ae43ee70bdd5eef4a64072a", "sha256": "0dc990ea5da0e99d9519bc31780069e500b112813bd15fbfb31afd58a4da1248" }, "downloads": -1, "filename": "raytracing-1.0.9-py3-none-any.whl", "has_sig": false, "md5_digest": "aa73cb623ae43ee70bdd5eef4a64072a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 30269, "upload_time": "2019-03-02T19:56:13", "url": "https://files.pythonhosted.org/packages/c5/8f/a9bbfcc48115d721de11386c55a5e2201cf08ca29c2acfa2e0458bd4b0d1/raytracing-1.0.9-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e874df57614a5c1e0910684f6ddf9bdb", "sha256": "86bc26f4a9d4cc15be2493859838b9eb02a8da3572da599f25c0aca29e4b3e12" }, "downloads": -1, "filename": "raytracing-1.0.9.tar.gz", "has_sig": false, "md5_digest": "e874df57614a5c1e0910684f6ddf9bdb", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 851210, "upload_time": "2019-03-02T19:56:15", "url": "https://files.pythonhosted.org/packages/52/ea/992ecd89057354107ff3c7986e808d2d4cdee363558d5addc42dfd031267/raytracing-1.0.9.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "28e7700260e173451f661ad652bcc078", "sha256": "4a64f8741f7f4f32fc994b57e9293d992208fe654cdd68f61c228790d2b4104b" }, "downloads": -1, "filename": "raytracing-1.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "28e7700260e173451f661ad652bcc078", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 32308, "upload_time": "2019-03-07T04:08:03", "url": "https://files.pythonhosted.org/packages/f2/7f/3ef35afddff9663bddded2d96d7982f30e4e20675c8ccb977a1cb4d772d5/raytracing-1.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "309b0c37355c8ab7490220d912ab9eb6", "sha256": "c2c7aa2c9c9a1f08fee6611b5bf7b049b43668e43b9ef06abeb2dcdfc6ab4273" }, "downloads": -1, "filename": "raytracing-1.1.0.tar.gz", "has_sig": false, "md5_digest": "309b0c37355c8ab7490220d912ab9eb6", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 854260, "upload_time": "2019-03-07T04:08:08", "url": "https://files.pythonhosted.org/packages/aa/a7/fb43b8e0069e23f61134c666f1f5784ff2b9b494d3f6ddafb248b9e2c108/raytracing-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "733f663790c8e16ab9ed3eb32c002fbc", "sha256": "c4c898d3c0162588f9d834a64732b2f15892529489a8cb1eed5dd42443bdec4b" }, "downloads": -1, "filename": "raytracing-1.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "733f663790c8e16ab9ed3eb32c002fbc", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 34561, "upload_time": "2019-03-09T05:14:27", "url": "https://files.pythonhosted.org/packages/68/f1/8d87c237161c3c86758376eb243c00126f837514c5b3b84f9bfac760447d/raytracing-1.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "45131b4f3f2678899dfa7b3b076aec04", "sha256": "d88a4c3faaef65f1533c98ed64e8e4efd34546656ed361666638f722ade802de" }, "downloads": -1, "filename": "raytracing-1.1.1.tar.gz", "has_sig": false, "md5_digest": "45131b4f3f2678899dfa7b3b076aec04", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 856618, "upload_time": "2019-03-09T05:14:29", "url": "https://files.pythonhosted.org/packages/ed/94/64f2a9e63fe814665705911f7f976ed327da31b69d21ccc6898acaa1c2a0/raytracing-1.1.1.tar.gz" } ], "1.1.10": [ { "comment_text": "", "digests": { "md5": "1e39f87bf728fd392b0edcf13b27593b", "sha256": "c0209716eb401837ffe51f4da12d3287b85a92f0821baeb4fc459bc924f44764" }, "downloads": -1, "filename": "raytracing-1.1.10-py3-none-any.whl", "has_sig": false, "md5_digest": "1e39f87bf728fd392b0edcf13b27593b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 63964, "upload_time": "2019-10-08T18:48:52", "url": "https://files.pythonhosted.org/packages/b5/75/49d4e31effeaa8caa79b13727d95500055eb7aa8f810ca2145760d505669/raytracing-1.1.10-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "501d0662de3b79854b3b058a985b4b4e", "sha256": "7983dd6ed5606c881a6646fce6de14b5c7e35cb07a05eb3cbc6c80a66be61fbe" }, "downloads": -1, "filename": "raytracing-1.1.10.tar.gz", "has_sig": false, "md5_digest": "501d0662de3b79854b3b058a985b4b4e", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 1099872, "upload_time": "2019-10-08T18:48:55", "url": "https://files.pythonhosted.org/packages/1f/21/7920464134cc428e61d6abede583aa6a684bb419bf6a3a61556716a1df4f/raytracing-1.1.10.tar.gz" } ], "1.1.11": [ { "comment_text": "", "digests": { "md5": "d503015513e7503700f5d341e7ffb8c6", "sha256": "ca339d728547083f891264a5a8566cc869f84e881a026a34ca4ff630c81bfec4" }, "downloads": -1, "filename": "raytracing-1.1.11-py3-none-any.whl", "has_sig": false, "md5_digest": "d503015513e7503700f5d341e7ffb8c6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 63965, "upload_time": "2019-10-08T18:51:18", "url": "https://files.pythonhosted.org/packages/bb/a9/f2c394c76d679f1b0aef4d82115866887f90fcd76d913cde2245fa02fc31/raytracing-1.1.11-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0751e575ec319c18646756ad59ab8c1e", "sha256": "92f0e6bbedb15540dda972299fcc9d0eeebf357b272208a767f195bc584d1944" }, "downloads": -1, "filename": "raytracing-1.1.11.tar.gz", "has_sig": false, "md5_digest": "0751e575ec319c18646756ad59ab8c1e", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 1099865, "upload_time": "2019-10-08T18:51:21", "url": "https://files.pythonhosted.org/packages/71/3c/3fd6db95b9ac1e4c6f292e77eea5024f7f9e9cbf1fa1c56be44eb366e81c/raytracing-1.1.11.tar.gz" } ], "1.1.2": [ { "comment_text": "", "digests": { "md5": "f189155b3c3fd7ac6d7b0faaf894f58d", "sha256": "4ab2f0305cd4978d4f3c43b3dd7a3a4925a6471a422dcde2791166daf6f4e29a" }, "downloads": -1, "filename": "raytracing-1.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "f189155b3c3fd7ac6d7b0faaf894f58d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 34882, "upload_time": "2019-03-09T15:09:54", "url": "https://files.pythonhosted.org/packages/9d/dc/70be9d3aea19655a8d988f262ab76a324295fbace5de3b834d6dae1c3892/raytracing-1.1.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3b5f37cbb918aba394d77bf75e0fde93", "sha256": "b062528c36be31f1142b88b4b2a88125b4f1c1b16582078c21c3920173ca7385" }, "downloads": -1, "filename": "raytracing-1.1.2.tar.gz", "has_sig": false, "md5_digest": "3b5f37cbb918aba394d77bf75e0fde93", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 856946, "upload_time": "2019-03-09T15:09:56", "url": "https://files.pythonhosted.org/packages/23/cb/2577d9c97bc96e6fd5deed62cb76008411a87cb70512c56d65cb41e2cacf/raytracing-1.1.2.tar.gz" } ], "1.1.3": [ { "comment_text": "", "digests": { "md5": "1d19e61be56f80de706b6e54a3abb2d8", "sha256": "4b0339d81cf61288a9906f5bf49fe6237ac0df04fcdd0933d3156adc0feb1bc4" }, "downloads": -1, "filename": "raytracing-1.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "1d19e61be56f80de706b6e54a3abb2d8", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 35356, "upload_time": "2019-03-12T12:07:30", "url": "https://files.pythonhosted.org/packages/d7/87/120732ea06aeee24ffad198daa339076e76418573c7c85d7b391f494e6fc/raytracing-1.1.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4ce00e93c0fc6855f66d330df0d258ea", "sha256": "5d357c91b73e187286a74723b623d70e1499cca642d8ef4fa7f4e8011a9620ee" }, "downloads": -1, "filename": "raytracing-1.1.3.tar.gz", "has_sig": false, "md5_digest": "4ce00e93c0fc6855f66d330df0d258ea", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 857533, "upload_time": "2019-03-12T12:07:31", "url": "https://files.pythonhosted.org/packages/74/72/51945356a81ae286d585684229f8cffca0abcf2d1c0ec38c708ffcb6cf50/raytracing-1.1.3.tar.gz" } ], "1.1.4": [ { "comment_text": "", "digests": { "md5": "ec5616d86afe82a5cc33cac1f6756c8f", "sha256": "cb3fe899401f06a651905989a3446b2b5d2956db5562150e89765b1359f7897a" }, "downloads": -1, "filename": "raytracing-1.1.4-py3-none-any.whl", "has_sig": false, "md5_digest": "ec5616d86afe82a5cc33cac1f6756c8f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 35398, "upload_time": "2019-03-12T14:53:05", "url": "https://files.pythonhosted.org/packages/08/3a/bc59620f890022ce5c4ad070b700ebef630be05f94cba541a3d4a96a773f/raytracing-1.1.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ca2e7ca3a77973a81f6cb14f4c6fdec9", "sha256": "9468889f0bb8b0513881629add84cc0afbab8b62ef4a056f8d2a08a7bf7cf09f" }, "downloads": -1, "filename": "raytracing-1.1.4.tar.gz", "has_sig": false, "md5_digest": "ca2e7ca3a77973a81f6cb14f4c6fdec9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 857563, "upload_time": "2019-03-12T14:53:06", "url": "https://files.pythonhosted.org/packages/7f/fb/c36f5e4d865ebc0245fe5b34aac067ee314b6160325d1c484cb474f825f0/raytracing-1.1.4.tar.gz" } ], "1.1.5": [ { "comment_text": "", "digests": { "md5": "379eb11805d1a8506a8a4f53543c1a6e", "sha256": "09a80f356f4ccfbcfb096ea2a2c2ae11796a0189fe8f92bb6226a56aad938d08" }, "downloads": -1, "filename": "raytracing-1.1.5-py3-none-any.whl", "has_sig": false, "md5_digest": "379eb11805d1a8506a8a4f53543c1a6e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 36894, "upload_time": "2019-04-07T20:12:30", "url": "https://files.pythonhosted.org/packages/ee/ed/d85ae07c099d6ad867d3fd15335a8686c012a0911221ca17464f82495828/raytracing-1.1.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9b8bc7273156d2d97c9450d4bbf90530", "sha256": "0cba283f6109755cbe2aeceee16d5eb3b0151bc7abd4645698d8c724dbe6f4d9" }, "downloads": -1, "filename": "raytracing-1.1.5.tar.gz", "has_sig": false, "md5_digest": "9b8bc7273156d2d97c9450d4bbf90530", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 859131, "upload_time": "2019-04-07T20:12:35", "url": "https://files.pythonhosted.org/packages/dc/0e/aa926d471b09689b095edc7f527202740371c1d09a6002cf67cbd185ef6c/raytracing-1.1.5.tar.gz" } ], "1.1.6": [ { "comment_text": "", "digests": { "md5": "30ba3df54d00cdf7a3b4d1b5285c648d", "sha256": "9b5900194ff84fabbbf24c62e34922af9fbe19560b842a779eee78547d38408c" }, "downloads": -1, "filename": "raytracing-1.1.6-py3-none-any.whl", "has_sig": false, "md5_digest": "30ba3df54d00cdf7a3b4d1b5285c648d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 36980, "upload_time": "2019-04-10T12:21:33", "url": "https://files.pythonhosted.org/packages/62/ba/25519c13e5ce3128e402f1386ec3ff1e031123dbcd9fbd5a4fd6be074f24/raytracing-1.1.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2ee72f624e33b63556d1dfb8bfa014cd", "sha256": "953c977fe38eb85605ec58d8a15e3e8c36b9024028e7a26d69b04b47f05a317e" }, "downloads": -1, "filename": "raytracing-1.1.6.tar.gz", "has_sig": false, "md5_digest": "2ee72f624e33b63556d1dfb8bfa014cd", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 859336, "upload_time": "2019-04-10T12:21:35", "url": "https://files.pythonhosted.org/packages/26/0b/973ba11e1cde9331d6fab2f5e23138b9909f49243aadc37751c574d089e3/raytracing-1.1.6.tar.gz" } ], "1.1.7": [ { "comment_text": "", "digests": { "md5": "c579bd76d9322b870f95d56287c816a7", "sha256": "2476de4d170688e3c598634f4646aee34460c667ba126743670abb658be7afbe" }, "downloads": -1, "filename": "raytracing-1.1.7-py3-none-any.whl", "has_sig": false, "md5_digest": "c579bd76d9322b870f95d56287c816a7", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 37725, "upload_time": "2019-04-11T12:47:22", "url": "https://files.pythonhosted.org/packages/94/ad/d4206d3af23db11faadc5786c4ff200fecbc121c319c23b7d3f10fb04c86/raytracing-1.1.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c53692c9f1134ff9f2d358ccfb33f63c", "sha256": "2d33464d4490447d537efe84f86e21280a3752d2ef55eb087dada31f5b4482ff" }, "downloads": -1, "filename": "raytracing-1.1.7.tar.gz", "has_sig": false, "md5_digest": "c53692c9f1134ff9f2d358ccfb33f63c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 860033, "upload_time": "2019-04-11T12:47:25", "url": "https://files.pythonhosted.org/packages/ea/76/6aa465c3393834b53d48262e4a1d7a7d5d47823061b991f62e93ce360fc1/raytracing-1.1.7.tar.gz" } ], "1.1.8": [ { "comment_text": "", "digests": { "md5": "5b4a13e83694573ec56eea6b0fb41dec", "sha256": "59d126060b1c44fc4cadc5ed4cfa050504ea69fd4df8b24d6a717295148133bc" }, "downloads": -1, "filename": "raytracing-1.1.8-py3-none-any.whl", "has_sig": false, "md5_digest": "5b4a13e83694573ec56eea6b0fb41dec", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 298062, "upload_time": "2019-05-12T04:44:20", "url": "https://files.pythonhosted.org/packages/31/94/0cfaabaf12965de2e8f9ea31c6e34f361d3924663a83d757ee4187abf727/raytracing-1.1.8-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "39ca7e4dbe0a9563db8784582f70e27f", "sha256": "548ae323030880f4811ee320c33432456525286d6eaea8e579de446e109a4755" }, "downloads": -1, "filename": "raytracing-1.1.8.tar.gz", "has_sig": false, "md5_digest": "39ca7e4dbe0a9563db8784582f70e27f", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 1099321, "upload_time": "2019-05-12T04:44:23", "url": "https://files.pythonhosted.org/packages/b3/f5/e953efc7ec890d80ed2a76b8bb2b23960020def91cf72842c6e28e3766ab/raytracing-1.1.8.tar.gz" } ], "1.1.9": [ { "comment_text": "", "digests": { "md5": "5a0a63556f608e1532ade82a8497bcf7", "sha256": "d9623f89b6179c0efa8582c957b217e3cf8f37c7c2543a499e9766ed8dbcd400" }, "downloads": -1, "filename": "raytracing-1.1.9-py3-none-any.whl", "has_sig": false, "md5_digest": "5a0a63556f608e1532ade82a8497bcf7", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 63598, "upload_time": "2019-05-29T15:54:17", "url": "https://files.pythonhosted.org/packages/55/03/ec5015fe123a3b78f4918dd2981e06f297c85033d4a3492165cff4cbad58/raytracing-1.1.9-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "15087fa5326e4c13c1ed003ce207b1d3", "sha256": "2fd29be1cd05ee3d4ece257e4ebb2fccbcdf874ba342f52418ccba93a3dca432" }, "downloads": -1, "filename": "raytracing-1.1.9.tar.gz", "has_sig": false, "md5_digest": "15087fa5326e4c13c1ed003ce207b1d3", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 1099433, "upload_time": "2019-05-29T15:54:20", "url": "https://files.pythonhosted.org/packages/7a/1a/9be6c4ee7fc6772bd8ede52cb0d7b7c3069cb4cd29d0cfa125284584f12a/raytracing-1.1.9.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d503015513e7503700f5d341e7ffb8c6", "sha256": "ca339d728547083f891264a5a8566cc869f84e881a026a34ca4ff630c81bfec4" }, "downloads": -1, "filename": "raytracing-1.1.11-py3-none-any.whl", "has_sig": false, "md5_digest": "d503015513e7503700f5d341e7ffb8c6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 63965, "upload_time": "2019-10-08T18:51:18", "url": "https://files.pythonhosted.org/packages/bb/a9/f2c394c76d679f1b0aef4d82115866887f90fcd76d913cde2245fa02fc31/raytracing-1.1.11-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0751e575ec319c18646756ad59ab8c1e", "sha256": "92f0e6bbedb15540dda972299fcc9d0eeebf357b272208a767f195bc584d1944" }, "downloads": -1, "filename": "raytracing-1.1.11.tar.gz", "has_sig": false, "md5_digest": "0751e575ec319c18646756ad59ab8c1e", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 1099865, "upload_time": "2019-10-08T18:51:21", "url": "https://files.pythonhosted.org/packages/71/3c/3fd6db95b9ac1e4c6f292e77eea5024f7f9e9cbf1fa1c56be44eb366e81c/raytracing-1.1.11.tar.gz" } ] }