Skip to content

Conversation

@weiliangjin2021
Copy link
Collaborator

@weiliangjin2021 weiliangjin2021 commented Nov 5, 2025

  • add tests

Greptile Overview

Updated On: 2025-11-05 20:52:36 UTC

Greptile Summary

This PR introduces BroadbandPulse, a new source time dependence class that enables exciting simulations across a wide frequency spectrum. The feature is implemented as a wrapper around the tidy3d-extras licensed implementation.

Key changes:

  • Added BroadbandPulse class in tidy3d/components/source/time.py with configurable frequency range and minimum amplitude
  • Refactored tidy3d-extras checking logic into reusable helper functions (_check_tidy3d_extras_available and check_tidy3d_extras_licensed_feature)
  • Updated documentation and CHANGELOG to reflect the new feature

Issues found:

  • Syntax error in tidy3d/packaging.py:244 - missing 'f' prefix on f-string causes literal {exc!s} to appear in error message instead of being interpolated

Confidence Score: 4/5

  • This PR is mostly safe to merge with one syntax error that needs fixing
  • The implementation is well-structured with proper licensing checks and documentation. However, there's a syntax error in the error message formatting that will cause incorrect error messages to be displayed to users when tidy3d-extras fails to load. This is a user-facing bug that should be fixed before merge.
  • Pay attention to tidy3d/packaging.py which contains a syntax error on line 244

Important Files Changed

File Analysis

Filename Score Overview
tidy3d/components/source/time.py 4/5 Added BroadbandPulse class that wraps tidy3d-extras implementation for wide frequency spectrum excitation
tidy3d/packaging.py 2/5 Refactored tidy3d-extras checking logic with new helper functions; contains f-string formatting bug on line 244

Sequence Diagram

sequenceDiagram
    participant User
    participant BroadbandPulse
    participant Validator
    participant PackagingModule
    participant TidyExtras

    User->>BroadbandPulse: Instantiate with freq_range, minimum_amplitude
    BroadbandPulse->>Validator: _check_broadband_pulse_available()
    Validator->>PackagingModule: check_tidy3d_extras_licensed_feature("BroadbandPulse")
    PackagingModule->>PackagingModule: _check_tidy3d_extras_available()
    
    alt tidy3d-extras not loaded
        PackagingModule->>TidyExtras: import tidy3d_extras
        alt Import fails
            TidyExtras-->>PackagingModule: ImportError
            PackagingModule-->>Validator: Tidy3dImportError
            Validator-->>User: Error: Install tidy3d-extras
        else Import succeeds
            TidyExtras-->>PackagingModule: tidy3d_extras_mod
            PackagingModule->>PackagingModule: Check version and features
            alt BroadbandPulse not in features
                PackagingModule-->>Validator: Tidy3dImportError
                Validator-->>User: Error: Feature not licensed
            else Feature available
                PackagingModule->>PackagingModule: Cache tidy3d_extras["mod"]
                Validator-->>BroadbandPulse: Validation passed
            end
        end
    else tidy3d-extras already loaded
        PackagingModule->>PackagingModule: Check features list
        alt BroadbandPulse not in features
            PackagingModule-->>Validator: Tidy3dImportError
            Validator-->>User: Error: Feature not licensed
        else Feature available
            Validator-->>BroadbandPulse: Validation passed
        end
    end
    
    BroadbandPulse->>User: Instance created
    
    User->>BroadbandPulse: Call amp_time(time) or amp_freq(freq)
    BroadbandPulse->>BroadbandPulse: Access _source property
    BroadbandPulse->>TidyExtras: extension.BroadbandPulse(...)
    TidyExtras-->>BroadbandPulse: BroadbandPulse instance
    BroadbandPulse->>TidyExtras: _source.amp_time(time)
    TidyExtras-->>BroadbandPulse: Complex amplitude
    BroadbandPulse-->>User: Return amplitude
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@weiliangjin2021 weiliangjin2021 force-pushed the weiliang/FXC-2556-microwave branch 2 times, most recently from 6c05805 to 026198a Compare November 5, 2025 20:53
@weiliangjin2021 weiliangjin2021 force-pushed the weiliang/FXC-2556-microwave branch from 026198a to b00febc Compare November 5, 2025 22:19
@github-actions
Copy link
Contributor

github-actions bot commented Nov 5, 2025

Diff Coverage

Diff: origin/develop...HEAD, staged and unstaged changes

  • tidy3d/components/source/time.py (56.7%): Missing lines 636-639,642,647-648,653,664,668,672,676,682
  • tidy3d/packaging.py (54.5%): Missing lines 195,205-206,208-209,213,215-216,221-222,228,252-254,285

Summary

  • Total: 63 lines
  • Missing: 28 lines
  • Coverage: 55%

tidy3d/components/source/time.py

  632 
  633     @pydantic.validator("freq_range", always=True)
  634     def _validate_freq_range(cls, val):
  635         """Validate that freq_range is positive and properly ordered."""
! 636         if val[0] <= 0 or val[1] <= 0:
! 637             raise ValidationError("Both elements of 'freq_range' must be positive.")
! 638         if val[1] <= val[0]:
! 639             raise ValidationError(
  640                 f"'freq_range[1]' ({val[1]}) must be greater than 'freq_range[0]' ({val[0]})."
  641             )
! 642         return val
  643 
  644     @pydantic.root_validator()
  645     def _check_broadband_pulse_available(cls, values):
  646         """Check if BroadbandPulse is available."""
