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 CHANGED
@@ -10,4 +10,4 @@ Last updated: 2024-12-16
10
10
 
11
11
  """
12
12
 
13
- __version__ = "0.0.231"
13
+ __version__ = "0.0.251"
@@ -96,7 +96,10 @@ class LaserParameters:
96
96
  Power in watts
97
97
  """
98
98
  if callable(self.power):
99
- return self.power(t)
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.1 # 10% of max radius
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(self.current_global_time, time)
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.231
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=rqdkAwhLvzoA4UNC7EgJOgze5vTlp72Cm62WfiIINCc,328
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=0UZfyT44nrB4JdfnFnRPTVBm3tPbCyOnPXiBBZs8xIc,18617
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=J9czY646XcW8GzXx9Eb16mG7tQdWw4oVYveOrihZCeY,22745
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=0cc7Vc4LtAbEdGDeg22IJmRGLsONOty4c32hXHO-TSU,5281
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.231.dist-info/METADATA,sha256=Rs9gQc6T1-ZcguRTLWfsl42ZsTmJCtVgXRn-pcL7noY,5284
52
- ams_bp-0.0.231.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
53
- ams_bp-0.0.231.dist-info/entry_points.txt,sha256=MFUK9bZWW61djfsavqopMqiVPVn4lJtt6v8qzyEFyNM,76
54
- ams_bp-0.0.231.dist-info/licenses/LICENSE,sha256=k_-JV1DQKvO0FR8WjvOisqdTl0kp6VJ7RFM3YZhao0c,1071
55
- ams_bp-0.0.231.dist-info/RECORD,,
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,,