AMS-BP 0.0.231__py3-none-any.whl → 0.0.251__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- AMS_BP/__init__.py +1 -1
- AMS_BP/optics/lasers/laser_profiles.py +5 -168
- AMS_BP/photophysics/state_kinetics.py +4 -1
- AMS_BP/sim_microscopy.py +3 -1
- {ams_bp-0.0.231.dist-info → ams_bp-0.0.251.dist-info}/METADATA +3 -1
- {ams_bp-0.0.231.dist-info → ams_bp-0.0.251.dist-info}/RECORD +9 -9
- {ams_bp-0.0.231.dist-info → ams_bp-0.0.251.dist-info}/WHEEL +0 -0
- {ams_bp-0.0.231.dist-info → ams_bp-0.0.251.dist-info}/entry_points.txt +0 -0
- {ams_bp-0.0.231.dist-info → ams_bp-0.0.251.dist-info}/licenses/LICENSE +0 -0
AMS_BP/__init__.py
CHANGED
@@ -96,7 +96,10 @@ class LaserParameters:
|
|
96
96
|
Power in watts
|
97
97
|
"""
|
98
98
|
if callable(self.power):
|
99
|
-
|
99
|
+
power = self.power(t)
|
100
|
+
if power < 0:
|
101
|
+
raise ValueError("Laser Power Cannot be Negative")
|
102
|
+
return power
|
100
103
|
return self.power
|
101
104
|
|
102
105
|
def get_position(self, t: float) -> Tuple[float, float, float]:
|
@@ -413,7 +416,7 @@ class WidefieldBeam(LaserProfile):
|
|
413
416
|
base_intensity = power / (np.pi * self.max_radius**2)
|
414
417
|
|
415
418
|
# Apply radial intensity profile with smooth falloff at edges
|
416
|
-
edge_width = self.max_radius * 0.
|
419
|
+
edge_width = self.max_radius * 0.00001
|
417
420
|
radial_profile = 0.5 * (1 - np.tanh((r - self.max_radius) / edge_width))
|
418
421
|
# Apply DoF-based axial intensity profile
|
419
422
|
axial_profile = self._calculate_dof_profile(z_shifted)
|
@@ -422,32 +425,6 @@ class WidefieldBeam(LaserProfile):
|
|
422
425
|
return base_intensity * radial_profile * axial_profile
|
423
426
|
|
424
427
|
|
425
|
-
# Example usage
|
426
|
-
if __name__ == "__main__":
|
427
|
-
# Create parameters for a typical microscope objective
|
428
|
-
params = LaserParameters(
|
429
|
-
wavelength=488, # 488 nm
|
430
|
-
power=0.001, # 1 mW
|
431
|
-
beam_width=0.25, # 250 nm
|
432
|
-
numerical_aperture=1.4,
|
433
|
-
refractive_index=1.518, # Oil immersion
|
434
|
-
)
|
435
|
-
|
436
|
-
# Create beam object
|
437
|
-
beam = GaussianBeam(params)
|
438
|
-
|
439
|
-
# Get intensity map
|
440
|
-
result = beam.get_intensity_map(
|
441
|
-
volume_size=(5, 5, 10), # 5x5x10 microns
|
442
|
-
voxel_size=0.1, # 100 nm voxels
|
443
|
-
t=0, # t=0 seconds
|
444
|
-
)
|
445
|
-
|
446
|
-
# print(f"Beam waist: {params.beam_width:.3f} µm")
|
447
|
-
# print(f"Rayleigh range: {params.rayleigh_range:.3f} µm")
|
448
|
-
# print(f"Diffraction limit: {params.diffraction_limited_width:.3f} µm")
|
449
|
-
|
450
|
-
|
451
428
|
class HiLoBeam(LaserProfile):
|
452
429
|
"""
|
453
430
|
Highly Inclined Laminated Optical (HiLo) illumination profile.
|
@@ -549,143 +526,3 @@ class HiLoBeam(LaserProfile):
|
|
549
526
|
lamination_factor = np.exp(-np.abs(z_shifted) / (2 * self.axial_resolution))
|
550
527
|
|
551
528
|
return intensity * lamination_factor
|
552
|
-
|
553
|
-
|
554
|
-
class ConfocalBeam(LaserProfile):
|
555
|
-
"""
|
556
|
-
Confocal microscopy beam profile with point scanning and pinhole characteristics.
|
557
|
-
|
558
|
-
Implements key optical principles of confocal microscopy:
|
559
|
-
- Point scanning illumination
|
560
|
-
- Pinhole-based rejection of out-of-focus light
|
561
|
-
- Depth-resolved imaging capabilities
|
562
|
-
"""
|
563
|
-
|
564
|
-
def __init__(
|
565
|
-
self,
|
566
|
-
params: LaserParameters,
|
567
|
-
pinhole_diameter: float, # Pinhole diameter in microns
|
568
|
-
scanning_mode: str = "point", # 'point' or 'line'
|
569
|
-
line_orientation: str = "horizontal", # 'horizontal' or 'vertical'
|
570
|
-
):
|
571
|
-
"""
|
572
|
-
Initialize Confocal beam profile.
|
573
|
-
|
574
|
-
Args:
|
575
|
-
params: LaserParameters for the beam
|
576
|
-
pinhole_diameter: Diameter of the detection pinhole in microns
|
577
|
-
scanning_mode: Scanning method ('point' or 'line')
|
578
|
-
line_orientation: Orientation for line scanning
|
579
|
-
"""
|
580
|
-
super().__init__(params)
|
581
|
-
|
582
|
-
# Validate numerical aperture
|
583
|
-
if params.numerical_aperture is None:
|
584
|
-
raise ValueError(
|
585
|
-
"Numerical aperture must be specified for confocal microscopy"
|
586
|
-
)
|
587
|
-
|
588
|
-
# Pinhole and optical characteristics
|
589
|
-
self.pinhole_diameter = pinhole_diameter
|
590
|
-
self.scanning_mode = scanning_mode
|
591
|
-
self.line_orientation = line_orientation
|
592
|
-
|
593
|
-
# Calculate optical parameters
|
594
|
-
wavelength_microns = params.wavelength / 1000.0
|
595
|
-
na = params.numerical_aperture
|
596
|
-
|
597
|
-
# Theoretical resolution calculations
|
598
|
-
self.lateral_resolution = 0.61 * wavelength_microns / na
|
599
|
-
self.axial_resolution = 0.5 * wavelength_microns / (na**2)
|
600
|
-
|
601
|
-
# Pinhole transmission calculation
|
602
|
-
# Airy disk radius calculation
|
603
|
-
self.airy_radius = 1.22 * wavelength_microns / (2 * na)
|
604
|
-
|
605
|
-
# Transmission through pinhole
|
606
|
-
def pinhole_transmission(z):
|
607
|
-
"""
|
608
|
-
Calculate pinhole transmission as a function of z-position.
|
609
|
-
Uses an error function to model smooth transition.
|
610
|
-
"""
|
611
|
-
# Normalized z-position relative to focal plane
|
612
|
-
z_norm = z / self.axial_resolution
|
613
|
-
|
614
|
-
# Smooth transition function
|
615
|
-
return 0.5 * (1 + np.tanh(-z_norm))
|
616
|
-
|
617
|
-
self.pinhole_transmission = pinhole_transmission
|
618
|
-
|
619
|
-
# print("Confocal Microscopy Configuration:")
|
620
|
-
# print(f" Scanning Mode: {scanning_mode}")
|
621
|
-
# print(f" Pinhole Diameter: {pinhole_diameter:.2f} µm")
|
622
|
-
# print(f" Lateral Resolution: {self.lateral_resolution:.3f} µm")
|
623
|
-
# print(f" Axial Resolution: {self.axial_resolution:.3f} µm")
|
624
|
-
# print(f" Airy Disk Radius: {self.airy_radius:.3f} µm")
|
625
|
-
|
626
|
-
def calculate_intensity(
|
627
|
-
self,
|
628
|
-
x: np.ndarray | float,
|
629
|
-
y: np.ndarray | float,
|
630
|
-
z: np.ndarray | float,
|
631
|
-
t: float,
|
632
|
-
) -> np.ndarray:
|
633
|
-
"""
|
634
|
-
Calculate the confocal illumination intensity distribution.
|
635
|
-
|
636
|
-
Args:
|
637
|
-
x: X coordinates in microns (3D array)
|
638
|
-
y: Y coordinates in microns (3D array)
|
639
|
-
z: Z coordinates in microns (3D array)
|
640
|
-
t: Time in seconds
|
641
|
-
|
642
|
-
Returns:
|
643
|
-
3D array of intensities in W/µm²
|
644
|
-
"""
|
645
|
-
# Get time-dependent parameters
|
646
|
-
power = self.params.get_power(t)
|
647
|
-
pos = self.params.get_position(t)
|
648
|
-
|
649
|
-
# Shift coordinates based on current beam position
|
650
|
-
x_shifted = x - pos[0]
|
651
|
-
y_shifted = y - pos[1]
|
652
|
-
z_shifted = z - pos[2]
|
653
|
-
|
654
|
-
# Base beam parameters
|
655
|
-
w0 = self.params.beam_width # Beam waist
|
656
|
-
zR = self.params.rayleigh_range # Rayleigh range
|
657
|
-
|
658
|
-
# Calculate beam width at z
|
659
|
-
w_z = w0 * np.sqrt(1 + (z_shifted / zR) ** 2)
|
660
|
-
|
661
|
-
# Peak intensity calculation
|
662
|
-
I0 = 2 * power / (np.pi * w0**2)
|
663
|
-
|
664
|
-
# Scanning mode intensity modification
|
665
|
-
if self.scanning_mode == "point":
|
666
|
-
# Point scanning: standard Gaussian beam
|
667
|
-
radial_intensity = (
|
668
|
-
I0
|
669
|
-
* (w0 / w_z) ** 2
|
670
|
-
* np.exp(-2 * (x_shifted**2 + y_shifted**2) / w_z**2)
|
671
|
-
)
|
672
|
-
elif self.scanning_mode == "line":
|
673
|
-
# Line scanning: different intensity distribution
|
674
|
-
if self.line_orientation == "horizontal":
|
675
|
-
line_intensity = (
|
676
|
-
I0 * (w0 / w_z) ** 2 * np.exp(-2 * y_shifted**2 / w_z**2)
|
677
|
-
)
|
678
|
-
radial_intensity = line_intensity
|
679
|
-
else: # vertical line scanning
|
680
|
-
line_intensity = (
|
681
|
-
I0 * (w0 / w_z) ** 2 * np.exp(-2 * x_shifted**2 / w_z**2)
|
682
|
-
)
|
683
|
-
radial_intensity = line_intensity
|
684
|
-
else:
|
685
|
-
raise ValueError(f"Unknown scanning mode: {self.scanning_mode}")
|
686
|
-
|
687
|
-
# Pinhole transmission effect
|
688
|
-
pinhole_effect = self.pinhole_transmission(z_shifted)
|
689
|
-
|
690
|
-
# Final intensity calculation
|
691
|
-
return radial_intensity * pinhole_effect
|
@@ -27,6 +27,7 @@ class StateTransitionCalculator:
|
|
27
27
|
self.current_global_time = current_global_time # ms (oversample motion time)
|
28
28
|
self.laser_intensity_generator = laser_intensity_generator
|
29
29
|
self.fluorescent_state_history = {} # {fluorescent.state.name : [delta time (seconds), laser_intensites], ...}
|
30
|
+
self.current_global_time_s = self.current_global_time * 1e-3
|
30
31
|
|
31
32
|
def __call__(
|
32
33
|
self,
|
@@ -48,7 +49,9 @@ class StateTransitionCalculator:
|
|
48
49
|
time = 0
|
49
50
|
transitions = self.flurophoreobj.state_history[self.current_global_time][2]
|
50
51
|
final_state_name = transitions[0].from_state
|
51
|
-
laser_intensities = self._initialize_state_hist(
|
52
|
+
laser_intensities = self._initialize_state_hist(
|
53
|
+
self.current_global_time, time + self.current_global_time_s
|
54
|
+
)
|
52
55
|
|
53
56
|
while time < self.time_duration:
|
54
57
|
stateTransitionMatrixR = [
|
AMS_BP/sim_microscopy.py
CHANGED
@@ -73,7 +73,9 @@ class VirtualMicroscope:
|
|
73
73
|
def _set_laser_powers(self, laser_power: Dict[str, float]) -> None:
|
74
74
|
if laser_power is not None:
|
75
75
|
for laser in laser_power.keys():
|
76
|
-
if isinstance(self.lasers[laser].params.power, float)
|
76
|
+
if isinstance(self.lasers[laser].params.power, float) and isinstance(
|
77
|
+
laser_power[laser], float
|
78
|
+
):
|
77
79
|
if laser_power[laser] > self.lasers[laser].params.max_power:
|
78
80
|
raise ValueError(
|
79
81
|
"Provided laser power for laser: {} nm, is larger than the maximum power: {}".format(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: AMS_BP
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.251
|
4
4
|
Summary: Advanced Microscopy Simulations developed for the Weber Lab by Baljyot Singh Parmar
|
5
5
|
Project-URL: Documentation, https://joemans3.github.io/AMS_BP/
|
6
6
|
Project-URL: Source code, https://github.com/joemans3/AMS_BP
|
@@ -171,3 +171,5 @@ frames, metadata = function_exp(microscope=microscope, config=config_exp)
|
|
171
171
|
from AMS_BP.configio.saving import save_config_frames
|
172
172
|
save_config_frames(metadata, frames, setup_config["base_config"].OutputParameters)
|
173
173
|
```
|
174
|
+
|
175
|
+
> A more detailed example is provided in the jupyter notebook in the examples. For starters refer to the [VisualizingIndividualModules](examples/VisualizingIndividualModules/modules_explained.ipynb). Then head over to the [laser modulation module](examples/VisualizingIndividualModules/laser_modulation.ipynb) which will show how to change the laser power over time in the simulations. Then view an example of a complex experiment setup for [FRAP](examples/QuantitativeExperiments/FRAP_methods.ipynb) which is possible by the use of compositions of modules in this simulation library.
|
@@ -1,7 +1,7 @@
|
|
1
|
-
AMS_BP/__init__.py,sha256=
|
1
|
+
AMS_BP/__init__.py,sha256=qv5C9LGYuQzZP9NQ_ST5KH4IuqGwi8PVl44IypUo97w,328
|
2
2
|
AMS_BP/run_cell_simulation.py,sha256=7InopFikjo0HfaLO2siXskBIbyCIte9avG4YXjjaWCI,7420
|
3
3
|
AMS_BP/sim_config.toml,sha256=3IqOQIJYmP5g4okk15nqQiNZb3ij7Pt63HbpI-5tySw,11672
|
4
|
-
AMS_BP/sim_microscopy.py,sha256=
|
4
|
+
AMS_BP/sim_microscopy.py,sha256=u60ApTA6MTUmqSAd7EsAxweKya_Typput8NumDq9fp8,18697
|
5
5
|
AMS_BP/cells/__init__.py,sha256=yWFScBC1uOGDkeC8i1m1ZBtIREcyt4JHxYa72LxbBZU,177
|
6
6
|
AMS_BP/cells/base_cell.py,sha256=FIPB9J8F40tb53vv7C6qG-SaAFLOI8-MGIk1mmZ-gnI,1503
|
7
7
|
AMS_BP/cells/rectangular_cell.py,sha256=5yGxvTXYvgldLXyWXpE_SD9Zx2NLerC-I2j02reHsJ0,2515
|
@@ -29,12 +29,12 @@ AMS_BP/optics/filters/filters.py,sha256=-iw7eqmDO77SEqlFTv5jJNVwpA8y93TLsjy5hhsA
|
|
29
29
|
AMS_BP/optics/filters/channels/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
30
|
AMS_BP/optics/filters/channels/channelschema.py,sha256=SConyA5yVdfnI_8sgcxVC8SV7S8tGUJYPPC6jn7lglU,906
|
31
31
|
AMS_BP/optics/lasers/__init__.py,sha256=T7dHohhyLf_pBw4TidarYHWmiwxVXGE71-Bf1aeBbuc,564
|
32
|
-
AMS_BP/optics/lasers/laser_profiles.py,sha256=
|
32
|
+
AMS_BP/optics/lasers/laser_profiles.py,sha256=DM3YDh6JccgQk8fjBRh6J3bDpTChm8Im_AE5z9EK3EI,17101
|
33
33
|
AMS_BP/optics/psf/__init__.py,sha256=ezrKPgpTeR4gTHOvF0mhF6u2zMMTd8Bgp8PGeOf11fA,121
|
34
34
|
AMS_BP/optics/psf/psf_engine.py,sha256=Do54D1jMbSrj5uljdTrrEttCvxq3qbVT74acRuOk15c,9434
|
35
35
|
AMS_BP/photophysics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
36
|
AMS_BP/photophysics/photon_physics.py,sha256=QRG_QIZ4csJ3g5qGP9Wtk7kzqm8_MUbVHfFef6cMtHQ,6671
|
37
|
-
AMS_BP/photophysics/state_kinetics.py,sha256=
|
37
|
+
AMS_BP/photophysics/state_kinetics.py,sha256=IdZtlHCLs--iSjLwDu2IQA617qXC4la8VpqosrM-vgQ,5401
|
38
38
|
AMS_BP/probabilityfuncs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
39
|
AMS_BP/probabilityfuncs/markov_chain.py,sha256=LV6KGr8Lv4NIvBPJqsR0CEynssa_mPH30qLaK85GObA,4339
|
40
40
|
AMS_BP/probabilityfuncs/probability_functions.py,sha256=j_rIxrupGBf_FKkQBh1TvEa34A44jAasaZQRg2u3FuY,11793
|
@@ -48,8 +48,8 @@ AMS_BP/utils/decorators.py,sha256=4qFdvzPJne0dhkhD1znPxRln1Rfr5NX8rdcCDcbATRU,62
|
|
48
48
|
AMS_BP/utils/errors.py,sha256=7BOd-L4_YeKmWn3Q4EOdTnNF3Bj_exDa3eg5X0yCZrc,759
|
49
49
|
AMS_BP/utils/maskMaker.py,sha256=2ca3n2nc8rFtUh1LurKXOJJsUmhrOpWbRnVX7fjRVvs,335
|
50
50
|
AMS_BP/utils/util_functions.py,sha256=jI6WBh09_khdABnEoVK7SK1WRvCLHuw40f5ALyflzlc,9478
|
51
|
-
ams_bp-0.0.
|
52
|
-
ams_bp-0.0.
|
53
|
-
ams_bp-0.0.
|
54
|
-
ams_bp-0.0.
|
55
|
-
ams_bp-0.0.
|
51
|
+
ams_bp-0.0.251.dist-info/METADATA,sha256=lSmQVE_Aaw13hf692nC4MuTZplqmg5vBqjap8PTnow0,5870
|
52
|
+
ams_bp-0.0.251.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
53
|
+
ams_bp-0.0.251.dist-info/entry_points.txt,sha256=MFUK9bZWW61djfsavqopMqiVPVn4lJtt6v8qzyEFyNM,76
|
54
|
+
ams_bp-0.0.251.dist-info/licenses/LICENSE,sha256=k_-JV1DQKvO0FR8WjvOisqdTl0kp6VJ7RFM3YZhao0c,1071
|
55
|
+
ams_bp-0.0.251.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|