AMS-BP 0.0.21__py3-none-any.whl → 0.0.22__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.21"
13
+ __version__ = "0.0.22"
@@ -324,11 +324,12 @@ class ConfigLoader:
324
324
  ):
325
325
  # Create PSFParameters instance
326
326
  parameters = PSFParameters(
327
- wavelength=wavelength,
327
+ emission_wavelength=wavelength,
328
328
  numerical_aperture=float(params_config["numerical_aperture"]),
329
329
  pixel_size=pixel_size,
330
330
  z_step=float(params_config["z_step"]) if z_step is None else z_step,
331
331
  refractive_index=float(params_config.get("refractive_index", 1.0)),
332
+ pinhole_diameter=params_config.get("pinhole_diameter", None),
332
333
  )
333
334
 
334
335
  # Create PSF engine
@@ -1,4 +1,4 @@
1
- from typing import Iterator, List, Literal, Union
1
+ from typing import Dict, Iterator, List, Literal, Union
2
2
 
3
3
  from pydantic import BaseModel
4
4
 
@@ -77,7 +77,7 @@ class MetaData(BaseModel):
77
77
  PhysicalSizeXUnit: Literal["nm", "m"]
78
78
  PhysicalSizeY: float
79
79
  PhysicalSizeYUnit: Literal["nm", "m"]
80
- # Channel: Dict[Literal["Name"], List[str]]
80
+ Channel: Dict[Literal["Name"], List[str]]
81
81
 
82
82
  def __post_init__(self):
83
83
  if isinstance(self.notes, (list, str)):
@@ -5,52 +5,61 @@ from typing import Literal, Optional, Tuple
5
5
  import numpy as np
6
6
  from numpy.typing import NDArray
7
7
 
8
+ AIRYFACTOR = 1.0
9
+
8
10
 
9
11
  @dataclass(frozen=True)
10
12
  class PSFParameters:
11
- """Parameters for PSF (Point Spread Function) generation.
13
+ """Parameters for emission PSF (Point Spread Function) at the detector.
14
+
15
+
16
+ This class defines parameters that determine how light from a point source
17
+ (e.g., a fluorescent molecule) diffracts through the collection optics
18
+ to form a pattern at the detector.
12
19
 
13
20
  Attributes:
14
- wavelength: Light wavelength in nanometers
15
- numerical_aperture: Numerical aperture of the optical system
16
- pixel_size: Size of pixels in micrometers
21
+ emission_wavelength: Emission wavelength in nanometers
22
+ numerical_aperture: Numerical aperture of the collection objective
23
+ pixel_size: Size of pixels in micrometers at the detector
17
24
  z_step: Axial step size in micrometers
18
25
  refractive_index: Refractive index of the medium (default: 1.0 for air)
26
+ pinhole_diameter: Diameter of the pinhole in micrometers (default: None for widefield)
27
+ The pinhole spatially filters the emitted light before it reaches
28
+ the detector.
19
29
  """
20
30
 
21
- wavelength: float
31
+ emission_wavelength: float
22
32
  numerical_aperture: float
23
33
  pixel_size: float
24
34
  z_step: float
25
35
  refractive_index: float = 1.0
26
-
27
- # def __post_init__(self) -> None:
28
- # """Validate parameters after initialization."""
29
- # if any(
30
- # param <= 0
31
- # for param in (
32
- # self.wavelength,
33
- # self.numerical_aperture,
34
- # self.pixel_size,
35
- # self.z_step,
36
- # self.refractive_index,
37
- # )
38
- # ):
39
- # raise ValueError("All parameters must be positive numbers")
40
- # if self.numerical_aperture >= self.refractive_index:
41
- # raise ValueError("Numerical aperture must be less than refractive index")
36
+ pinhole_diameter: Optional[float] = None # um
42
37
 
43
38
  @cached_property
44
39
  def wavelength_um(self) -> float:
45
- """Wavelength in micrometers."""
46
- return self.wavelength / 1000.0
40
+ """Emission wavelength in micrometers."""
41
+ return self.emission_wavelength / 1000.0
42
+
43
+ @cached_property
44
+ def pinhole_radius(self) -> Optional[float]:
45
+ """Pinhole radius in micrometers."""
46
+ return (
47
+ self.pinhole_diameter / 2.0 if self.pinhole_diameter is not None else None
48
+ )
47
49
 
48
50
 
49
51
  class PSFEngine:
50
- """Engine for generating various microscope Point Spread Functions.
52
+ """Engine for calculating emission light PSF at the detector.
53
+
54
+ This class calculates how light from a point source (like a fluorescent molecule)
55
+ spreads due to diffraction through the collection optics to form a pattern at
56
+ the detector. For confocal systems, it can include the effect of a pinhole
57
+ that spatially filters the light before detection.
51
58
 
52
- This class implements calculations for both 2D and 3D Point Spread Functions
53
- using Gaussian approximations.
59
+ Note: This PSF describes only the diffraction of emitted light through the
60
+ collection optics. While a confocal microscope uses focused illumination to
61
+ excite molecules, that illumination pattern does not affect how the emitted
62
+ light diffracts to form the PSF we calculate here.
54
63
  """