! 647         check_tidy3d_extras_licensed_feature("BroadbandPulse")
! 648         return values
  649 
  650     @cached_property
  651     def _source(self):
  652         """Implementation of broadband pulse."""
! 653         return tidy3d_extras["mod"].extension.BroadbandPulse(
  654             fmin=self.freq_range[0],
  655             fmax=self.freq_range[1],
  656             minRelAmp=self.minimum_amplitude,
  657             amp=self.amplitude,

  660         )
  661 
  662     def end_time(self) -> float:
  663         """Time after which the source is effectively turned off / close to zero amplitude."""
! 664         return self._source.end_time(END_TIME_FACTOR_GAUSSIAN)
  665 
  666     def amp_time(self, time: float) -> complex:
  667         """Complex-valued source amplitude as a function of time."""
! 668         return self._source.amp_time(time)
  669 
  670     def amp_freq(self, freq: float) -> complex:
  671         """Complex-valued source amplitude as a function of frequency."""
! 672         return self._source.amp_freq(freq)
  673 
  674     def frequency_range_sigma(self, sigma: float = DEFAULT_SIGMA) -> FreqBound:
  675         """Frequency range where the source amplitude is within ``exp(-sigma**2/2)`` of the peak amplitude."""
! 676         return self._source.frequency_range(sigma)
  677 
  678     def frequency_range(self, num_fwidth: float = DEFAULT_SIGMA) -> FreqBound:
  679         """Delegated to `frequency_range_sigma(sigma=num_fwidth)` for computing the frequency range where the source amplitude
  680         is within ``exp(-num_fwidth**2/2)`` of the peak amplitude.

  678     def frequency_range(self, num_fwidth: float = DEFAULT_SIGMA) -> FreqBound:
  679         """Delegated to `frequency_range_sigma(sigma=num_fwidth)` for computing the frequency range where the source amplitude
  680         is within ``exp(-num_fwidth**2/2)`` of the peak amplitude.
  681         """
! 682         return self.frequency_range_sigma(num_fwidth)
  683 
  684 
  685 SourceTimeType = Union[GaussianPulse, ContinuousWave, CustomSourceTime, BroadbandPulse]

tidy3d/packaging.py

  191     Tidy3dImportError
  192         If tidy3d-extras is not available or not properly initialized.
  193     """
  194     if tidy3d_extras["mod"] is not None:
! 195         return
  196 
  197     module_exists = find_spec("tidy3d_extras") is not None
  198     if not module_exists:
  199         raise Tidy3dImportError(

  201             "Please install the 'tidy3d-extras' package using, for "
  202             "example, 'pip install tidy3d[extras]'."
  203         )
  204 
! 205     try:
! 206         import tidy3d_extras as tidy3d_extras_mod
  207 
! 208     except ImportError as exc:
! 209         raise Tidy3dImportError(
  210             "The package 'tidy3d-extras' did not initialize correctly."
  211         ) from exc
  212 
! 213     version = tidy3d_extras_mod.__version__
  214 
! 215     if version is None:
! 216         raise Tidy3dImportError(
  217             "The package 'tidy3d-extras' did not initialize correctly, "
  218             "likely due to an invalid API key."
  219         )
  220 
! 221     if version != __version__:
! 222         raise Tidy3dImportError(
  223             f"The version of 'tidy3d-extras' is {version}, but the version of 'tidy3d' is {__version__}. "
  224             "They must match. You can install the correct "
  225             "version using 'pip install tidy3d[extras]'."
  226         )

  224             "They must match. You can install the correct "
  225             "version using 'pip install tidy3d[extras]'."
  226         )
  227 
! 228     tidy3d_extras["mod"] = tidy3d_extras_mod
  229 
  230 
  231 def check_tidy3d_extras_licensed_feature(feature_name: str):
  232     """Helper function to check if a specific feature is licensed in 'tidy3d-extras'.

  248         raise Tidy3dImportError(
  249             "The package 'tidy3d-extras' is required for this feature '{feature_name}'."
  250         ) from exc
  251 
! 252     features = tidy3d_extras["mod"].extension._features()
! 253     if feature_name not in features:
! 254         raise Tidy3dImportError(
  255             f"The feature '{feature_name}' is not available with your license. "
  256             "Please contact Tidy3D support, or upgrade your license."
  257         )

  281             # preference is None, so we can just return
  282             return fn(*args, **kwargs)
  283 
  284         # local_subpixel is available
! 285         tidy3d_extras["use_local_subpixel"] = True
  286         return fn(*args, **kwargs)
  287 
  288     return _fn

Copy link
Contributor

@caseyflex caseyflex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! So now if use_local_subpixel is None, then the feature will be used if everything works (package installed + licensing for that feature), and otherwise it will not be used. I think this makes sense going forward.

@daquinteroflex The install option tidy3d[extras] is still commented out in pyproject.toml. It should be uncommented before release. However I think it will cause an issue with poetry lock because the version is not yet available on pypi. Did we ever decide how to resolve this?

@daquinteroflex
Copy link
Collaborator

Hi @caseyflex I was actually testing just that yesterday https://github.com/flexcompute/tidy3d/pull/2967/files

@weiliangjin2021 weiliangjin2021 force-pushed the weiliang/FXC-2556-microwave branch from 81e3dc1 to 09d91b7 Compare November 11, 2025 17:11
@weiliangjin2021 weiliangjin2021 added this pull request to the merge queue Nov 11, 2025
Merged via the queue into develop with commit 79d8f19 Nov 11, 2025
26 checks passed
@weiliangjin2021 weiliangjin2021 deleted the weiliang/FXC-2556-microwave branch November 11, 2025 18:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants