Replies: 2 comments 5 replies
-
Thanks for taking the time to write this up. I may this up into several responses, cause it's late here and there are a variety of questions :-) First, as far as python is concerned, I've tried to follow the PEP8 guidelines and more generally items in the Effective Python book. One aspect of the latter (among many) is the advocacy of public instance variables instead of getters and setters. There are a few cases where I've transitioned to python properties, where additional flexibility was needed. Certainly one aspect of working in a python environment (vs using a compiled program) is that you can get at everything. You clearly appreciate this and are understandably uneasy. Almost all class instance variables in ray-optics are public; they really should be public attributes. There are a few cases where a leading underscore is used; this can be related to changing an attribute to a property. So don't feel bad about changing values directly; that's how its done. To your specific example, flipping a single lens around is the most straightforward using the sequential model, sm. For your case you can do the following: |
Beta Was this translation helpful? Give feedback.
-
Continuing with the use case I have successfully flipped surfaces of the lens.
This seems to work just fine.
Obviously this is not the right approach, because most of my plotting attempts throw errors now. |
Beta Was this translation helpful? Give feedback.
-
I have started playing around with this library recently and I'm still trying to get my head around how to use it and what I am not supposed to do. I got a first idea by going through the example code given in the documentation but without the chapter "Models and Representations" I would have to stick closely to the examples and I certainly would not be able to use it as a tool. But there are still a lot of assumptions I have to make. I try to back my guesses as good as I can by having a glimpse at the source but since Python does not provide private methods it's not always clear what's part of the API and what's for internal purposes. Are there any conventions that I can follow, like "names with leading underscores are private" for instance, or "stick to getters and setters"?
To my understanding the optical system aka
OpticalModel
can be configured and even altered using one of 5 interfaces (4 models and the specs) at a time. After changes were made to one of the models its method 'model_update' must bet called before another interface can be used. The fact thatOpticalModel
itself has an 'model_update' method seems counterintuitive to me. (Are updates never ambiguous anyway?)Sometimes I might be using the library in a way it is not meant to be used. Here is a use case:
I read that single meniscus lenses were used in early photography and so I downloaded a Zemax file in order play with it. Contrary to the file the lens was used with the concave side facing the object. Instead of editing the file directly I decided to try to flip the lens in Python. Since the
ElementModel
does not yet provide that feature I tried using theSequentialModel
.[snip]
The
SequentialModel
was as expected, theOpticalSpecs
not so.SpecSheet:
infinite conjugates:
imager: IdealImager(m=-0.0, s=-inf, sp=99.6611978424791, tt=inf, f=99.6611978424791)
imager inputs: {'s': -inf}
frozen imager inputs: [True, True, True, True, False]
etendue inputs:
field: {'object': {'angle': 0.0}, 'image': {}}
aperture: {'object': {'pupil': 22.86}, 'image': {}}
etendue values:
field: {'object': {'angle': 0.0}, 'image': {'height': 0.0}}
aperture:
object: {'pupil': 22.86, 'NA': 0, 'f/#': 0}
image: {'f/#': -4.359632451552017, 'NA': 0.11394165154571817, 'pupil': -22.86}
What are the 'etendue inputs' and 'etendue values' and how are they related to
OpticalSpecs
'sFieldSpec
andPupilSpec
properties? Why do the wavelengths and focus range specification not show up? If I want to make changes, shall I edit the specsheet or replace the spec objects with new instances?Editing the surface values in place seems to work (in that case) but since there are no getters and setters I shied away from doing so and followed the code sample from chapter "Triplet example".
SequentialModel:
c t medium mode zdr sd
Obj: 0.000000 1.00000e+10 air 1 0.0000
Stop: -0.012161 3.59000 N-BK7 1 11.430
2: -0.031114 92.6947 air 1 11.537
Img: 0.000000 0.00000 1 0.80125
[snip]
Was this really the official way to get and set the object distance?
Why are the semi diameter values different now?
Without detailed understanding of the inner processes I always have that feeling of uncertainty whether I've used the tool correctly or in a way that leads to unexpected results. The amount of thought and expertise contained in this library is definitely worth the effort of a cosmetic overhaul. If I had better understanding and weren't new to Python I would volunteer.
Cheers!
Beta Was this translation helpful? Give feedback.
All reactions