55
64
 
56
65
  def __init__(self, params: PSFParameters):
@@ -79,34 +88,69 @@ class PSFEngine:
79
88
  self._norm_sigma_xy = self._sigma_xy / 2.355
80
89
  self._norm_sigma_z = self._sigma_z / 2.355
81
90
 
91
+ # Generate pinhole mask if specified
92
+ if self.params.pinhole_radius is not None:
93
+ if self.params.pinhole_radius < AIRYFACTOR * self._sigma_xy:
94
+ raise ValueError(
95
+ f"Pinhole size ({self.params.pinhole_radius} um) is smaller than {AIRYFACTOR} times the Airy lobe. This will diffract the emission light in the pinhole; an ideal pinhole size for this setup is {self._sigma_xy} um."
96
+ )
97
+ self._pinhole_mask = self._generate_pinhole_mask()
98
+ else:
99
+ self._pinhole_mask = None
100
+
101
+ def _generate_pinhole_mask(self) -> NDArray[np.float64]:
102
+ """Generate a binary mask representing the pinhole's spatial filtering.
103
+
104
+ The pinhole blocks emission light based on position in the image plane,
105
+ affecting what portion of the diffracted light reaches the detector.
106
+ """
107
+ x, y = self._grid_xy
108
+ r = np.sqrt(x**2 + y**2)
109
+ return (r <= self.params.pinhole_radius).astype(np.float64)
110
+
82
111
  @lru_cache(maxsize=128)
83
112
  def psf_z(self, z_val: float) -> NDArray[np.float64]:
84
- """Generate z=z_val Gaussian approximation of PSF.
113
+ """Calculate the PSF at the detector for a point source at z_val.
114
+
115
+ This represents how light from a point source at position z_val
116
+ diffracts through the collection optics to form a pattern at the
117
+ detector. If a pinhole is present, it spatially filters this pattern.
85
118
 
86
119
  Args:
87
- z_val: Z-position in micrometers
120
+ z_val: Z-position of the point source in micrometers
88
121
 
89
122
  Returns:
90
- 2D array containing the PSF at given z position
123
+ 2D array containing the light intensity pattern at the detector
91
124
  """
92
125
  x, y = self._grid_xy
93
126
 
94
- # Vectorized calculation
127
+ # Calculate how light from the point source diffracts through collection optics
95
128
  r_squared = (x / self._norm_sigma_xy) ** 2 + (y / self._norm_sigma_xy) ** 2
96
129
  z_term = (z_val / self._norm_sigma_z) ** 2
97
- return np.exp(-0.5 * (r_squared + z_term))
130
+ psf_at_detector = np.exp(-0.5 * (r_squared + z_term))
131
+
132
+ if self._pinhole_mask is not None:
133
+ # Apply pinhole's spatial filtering
134
+ return psf_at_detector * self._pinhole_mask
135
+
136
+ return psf_at_detector
98
137
 
99
138
  @lru_cache(maxsize=128)
100
139
  def psf_z_xy0(self, z_val: float) -> float:
101
- """Generate z=z_val Gaussian approximation of PSF with x=y=0.
140
+ """Calculate the PSF intensity at the center of the detector.
141
+
142
+ For a point source at z_val, this gives the intensity of light
143
+ that reaches the detector center (x=y=0). This point is always
144
+ within the pinhole if one is present.
102
145
 
103
146
  Args:
104
- z_val: Z-position in micrometers
147
+ z_val: Z-position of the point source in micrometers
105
148
 
106
149
  Returns:
107
- PSF value at x=y=0 and given z position
150
+ Light intensity at detector center
108
151
  """
109
- return np.exp(-0.5 * (z_val / self._norm_sigma_z) ** 2)
152
+ z_term = (z_val / self._norm_sigma_z) ** 2
153
+ return np.exp(-0.5 * z_term)
110
154
 
111
155
  @cache
