AMS-BP 0.0.31__py3-none-any.whl → 0.0.231__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/motion/movement/fbm_BP.py +5 -4
- AMS_BP/motion/track_gen.py +6 -6
- AMS_BP/optics/lasers/laser_profiles.py +177 -15
- AMS_BP/optics/psf/psf_engine.py +8 -25
- AMS_BP/photophysics/photon_physics.py +4 -4
- AMS_BP/photophysics/state_kinetics.py +1 -4
- AMS_BP/sim_microscopy.py +1 -3
- {ams_bp-0.0.31.dist-info → ams_bp-0.0.231.dist-info}/METADATA +1 -3
- {ams_bp-0.0.31.dist-info → ams_bp-0.0.231.dist-info}/RECORD +13 -13
- {ams_bp-0.0.31.dist-info → ams_bp-0.0.231.dist-info}/WHEEL +0 -0
- {ams_bp-0.0.31.dist-info → ams_bp-0.0.231.dist-info}/entry_points.txt +0 -0
- {ams_bp-0.0.31.dist-info → ams_bp-0.0.231.dist-info}/licenses/LICENSE +0 -0
    
        AMS_BP/__init__.py
    CHANGED
    
    
    
        AMS_BP/motion/movement/fbm_BP.py
    CHANGED
    
    | @@ -1,7 +1,6 @@ | |
| 1 1 | 
             
            import numpy as np
         | 
| 2 | 
            -
             | 
| 2 | 
            +
            from .boundary_conditions import _refecting_boundary, _absorbing_boundary
         | 
| 3 3 | 
             
            from ...probabilityfuncs.markov_chain import MCMC_state_selection
         | 
| 4 | 
            -
            from .boundary_conditions import _absorbing_boundary, _refecting_boundary
         | 
