Added some comments on how to create an optical system from the scratch authored by joha2's avatar joha2
## Introduction
# Introduction
Welcome to the pyrate wiki! This wiki is intended for posting status updates,
new ideas, some screenshots, and maybe some introductory documentation.
......@@ -15,7 +15,35 @@ For the underlying physical stuff, please read the fundamental manual. :-)
To reproduce some of the following screenshots you may just play around a bit
with the demo files in the ~~main~~ demos directory: `~/pyrate$ python demos/demo_optimize.py`.
For setting up your own system, you may use one of the convenience functions
The way of defining an optical system is always the same:
* create an empty system via `system = OpticalSystem.p(name="opticalsystem")`
* Notice you may also provide a background material via the `matbackground=mybackgroundmaterial` keyword, which is the intermediate material between optical elements (this is mainly to support immersion media), `None` is equivalent to `ConstantIndexGlass(system.rootcoordinatesystem, 1.0)`
* create an interelated set of `LocalCoordinates` via `lcX = LocalCoordinates.p(name="bla", decx=0., decy=0., decz=0., tiltx=..., tilty=..., tiltz=..., refname=other_localcoordinates.name)`
* where `decx, decy, decz, tiltx, tilty, tiltz` are always in relation to other_localcoordinates
* there is a parameter `tiltThenDecenter` which determines whether the tilt or the decenter should be performed first (this is useful if you want to perform a coordinate transform and directly afterwards the inverse transform which takes the negative values of the former one and in reverse order)
* create surfaces by using `surfX = Surface.p(localcoordinates, shape=..., aperture=...)`
* where `shape` is from `raytracer.surface_shapes` and `aperture` is from `raytracer.apertures`
* create materials from `raytracer.materials....`
* The most simple materials are `ConstantIndexGlass` and `ModelGlass`
* `mymaterial = ConstantIndexGlass.p(material_coordinatesystem, n=1.5)`
* create opticalelements by using `element = OpticalElement.p(localcoordinates, name="opticalelement")`
* add materials and surfaces to optical element
* `element.addMaterial("material", mymaterial)`
* `element.addSurface("surfX", surfX, (material1, material2))` `(material1, material2)` describes the material boundary for a sequential raytracing, using `None` is equivalent for using the background material of the optical system super object
* add element to optical system `system.addElement("element", element)`
* notice: all strings provided in the `add...` functions as first argument are used for sequence in the following
* define sequence of surfaces for sequential raytracing `seq = [("elem1name", [("surf1name", optionsdict1), ("surf2name", optionsdict2), ... ("surfnname", optionsdictn)]), ("elem2name", [ ... ])]`
* in the sequence it is also possible to reuse elements or surfaces, this is for example useful for defining a laser resonator or if an element is to be travelled more than once (like lenses in an interferometric setup)
* optionsdict is usually empty. There are two options possible:
* "is_mirror" (True, False) -> changes the refraction into a reflection
* "is_stop" (True, False) -> used to determine stop for ray aiming
Then raytrace via `raytrace` (or `Aimy` which is highly experimental and located in `pyrateoptics.aim`) and draw via `draw`. `raytrace` and `draw` are defined in `pyrateoptics.__init__.py`.
For setting up your own system, it is recommended to use one of the convenience functions (also defined in `pyrateoptics.__init__.py`) `build_simple_optical_system` or `build_rotational_symmetric_optical_system` for avoiding all the administrative overhead given above (see also the code snippets provided in README.md).
It is further recommended to use an optical system setup by these functions
as a starting point and modify its properties afterwards directly.
```python
import pyrateoptics
from pyrateoptics.core.functionobject import FunctionObject
......
......