112
156
  def _3d_normalization_A(
@@ -1,14 +1,14 @@
1
1
  """
2
2
  run_cell_simulation.py
3
3
 
4
- This file contains the command-line interface (CLI) for the SMS_BP package, which is used for simulating single molecule localization microscopy experiments.
4
+ This file contains the command-line interface (CLI) for the AMS_BP package.
5
5
 
6
6
  The CLI is built using Typer and provides two main commands:
7
7
  1. 'config': Generates a sample configuration file.
8
8
  2. 'runsim': Runs the cell simulation using a provided configuration file.
9
9
 
10
10
  Main Components:
11
- - typer_app_sms_bp: The main Typer application object.
11
+ - typer_app_asms_bp: The main Typer application object.
12
12
  - cell_simulation(): Callback function that displays the version information.
13
13
  - generate_config(): Command to generate a sample configuration file.
14
14
  - run_cell_simulation(): Command to run the cell simulation using a configuration file.
@@ -37,7 +37,7 @@ from .configio.saving import save_config_frames
37
37
 
38
38
  cli_help_doc = str(
39
39
  """
40
- CLI tool to run [underline]A[/underline]dvanced [underline]M[/underline]olecule [underline]S[/underline]imulation: [underline]ASMS[/underline]-BP. GitHub: [green]https://github.com/joemans3/AMS_BP[/green].
40
+ CLI tool to run [underline]A[/underline]dvanced [underline]M[/underline]olecule [underline]S[/underline]imulation: [underline]AMS[/underline]-BP. GitHub: [green]https://github.com/joemans3/AMS_BP[/green].
41
41
  [Version: [bold]{0}[/bold]]
42
42
  """.format(__version__)
43
43
  )
AMS_BP/sim_config.toml CHANGED
@@ -275,6 +275,7 @@ custom_path = ""
275
275
  [psf.parameters]
276
276
  numerical_aperture = 1.4 # typical range: 0.1 - 1.5
277
277
  refractive_index = 1.0 # default is air (1.0)
278
+ #pinhole_diameter = 1.0 # Do not include for no pinhole else float in um units
278
279
 
279
280
  # Multiple Laser Configuration File
280
281
 
AMS_BP/sim_microscopy.py CHANGED
@@ -276,7 +276,7 @@ class VirtualMicroscope:
276
276
  PhysicalSizeXUnit="m",
277
277
  PhysicalSizeY=self.camera.pixel_size * 1e-6,
278
278
  PhysicalSizeYUnit="m",
279
- # Channel={"Name": self.channels.names},
279
+ Channel={"Name": self.channels.names},
280
280
  )
281
281
 
282
282
  # return frames in the format ZCTYX
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AMS_BP
3
- Version: 0.0.21
3
+ Version: 0.0.22
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
@@ -1,7 +1,7 @@
1
- AMS_BP/__init__.py,sha256=gA3WHujyg_TRO9bQK9orLK8uNHSObJpmsLkv8GHRzLc,327
2
- AMS_BP/run_cell_simulation.py,sha256=fPU1Tuu7hBupGtMk07j2t8QYo_TjFLMJRU9fwmAgU9c,7502
3
- AMS_BP/sim_config.toml,sha256=FD-OcSDAgRuNIalFe0pC8sbsaSwM-9DV2DNswds2q54,11976
4
- AMS_BP/sim_microscopy.py,sha256=7JQ6NQlgNZCvFE-FC1f9Ehh6DoJgn7bLzeqS_Mamq9Y,18619
1
+ AMS_BP/__init__.py,sha256=NlkysP1_GeDxvsm-dQaJIW9U1iNFB0jI_34DmCYn-bg,327
2
+ AMS_BP/run_cell_simulation.py,sha256=7InopFikjo0HfaLO2siXskBIbyCIte9avG4YXjjaWCI,7420
3
+ AMS_BP/sim_config.toml,sha256=LVpxp2zv-y6Ic-ve2AG7Ted1Fr_Tni-8yh8l5gp-7oM,12056
4
+ AMS_BP/sim_microscopy.py,sha256=0UZfyT44nrB4JdfnFnRPTVBm3tPbCyOnPXiBBZs8xIc,18617
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
@@ -9,11 +9,11 @@ AMS_BP/cells/rod_cell.py,sha256=jQ1kLEk74Pv2rcXPRJ6-QJJhux-mYiDSytzqlxCNWfA,3181
9
9
  AMS_BP/cells/spherical_cell.py,sha256=n3ou3tW0nCxXIwv6uLkVKHkYCfgoNn8VI6CVTLBIll0,2140
10
10
  AMS_BP/configio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  AMS_BP/configio/configmodels.py,sha256=Isc6THk3RAIVdjEUBW4c_OD0I122dYufgEvAcGJQ5uo,3046
12
- AMS_BP/configio/convertconfig.py,sha256=lS7FTDheESdbpaZ0K1LcE8rkdJOKLjzIvcmWpjeebSs,34654
12
+ AMS_BP/configio/convertconfig.py,sha256=Fg9pOCZSxmWuHnrg-5xZRvhPEK6Qc1kXqu6LL9e9QYw,34741
13
13
  AMS_BP/configio/experiments.py,sha256=HdfaSi0gPPJ_wLF87XcW5ICja19Uezx7-ygFEwNzi30,3995
14
14
  AMS_BP/configio/saving.py,sha256=596QgAadV32rzsN4B2FngGFcBWCzCDnLFN-qtQsv3bM,857
15
15
  AMS_BP/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- AMS_BP/metadata/metadata.py,sha256=_FwbSRsUhGwigY6YYffMgEx5hlXTT_vu-9AldMFPa6w,2923
16
+ AMS_BP/metadata/metadata.py,sha256=YDumjc5sI3lY_UZx8f0ZhMqbG2qKQkysXwl7CY4ZtnY,2927
17
17
  AMS_BP/motion/__init__.py,sha256=cy3W-wCRjjlN1DrTqYc-JltYwcE8SZCXMVPJ2o6q_BQ,178
18
18
  AMS_BP/motion/condensate_movement.py,sha256=cGLHIOL7VUJ7U-JrJXetcnUF2v9SepIBznoqu6AQPxU,13252
19
19
  AMS_BP/motion/track_gen.py,sha256=Z3QJLVMP1gX4SlgOXFxBg8sJhBG0Xq25ixnBoEHEAZI,19462
@@ -31,7 +31,7 @@ AMS_BP/optics/filters/channels/channelschema.py,sha256=SConyA5yVdfnI_8sgcxVC8SV7
31
31
  AMS_BP/optics/lasers/__init__.py,sha256=T7dHohhyLf_pBw4TidarYHWmiwxVXGE71-Bf1aeBbuc,564
32
32
  AMS_BP/optics/lasers/laser_profiles.py,sha256=J9czY646XcW8GzXx9Eb16mG7tQdWw4oVYveOrihZCeY,22745
33
33
  AMS_BP/optics/psf/__init__.py,sha256=ezrKPgpTeR4gTHOvF0mhF6u2zMMTd8Bgp8PGeOf11fA,121
34
- AMS_BP/optics/psf/psf_engine.py,sha256=ejmTwAKtEpXvKeMuUFcuz6HjJbEjQa_NvkE6a3hkVzk,6769
34
+ AMS_BP/optics/psf/psf_engine.py,sha256=wabdBszY4CcGUtt7ye8e3tQXQQxDJ8griGD7FMgAdIo,9192
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
37
  AMS_BP/photophysics/state_kinetics.py,sha256=0cc7Vc4LtAbEdGDeg22IJmRGLsONOty4c32hXHO-TSU,5281
@@ -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.21.dist-info/METADATA,sha256=RhM8C7dT2SXt-rbPFdQdo_EaiOFUx-7uC7uvic8IpvU,5316
52
- ams_bp-0.0.21.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
53
- ams_bp-0.0.21.dist-info/entry_points.txt,sha256=MFUK9bZWW61djfsavqopMqiVPVn4lJtt6v8qzyEFyNM,76
54
- ams_bp-0.0.21.dist-info/licenses/LICENSE,sha256=k_-JV1DQKvO0FR8WjvOisqdTl0kp6VJ7RFM3YZhao0c,1071
55
- ams_bp-0.0.21.dist-info/RECORD,,
51
+ ams_bp-0.0.22.dist-info/METADATA,sha256=VQheoFTH5ZdmZTZwrb58UxP9YTowy8U7r6zW5kabIMI,5316
52
+ ams_bp-0.0.22.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
53
+ ams_bp-0.0.22.dist-info/entry_points.txt,sha256=MFUK9bZWW61djfsavqopMqiVPVn4lJtt6v8qzyEFyNM,76
54
+ ams_bp-0.0.22.dist-info/licenses/LICENSE,sha256=k_-JV1DQKvO0FR8WjvOisqdTl0kp6VJ7RFM3YZhao0c,1071
55
+ ams_bp-0.0.22.dist-info/RECORD,,