| 5 4 |  | 
| 6 5 | 
             
            BOUNDARY_CONDITIONS = {
         | 
| 7 6 | 
             
                "reflecting": _refecting_boundary,
         | 
| @@ -162,8 +161,10 @@ class FBM_BP: | |
| 162 161 | 
             
                    phi = np.zeros(self.n)
         | 
| 163 162 | 
             
                    psi = np.zeros(self.n)
         | 
| 164 163 | 
             
                    # construct a gaussian noise vector
         | 
| 165 | 
            -
                    gn =  | 
| 166 | 
            -
                         | 
| 164 | 
            +
                    gn = (
         | 
| 165 | 
            +
                        np.random.normal(0, 1, self.n)
         | 
| 166 | 
            +
                        * np.sqrt(self.dt * 2 * self._diff_a_n)
         | 
| 167 | 
            +
                        * (self.dt ** (2 * self._hurst_n))
         | 
| 167 168 | 
             
                    )
         | 
| 168 169 | 
             
                    # catch is all hurst are 0.5 then use the gaussian noise vector corresponding to the scale defined by the diffusion parameter
         | 
| 169 170 | 
             
                    if np.all(self._hurst_n == 0.5):
         | 
    
        AMS_BP/motion/track_gen.py
    CHANGED
    
    | @@ -124,12 +124,12 @@ class Track_generator: | |
| 124 124 | 
             
                        rel_space_lim[i] = self.space_lim[i] - initials[i]
         | 
| 125 125 |  | 
| 126 126 | 
             
                    # convert the diffusion_coefficients
         | 
| 127 | 
            -
                     | 
| 128 | 
            -
             | 
| 129 | 
            -
                     | 
| 127 | 
            +
                    diffusion_coefficient = self._convert_diffcoef_um2s_um2xms(
         | 
| 128 | 
            +
                        diffusion_coefficient
         | 
| 129 | 
            +
                    )
         | 
| 130 130 | 
             
                    fbm = FBM_BP(
         | 
| 131 131 | 
             
                        n=track_length,
         | 
| 132 | 
            -
                        dt= | 
| 132 | 
            +
                        dt=1,
         | 
| 133 133 | 
             
                        hurst_parameters=[hurst_exponent],
         | 
| 134 134 | 
             
                        diffusion_parameters=[diffusion_coefficient],
         | 
| 135 135 | 
             
                        diffusion_parameter_transition_matrix=[1],
         | 
| @@ -216,11 +216,11 @@ class Track_generator: | |
| 216 216 | 
             
                    for i in range(3):
         | 
| 217 217 | 
             
                        rel_space_lim[i] = self.space_lim[i] - initials[i]
         | 
| 218 218 | 
             
                    # convert the diffusion_coefficients
         | 
| 219 | 
            -
                     | 
| 219 | 
            +
                    diffusion_parameters = self._convert_diffcoef_um2s_um2xms(diffusion_parameters)
         | 
| 220 220 | 
             
                    # initialize the fbm class
         | 
| 221 221 | 
             
                    fbm = FBM_BP(
         | 
| 222 222 | 
             
                        n=track_length,
         | 
| 223 | 
            -
                        dt= | 
| 223 | 
            +
                        dt=1,
         | 
| 224 224 | 
             
                        hurst_parameters=hurst_parameters,
         | 
| 225 225 | 
             
                        diffusion_parameters=diffusion_parameters,
         | 
| 226 226 | 
             
                        diffusion_parameter_transition_matrix=diffusion_transition_matrix,
         | 
| @@ -96,10 +96,7 @@ class LaserParameters: | |
| 96 96 | 
             
                        Power in watts
         | 
| 97 97 | 
             
                    """
         | 
| 98 98 | 
             
                    if callable(self.power):
         | 
| 99 | 
            -
                         | 
| 100 | 
            -
                        if power < 0:
         | 
| 101 | 
            -
                            raise ValueError("Laser Power Cannot be Negative")
         | 
| 102 | 
            -
                        return power
         | 
| 99 | 
            +
                        return self.power(t)
         | 
| 103 100 | 
             
                    return self.power
         | 
| 104 101 |  | 
| 105 102 | 
             
                def get_position(self, t: float) -> Tuple[float, float, float]:
         | 
| @@ -371,16 +368,15 @@ class WidefieldBeam(LaserProfile): | |
| 371 368 | 
             
                    Returns:
         | 
| 372 369 | 
             
                        Intensity scaling factor between 0 and 1
         | 
| 373 370 | 
             
                    """
         | 
| 374 | 
            -
                    #  | 
| 375 | 
            -
                    #  | 
| 376 | 
            -
                     | 
| 377 | 
            -
             | 
| 378 | 
            -
                    #  | 
| 379 | 
            -
                     | 
| 380 | 
            -
             | 
| 381 | 
            -
                    #  | 
| 382 | 
            -
                     | 
| 383 | 
            -
                    return 1.0
         | 
| 371 | 
            +
                    # Use error function for smooth transition at DoF boundaries
         | 
| 372 | 
            +
                    # Scale factor determines how sharp the transition is
         | 
| 373 | 
            +
                    scale_factor = 2.0  # Adjust this to change transition sharpness
         | 
| 374 | 
            +
             | 
| 375 | 
            +
                    # Normalize z by DoF and create smooth falloff
         | 
| 376 | 
            +
                    normalized_z = scale_factor * (np.abs(z) - self.dof / 2) / self.dof
         | 
| 377 | 
            +
             | 
| 378 | 
            +
                    # Use sigmoid function for smooth transition
         | 
| 379 | 
            +
                    return 1 / (1 + np.exp(normalized_z))
         | 
| 384 380 |  | 
| 385 381 | 
             
                def calculate_intensity(
         | 
| 386 382 | 
             
                    self,
         | 
| @@ -417,7 +413,7 @@ class WidefieldBeam(LaserProfile): | |
| 417 413 | 
             
                    base_intensity = power / (np.pi * self.max_radius**2)
         | 
| 418 414 |  | 
| 419 415 | 
             
                    # Apply radial intensity profile with smooth falloff at edges
         | 
| 420 | 
            -
                    edge_width = self.max_radius * 0. | 
| 416 | 
            +
                    edge_width = self.max_radius * 0.1  # 10% of max radius
         | 
| 421 417 | 
             
                    radial_profile = 0.5 * (1 - np.tanh((r - self.max_radius) / edge_width))
         | 
| 422 418 | 
             
                    # Apply DoF-based axial intensity profile
         | 
| 423 419 | 
             
                    axial_profile = self._calculate_dof_profile(z_shifted)
         | 
| @@ -426,6 +422,32 @@ class WidefieldBeam(LaserProfile): | |
| 426 422 | 
             
                    return base_intensity * radial_profile * axial_profile
         | 
| 427 423 |  | 
| 428 424 |  | 
| 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 | 
            +
             | 
| 429 451 | 
             
            class HiLoBeam(LaserProfile):
         | 
| 430 452 | 
             
                """
         | 
| 431 453 | 
             
                Highly Inclined Laminated Optical (HiLo) illumination profile.
         | 
| @@ -527,3 +549,143 @@ class HiLoBeam(LaserProfile): | |
| 527 549 | 
             
                    lamination_factor = np.exp(-np.abs(z_shifted) / (2 * self.axial_resolution))
         | 
| 528 550 |  | 
| 529 551 | 
             
                    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
         | 
    
        AMS_BP/optics/psf/psf_engine.py
    CHANGED
    
    | @@ -85,19 +85,15 @@ class PSFEngine: | |
| 85 85 | 
             
                    self._grid_xy = _generate_grid(self._psf_size, self.params.pixel_size)
         | 
| 86 86 |  | 
| 87 87 | 
             
                    # Pre-calculate normalized sigma values
         | 
| 88 | 
            -
                    self._norm_sigma_xy = self._sigma_xy / 2. | 
| 89 | 
            -
                    self._norm_sigma_z = self._sigma_z / 2. | 
| 88 | 
            +
                    self._norm_sigma_xy = self._sigma_xy / 2.355
         | 
| 89 | 
            +
                    self._norm_sigma_z = self._sigma_z / 2.355
         | 
| 90 90 |  | 
| 91 91 | 
             
                    # Generate pinhole mask if specified
         | 
| 92 92 | 
             
                    if self.params.pinhole_radius is not None:
         | 
| 93 93 | 
             
                        if self.params.pinhole_radius < AIRYFACTOR * self._sigma_xy:
         | 
| 94 | 
            -
                             | 
| 94 | 
            +
                            raise ValueError(
         | 
| 95 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 96 | 
             
                            )
         | 
| 97 | 
            -
                            #
         | 
| 98 | 
            -
                            # raise ValueError(
         | 
| 99 | 
            -
                            #     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."
         | 
| 100 | 
            -
                            # )
         | 
| 101 97 | 
             
                        self._pinhole_mask = self._generate_pinhole_mask()
         | 
| 102 98 | 
             
                    else:
         | 
| 103 99 | 
             
                        self._pinhole_mask = None
         | 
| @@ -120,9 +116,7 @@ class PSFEngine: | |
| 120 116 | 
             
                    return (r <= self.params.pinhole_radius).astype(np.float64)
         | 
| 121 117 |  | 
| 122 118 | 
             
                @lru_cache(maxsize=128)
         | 
| 123 | 
            -
                def psf_z(
         | 
| 124 | 
            -
                    self, x_val: float, y_val: float, z_val: float, norm_scale: bool = True
         | 
| 125 | 
            -
                ) -> NDArray[np.float64]:
         | 
| 119 | 
            +
                def psf_z(self, z_val: float) -> NDArray[np.float64]:
         | 
| 126 120 | 
             
                    """Calculate the PSF at the detector for a point source at z_val.
         | 
| 127 121 |  | 
| 128 122 | 
             
                    This represents how light from a point source at position z_val
         | 
| @@ -130,28 +124,17 @@ class PSFEngine: | |
| 130 124 | 
             
                    detector. If a pinhole is present, it spatially filters this pattern.
         | 
| 131 125 |  | 
| 132 126 | 
             
                    Args:
         | 
| 133 | 
            -
                        x_val: x-position of the point source in micrometers
         | 
| 134 | 
            -
                        y_val: y-position of the point source in micrometers
         | 
| 135 127 | 
             
                        z_val: Z-position of the point source in micrometers
         | 
| 136 128 |  | 
| 137 129 | 
             
                    Returns:
         | 
| 138 130 | 
             
                        2D array containing the light intensity pattern at the detector
         | 
| 139 131 | 
             
                    """
         | 
| 140 132 | 
             
                    x, y = self._grid_xy
         | 
| 141 | 
            -
                    sigma_xy_z_squared = (self._norm_sigma_xy**2) * (
         | 
| 142 | 
            -
                        1 + (z_val / self._norm_sigma_z) ** 2
         | 
| 143 | 
            -
                    )
         | 
| 144 133 |  | 
| 145 134 | 
             
                    # Calculate how light from the point source diffracts through collection optics
         | 
| 146 | 
            -
                    r_squared = (x  | 
| 147 | 
            -
             | 
| 148 | 
            -
                     | 
| 149 | 
            -
                    psf_at_detector = np.exp(-0.5 * (r_squared / sigma_xy_z_squared))
         | 
| 150 | 
            -
             | 
| 151 | 
            -
                    if norm_scale:
         | 
| 152 | 
            -
                        psf_at_detector = self.normalize_psf(
         | 
| 153 | 
            -
                            psf_at_detector, mode="sum"
         | 
| 154 | 
            -
                        ) * self.psf_z_xy0(z_val)
         | 
| 135 | 
            +
                    r_squared = (x / self._norm_sigma_xy) ** 2 + (y / self._norm_sigma_xy) ** 2
         | 
| 136 | 
            +
                    z_term = (z_val / self._norm_sigma_z) ** 2
         | 
| 137 | 
            +
                    psf_at_detector = np.exp(-0.5 * (r_squared + z_term))
         | 
| 155 138 |  | 
| 156 139 | 
             
                    if self._pinhole_mask is not None:
         | 
| 157 140 | 
             
                        # Apply pinhole's spatial filtering
         | 
| @@ -269,7 +252,7 @@ def calculate_psf_size( | |
| 269 252 | 
             
                    Tuple of dimensions (z,y,x) or (y,x) for the PSF calculation
         | 
| 270 253 | 
             
                """
         | 
| 271 254 | 
             
                # Calculate radius to capture important features (2x Airy radius)
         | 
| 272 | 
            -
                r_psf =  | 
| 255 | 
            +
                r_psf = 2 * sigma_xy
         | 
| 273 256 |  | 
| 274 257 | 
             
                # Convert to pixels and ensure odd number
         | 
| 275 258 | 
             
                pixels_xy = int(np.ceil(r_psf / pixel_size))
         | 
| @@ -168,11 +168,11 @@ class incident_photons: | |
| 168 168 | 
             
                            photons_n = self.transmission_photon_rate.values[i] * dt
         | 
| 169 169 | 
             
                            photons += photons_n
         | 
| 170 170 | 
             
                            psf_gen = (
         | 
| 171 | 
            -
                                self.generator[i]. | 
| 172 | 
            -
                                     | 
| 173 | 
            -
                                     | 
| 174 | 
            -
                                    z_val=self.position[2],
         | 
| 171 | 
            +
                                self.generator[i].normalize_psf(
         | 
| 172 | 
            +
                                    self.generator[i].psf_z(z_val=self.position[2]),
         | 
| 173 | 
            +
                                    mode="sum",
         | 
| 175 174 | 
             
                                )
         | 
| 175 | 
            +
                                * self.generator[i].psf_z_xy0(z_val=self.position[2])
         | 
| 176 176 | 
             
                                * photons_n
         | 
| 177 177 | 
             
                            )
         | 
| 178 178 |  | 
| @@ -27,7 +27,6 @@ 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
         | 
| 31 30 |  | 
| 32 31 | 
             
                def __call__(
         | 
| 33 32 | 
             
                    self,
         | 
| @@ -49,9 +48,7 @@ class StateTransitionCalculator: | |
| 49 48 | 
             
                    time = 0
         | 
| 50 49 | 
             
                    transitions = self.flurophoreobj.state_history[self.current_global_time][2]
         | 
| 51 50 | 
             
                    final_state_name = transitions[0].from_state
         | 
| 52 | 
            -
                    laser_intensities = self._initialize_state_hist(
         | 
| 53 | 
            -
                        self.current_global_time, time + self.current_global_time_s
         | 
| 54 | 
            -
                    )
         | 
| 51 | 
            +
                    laser_intensities = self._initialize_state_hist(self.current_global_time, time)
         | 
| 55 52 |  | 
| 56 53 | 
             
                    while time < self.time_duration:
         | 
| 57 54 | 
             
                        stateTransitionMatrixR = [
         | 
    
        AMS_BP/sim_microscopy.py
    CHANGED
    
    | @@ -73,9 +73,7 @@ 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) | 
| 77 | 
            -
                                laser_power[laser], float
         | 
| 78 | 
            -
                            ):
         | 
| 76 | 
            +
                            if isinstance(self.lasers[laser].params.power, float):
         | 
| 79 77 | 
             
                                if laser_power[laser] > self.lasers[laser].params.max_power:
         | 
| 80 78 | 
             
                                    raise ValueError(
         | 
| 81 79 | 
             
                                        "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.231
         | 
| 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,5 +171,3 @@ 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=rqdkAwhLvzoA4UNC7EgJOgze5vTlp72Cm62WfiIINCc,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=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
         | 
| @@ -16,10 +16,10 @@ AMS_BP/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 | |
| 16 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=eig4WtD7o1cvIafWMjOk6pqxyhe_IIucgLcBEoDvasU,11648
         | 
| 19 | 
            -
            AMS_BP/motion/track_gen.py,sha256= | 
| 19 | 
            +
            AMS_BP/motion/track_gen.py,sha256=Z3QJLVMP1gX4SlgOXFxBg8sJhBG0Xq25ixnBoEHEAZI,19462
         | 
| 20 20 | 
             
            AMS_BP/motion/movement/__init__.py,sha256=PqovpG4dAuFFIP9M2_kt-6egQJX3P5ig4MMWVzNaswg,278
         | 
| 21 21 | 
             
            AMS_BP/motion/movement/boundary_conditions.py,sha256=jpfK3AEUY8btrTsu19bpUfx-jri7_HfyxqMFjMoxAVM,2200
         | 
| 22 | 
            -
            AMS_BP/motion/movement/fbm_BP.py,sha256= | 
| 22 | 
            +
            AMS_BP/motion/movement/fbm_BP.py,sha256=dH-JZiAInnIaZXH1wAAo8dOIX9zafclqnZ4dOhKtnO0,9327
         | 
| 23 23 | 
             
            AMS_BP/optics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 24 24 | 
             
            AMS_BP/optics/camera/__init__.py,sha256=eCoDUFHcoCWgbgYdLn8EH7AULM53A3XWTXNZnV8QxeY,182
         | 
| 25 25 | 
             
            AMS_BP/optics/camera/detectors.py,sha256=_815Ovo7Aj375OZh5Xim8pFuZEEcSVtSdnLRYFqb3_8,10355
         | 
| @@ -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=J9czY646XcW8GzXx9Eb16mG7tQdWw4oVYveOrihZCeY,22745
         | 
| 33 33 | 
             
            AMS_BP/optics/psf/__init__.py,sha256=ezrKPgpTeR4gTHOvF0mhF6u2zMMTd8Bgp8PGeOf11fA,121
         | 
| 34 | 
            -
            AMS_BP/optics/psf/psf_engine.py,sha256= | 
| 34 | 
            +
            AMS_BP/optics/psf/psf_engine.py,sha256=Do54D1jMbSrj5uljdTrrEttCvxq3qbVT74acRuOk15c,9434
         | 
| 35 35 | 
             
            AMS_BP/photophysics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 36 | 
            -
            AMS_BP/photophysics/photon_physics.py,sha256= | 
| 37 | 
            -
            AMS_BP/photophysics/state_kinetics.py,sha256= | 
| 36 | 
            +
            AMS_BP/photophysics/photon_physics.py,sha256=QRG_QIZ4csJ3g5qGP9Wtk7kzqm8_MUbVHfFef6cMtHQ,6671
         | 
| 37 | 
            +
            AMS_BP/photophysics/state_kinetics.py,sha256=0cc7Vc4LtAbEdGDeg22IJmRGLsONOty4c32hXHO-TSU,5281
         | 
| 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.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,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |