-
Notifications
You must be signed in to change notification settings - Fork 31
Refactor simulation #141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Refactor simulation #141
Conversation
@viljarjf I would love to be convinced that it is fine to leave, but for the time being the simulation just does not work for me, which has an opposite effect. I get no errors no log messages, but neither do I get an image. Neither brightness nor dynamical range affects it. Maybe there are some special steps to set it up? ![]() Edit: I played with it a bit and I DID see diffraction for a second or so, but it disappeared and I could never get it back. So it definitely does work, but given that I though it doesn't does means user might think so as well. It does not fill me with much confidence for the time being... |
Strange. Perhaps there are no crystals in that area? Could you try changing to very low magnification and see if any show up? A more user-friendly experience is necessary regardless, i agree |
I played with it a bit and found a lot of issues. I started writing a structured response, but after a lot of writing and testing I realized that the behavior of Instamatic was changing for me as I kept writing and testing... I think some of the issues are due to some strange interaction with new implementation in #131. If you want to see what I am talking about, try change your display range to the new simulator default of 255 - oddly enough it does not matter whether Auto contrast is on or off. I must look into this code... This is not to say all problems are there – most of the time I still can't see any crystals/diffraction. May be an issue with zoom or the way simulated stage works. Will look later. Edit: I cannot get an image consistently enough to test for issues. I spent 15 minutes trying to get image to no avail. With that I unfortunately have to pass debugging for the time being. |
I'll add an option to have crystals in a regular grid on the stage instead of randomly dispersed. Then you should always see one at the origin. I'll also add some noise and fix the value ranges/type. That might hopefully help Edit: Options can be in the dedicated simulation repo. I'll have one crystal always be at (0, 0), the rest random |
I added some noise, a 100nm cross at (0, 0), and forced a crystal to be at (0, 0). I am seeing some strangeness at displayrange 255 when auto contrast is on. It seems like the auto-contrast is off specifically at 255, as images with it off look similar when the displayrange is 254 or 256. I set datatype to int and the max value is 0xf000, if that matters. |
Ok, with your most recent changes I can see things. Apparently also my stage z was off the charts and the hand panel does not allow setting it, so any movements resulted in erratic changes. There are some funny things going on with display range and brightness as well. I think the new method does not work well with the sharp limits of the simulated data. Below is an image with crystal, cross, and background at four brightness settings and DisplayRange 250:
I'm off to test why does that happen, my guess is that some bits overflow or some to-be-variables are hard-coded. Edit: I will edit in my notes below so that I do not have to re-write the entire thought process twice. Testing notes
Case 1: Brightness 1.0, DisplayRange 255, Auto contrast on.
Case 2: Brightness 1.0, DisplayRange 256, Auto contrast on. if self.vsf.display_range != 255.0 or self.vsf.brightness != 1.0:
if self.vsf.auto_contrast:
display_range = 1 + np.percentile(frame[::4, ::4], 99.5)
else:
display_range = self.vsf.display_range
frame = (self.vsf.brightness * 255 / display_range) * frame
frame = np.clip(frame.astype(np.int16), 0, 255).astype(np.uint8) Now the frame is properly scaled to the 255 range before before being displayed, so it it mostly correctly scaled. One remaining issue is that the frame fed to the last line still has scaled negative values for overlapping crystals, but these are small enough for Case 3: Brightness 10, DisplayRange 256, Auto contrast on. Case 4: Brightness 200, DisplayRange 256, Auto contrast on. Bonus fact: Brightness -1, DisplayRange 256, Auto contrast on. Notes on notesI added the following snippet to the if p := (random.random() < 0.002):
print('Frame:')
print(frame[::64, ::64].astype(np.int64)) |
Based on my notes shown above, I suggest the following:
Edit: I noticed that brightness is already soft-capped at 0 to 10 (other values can still be put in manually if needed, but the buttons do not allow it). I'd call this sufficient for the time being. |
Simulation is now a single file, and requires no dependencies. It is quite performant, I can run for a million crystals with no stuttering on my desktop.
I tried commenting the maths, but it can be hard to follow some places.
Hopefully you can try this out, @Baharis! I find it strange that it did not work for you before. It should also work with real microscopes, but the way communication is established is not pretty..
Of course, if you still want to keep complete seperation of simulation, then this PR can be ignored. It simply collects the existing simulation into one file, with a slight rewrite of some parts for simplicity.
I have not checked how accurate the spot positions are when accounting for camera length calibration ect, nor did I try to change the unit cell much.