pulsus-spec 0.1.1__tar.gz

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.
Files changed (33) hide show
  1. pulsus_spec-0.1.1/LICENSE +30 -0
  2. pulsus_spec-0.1.1/PKG-INFO +652 -0
  3. pulsus_spec-0.1.1/README.md +626 -0
  4. pulsus_spec-0.1.1/pyproject.toml +59 -0
  5. pulsus_spec-0.1.1/setup.cfg +4 -0
  6. pulsus_spec-0.1.1/src/pulsus/__init__.py +133 -0
  7. pulsus_spec-0.1.1/src/pulsus/linear.py +518 -0
  8. pulsus_spec-0.1.1/src/pulsus/liouville.py +213 -0
  9. pulsus_spec-0.1.1/src/pulsus/plotting.py +192 -0
  10. pulsus_spec-0.1.1/src/pulsus/pulses.py +211 -0
  11. pulsus_spec-0.1.1/src/pulsus/resolvents.py +74 -0
  12. pulsus_spec-0.1.1/src/pulsus/response.py +872 -0
  13. pulsus_spec-0.1.1/src/pulsus/spectra.py +594 -0
  14. pulsus_spec-0.1.1/src/pulsus/system.py +115 -0
  15. pulsus_spec-0.1.1/src/pulsus/time_domain.py +798 -0
  16. pulsus_spec-0.1.1/src/pulsus_spec.egg-info/PKG-INFO +652 -0
  17. pulsus_spec-0.1.1/src/pulsus_spec.egg-info/SOURCES.txt +31 -0
  18. pulsus_spec-0.1.1/src/pulsus_spec.egg-info/dependency_links.txt +1 -0
  19. pulsus_spec-0.1.1/src/pulsus_spec.egg-info/requires.txt +7 -0
  20. pulsus_spec-0.1.1/src/pulsus_spec.egg-info/top_level.txt +1 -0
  21. pulsus_spec-0.1.1/tests/test_conjugation_symmetry.py +93 -0
  22. pulsus_spec-0.1.1/tests/test_finite_pulse_rwa.py +171 -0
  23. pulsus_spec-0.1.1/tests/test_linear.py +357 -0
  24. pulsus_spec-0.1.1/tests/test_liouville.py +100 -0
  25. pulsus_spec-0.1.1/tests/test_notebook01_regression.py +245 -0
  26. pulsus_spec-0.1.1/tests/test_notebook04_regression.py +499 -0
  27. pulsus_spec-0.1.1/tests/test_plotting.py +172 -0
  28. pulsus_spec-0.1.1/tests/test_pulses.py +241 -0
  29. pulsus_spec-0.1.1/tests/test_resolvents.py +71 -0
  30. pulsus_spec-0.1.1/tests/test_response.py +402 -0
  31. pulsus_spec-0.1.1/tests/test_spectra.py +731 -0
  32. pulsus_spec-0.1.1/tests/test_system.py +321 -0
  33. pulsus_spec-0.1.1/tests/test_time_domain.py +449 -0
@@ -0,0 +1,30 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Alfonso Castillo-Gonzalez
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice,
10
+ this list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,652 @@
1
+ Metadata-Version: 2.4
2
+ Name: pulsus-spec
3
+ Version: 0.1.1
4
+ Summary: Pulse-dressed Liouvillian Spectroscopy Using Superoperators
5
+ Author: Alfonso Castillo-Gonzalez
6
+ License-Expression: BSD-3-Clause
7
+ Keywords: spectroscopy,nonlinear spectroscopy,quantum dynamics,open quantum systems,Liouville space,superoperators
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Science/Research
10
+ Classifier: Topic :: Scientific/Engineering :: Physics
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Operating System :: OS Independent
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: numpy
20
+ Requires-Dist: scipy
21
+ Requires-Dist: matplotlib
22
+ Requires-Dist: qutip
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest; extra == "dev"
25
+ Dynamic: license-file
26
+
27
+ # PULSUS
28
+
29
+ **PULSUS**: **PU**lse-dressed **L**iouvillian **S**pectroscopy **U**sing **S**uperoperators.
30
+
31
+ PULSUS is a Python package for direct frequency-domain spectroscopy of open quantum systems using Liouville-space superoperators.
32
+
33
+ PULSUS `v0.1.1` focuses on linear and third-order spectroscopy with time-independent Markovian Liouvillian dynamics, including finite Gaussian pulses, impulsive limits, rotating-wave approximations, arbitrary field-sign sectors, and complementary impulsive time-domain calculations.
34
+
35
+
36
+ ## Core idea
37
+
38
+ For a field-free Liouvillian
39
+
40
+ \[
41
+ \mathcal{L},
42
+ \]
43
+
44
+ PULSUS evaluates frequency-domain propagation using resolvent actions
45
+
46
+ \[
47
+ G_\eta(\omega)
48
+ =
49
+ \left[
50
+ (\eta-i\omega)I-\mathcal{L}
51
+ \right]^{-1},
52
+ \]
53
+
54
+ without explicitly constructing the matrix inverse.
55
+
56
+ Finite Gaussian pulses are represented by Liouvillian dressing operators. For example,
57
+
58
+ \[
59
+ F_1^{(s)}
60
+ =
61
+ C e^{is\Phi}
62
+ \exp\left[
63
+ \frac{\sigma^2}{2}
64
+ \left(
65
+ \mathcal{L}
66
+ +i(\omega_1-s\omega_L)I
67
+ \right)^2
68
+ \right].
69
+ \]
70
+
71
+ The production finite-pulse implementation uses the physical field-free Liouvillian inside the pulse dressing,
72
+
73
+ \[
74
+ F_j = F_j(\mathcal{L}),
75
+ \]
76
+
77
+ while the resolvents may use a small positive broadening parameter \(\eta\).
78
+
79
+
80
+ ## Standard finite-pulse assumption
81
+
82
+ The standard finite-pulse formulation assumes that the state immediately before the pulse sequence is stationary under the field-free Liouvillian,
83
+
84
+ \[
85
+ \mathcal{L}|\rho_0\rangle\rangle = 0.
86
+ \]
87
+
88
+ For dissipative systems this is typically the stationary state of the Liouvillian.
89
+
90
+ PULSUS can also accept explicitly supplied initial density matrices for calculations where this assumption is not desired.
91
+
92
+
93
+ ## Third-order spectroscopy
94
+
95
+ PULSUS currently provides four principal third-order models:
96
+
97
+ | Function | Pulse treatment | Light-matter interaction |
98
+ | --- | --- | --- |
99
+ | `finite_pulse_spectrum` | finite Gaussian pulses | full interaction |
100
+ | `impulsive_spectrum` | impulsive | full interaction |
101
+ | `short_pulse_rwa_spectrum` | Gaussian spectral envelopes | RWA |
102
+ | `impulsive_rwa_spectrum` | impulsive | RWA |
103
+
104
+ The impulsive approximation and the rotating-wave approximation are treated as distinct approximations.
105
+
106
+ In particular,
107
+
108
+ \[
109
+ \sigma \rightarrow 0
110
+ \]
111
+
112
+ for the full finite-pulse theory approaches the impulsive **full-interaction** response, not automatically the impulsive RWA response.
113
+
114
+
115
+ ## Linear spectroscopy
116
+
117
+ The corresponding linear-response calculations are available through:
118
+
119
+ ```python
120
+ pulsus.finite_pulse_linear_spectrum
121
+ pulsus.impulsive_linear_spectrum
122
+ pulsus.short_pulse_linear_rwa_spectrum
123
+ pulsus.impulsive_linear_rwa_spectrum
124
+ ```
125
+
126
+
127
+ ## Installation
128
+
129
+ Install the released package from PyPI with:
130
+
131
+ ```bash
132
+ pip install pulsus-spec
133
+ ```
134
+
135
+ The PyPI distribution is named `pulsus-spec`, while the Python package is imported as:
136
+
137
+ ```python
138
+ import pulsus
139
+ ```
140
+
141
+ For development from the repository source:
142
+
143
+ ```bash
144
+ python -m venv .venv
145
+ source .venv/bin/activate
146
+ python -m pip install -e ".[dev]"
147
+ ```
148
+
149
+ Run the test suite with:
150
+
151
+ ```bash
152
+ pytest -q
153
+ ```
154
+
155
+ ## Basic usage
156
+
157
+ A spectroscopy model is defined using `SpectroscopySystem`:
158
+
159
+ ```python
160
+ import pulsus
161
+
162
+ system = pulsus.SpectroscopySystem(
163
+ H=H,
164
+ dipole=mu,
165
+ collapse_ops=collapse_ops,
166
+ )
167
+ ```
168
+
169
+ The stationary state can be obtained from:
170
+
171
+ ```python
172
+ rho_ss = system.stationary_state()
173
+ ```
174
+
175
+ A Gaussian pulse is specified by its carrier frequency, temporal width, amplitude, and phase:
176
+
177
+ ```python
178
+ pulse = pulsus.GaussianPulse(
179
+ omega_L=1.10,
180
+ sigma=1.25,
181
+ E0=1.0,
182
+ phase=0.0,
183
+ )
184
+ ```
185
+
186
+ A finite-pulse nonrephasing spectrum can then be evaluated directly:
187
+
188
+ ```python
189
+ import numpy as np
190
+
191
+ omega1 = np.linspace(0.7, 1.5, 81)
192
+ omega3 = np.linspace(0.7, 1.5, 81)
193
+
194
+ S_NR = pulsus.finite_pulse_spectrum(
195
+ system=system,
196
+ pulse1=pulse,
197
+ pulse2=pulse,
198
+ pulse3=pulse,
199
+ omega1=omega1,
200
+ omega3=omega3,
201
+ T=20.0,
202
+ eta=0.02,
203
+ pathway="NR",
204
+ )
205
+ ```
206
+
207
+ The returned complex array has shape:
208
+
209
+ ```text
210
+ (len(omega3), len(omega1))
211
+ ```
212
+
213
+ with convention
214
+
215
+ \[
216
+ S[j,i]
217
+ =
218
+ S(\omega_{3,j},\omega_{1,i}).
219
+ \]
220
+
221
+
222
+ ## Rephasing and nonrephasing convention
223
+
224
+ PULSUS uses signed first-coherence frequencies.
225
+
226
+ For the nonrephasing sector,
227
+
228
+ \[
229
+ \omega_1>0,
230
+ \]
231
+
232
+ with field-sign signature
233
+
234
+ \[
235
+ (+,-,+).
236
+ \]
237
+
238
+ For the rephasing sector,
239
+
240
+ \[
241
+ \omega_1<0,
242
+ \]
243
+
244
+ with field-sign signature
245
+
246
+ \[
247
+ (-,+,+).
248
+ \]
249
+
250
+ For example:
251
+
252
+ ```python
253
+ omega1_NR = np.linspace(0.7, 1.5, 81)
254
+ omega1_R = -omega1_NR
255
+ ```
256
+
257
+ The rephasing spectrum may be displayed against the positive spectroscopic excitation coordinate `-omega1_R`, but the calculation itself uses signed negative first-coherence frequencies.
258
+
259
+
260
+ ## Arbitrary field-sign sectors
261
+
262
+ PULSUS is not restricted to R and NR pathways.
263
+
264
+ Any third-order signature
265
+
266
+ \[
267
+ (s_1,s_2,s_3),
268
+ \qquad
269
+ s_j=\pm1,
270
+ \]
271
+
272
+ can be supplied explicitly.
273
+
274
+ For example:
275
+
276
+ ```python
277
+ signature = (+1, +1, +1)
278
+
279
+ S = pulsus.finite_pulse_spectrum(
280
+ system=system,
281
+ pulse1=pulse,
282
+ pulse2=pulse,
283
+ pulse3=pulse,
284
+ omega1=omega1,
285
+ omega3=omega3,
286
+ T=20.0,
287
+ eta=0.02,
288
+ signature=signature,
289
+ )
290
+ ```
291
+
292
+ The aliases
293
+
294
+ ```python
295
+ pathway="NR"
296
+ pathway="R"
297
+ ```
298
+
299
+ remain available for the standard nonrephasing and rephasing sectors.
300
+
301
+
302
+ ## Sign-reversed conjugation symmetry
303
+
304
+ For the tested coupled-dimer model, the field-sign sectors satisfy
305
+
306
+ \[
307
+ S_{(-s_1,-s_2,-s_3)}
308
+ (-\omega_1,-\omega_3)
309
+ =
310
+ S_{(s_1,s_2,s_3)}
311
+ (\omega_1,\omega_3)^*
312
+ \]
313
+
314
+ to floating-point precision.
315
+
316
+ This groups the eight possible signatures into four sign-reversed conjugate pairs.
317
+
318
+
319
+ ## Full interaction and RWA
320
+
321
+ Full-interaction calculations require only the total dipole operator
322
+
323
+ \[
324
+ \mu.
325
+ \]
326
+
327
+ RWA calculations additionally require a decomposition
328
+
329
+ \[
330
+ \mu = \mu_+ + \mu_-.
331
+ \]
332
+
333
+ For example:
334
+
335
+ ```python
336
+ system = pulsus.SpectroscopySystem(
337
+ H=H,
338
+ dipole=mu,
339
+ collapse_ops=collapse_ops,
340
+ dipole_plus=mu_plus,
341
+ dipole_minus=mu_minus,
342
+ )
343
+ ```
344
+
345
+ PULSUS currently requires this decomposition to be supplied explicitly rather than inferring it automatically.
346
+
347
+
348
+ ## Time-domain calculations
349
+
350
+ PULSUS also provides impulsive time-domain response functions.
351
+
352
+ For linear spectroscopy:
353
+
354
+ ```python
355
+ R_t = pulsus.impulsive_linear_rwa_time_signal(
356
+ system=system,
357
+ times=times,
358
+ sign=+1,
359
+ )
360
+ ```
361
+
362
+ For third-order spectroscopy:
363
+
364
+ ```python
365
+ R_t3_t1 = pulsus.impulsive_third_order_rwa_time_signal(
366
+ system=system,
367
+ t1=t1,
368
+ t3=t3,
369
+ T=20.0,
370
+ pathway="NR",
371
+ )
372
+ ```
373
+
374
+ These provide a complementary time-domain representation of the same impulsive Liouvillian dynamics used in the direct frequency-domain formulation.
375
+
376
+
377
+ ## Pathway polarization in laboratory time
378
+
379
+ A selected RWA pathway can also be followed through the sequence of three impulsive interactions:
380
+
381
+ ```python
382
+ P, components = pulsus.impulsive_pathway_polarization(
383
+ system=system,
384
+ times=times,
385
+ pulse_times=(5.0, 15.0, 35.0),
386
+ signature=(+1, -1, +1),
387
+ return_components=True,
388
+ )
389
+ ```
390
+
391
+ The resulting polarization is piecewise associated with the perturbative state active between pulses:
392
+
393
+ \[
394
+ P_{\mathrm{path}}(t)
395
+ =
396
+ \begin{cases}
397
+ 0,
398
+ & t<\tau_1,\\
399
+ P^{(1)}(t),
400
+ & \tau_1\le t<\tau_2,\\
401
+ P^{(2)}(t),
402
+ & \tau_2\le t<\tau_3,\\
403
+ P^{(3)}(t),
404
+ & t\ge\tau_3.
405
+ \end{cases}
406
+ \]
407
+
408
+ This is the polarization of the **selected pathway**, not the total physical polarization from all perturbative orders and all field-sign sectors.
409
+
410
+
411
+ ## Complex spectra and plotting
412
+
413
+ PULSUS retains the complete complex response.
414
+
415
+ A spectrum can be plotted with:
416
+
417
+ ```python
418
+ pulsus.plot_spectrum(
419
+ omega1=omega1,
420
+ omega3=omega3,
421
+ spectrum=S_NR,
422
+ component="imag",
423
+ normalize=True,
424
+ )
425
+ ```
426
+
427
+ Supported displayed components are:
428
+
429
+ - `"real"`
430
+ - `"imag"`
431
+ - `"abs"`
432
+
433
+ Normalization is optional and disabled by default.
434
+
435
+
436
+ ## Numerical implementation
437
+
438
+ Two-dimensional spectrum calculations exploit the separable dependence on the excitation and detection frequencies.
439
+
440
+ For a third-order response, the grid can be written schematically as
441
+
442
+ \[
443
+ S_{ji}=L_jR_i,
444
+ \]
445
+
446
+ where \(R_i\) contains the \(\omega_1\)-dependent operations and \(L_j\) contains the \(\omega_3\)-dependent operations.
447
+
448
+ This avoids repeating expensive matrix exponentials and resolvent solves independently at every pair
449
+
450
+ \[
451
+ (\omega_1,\omega_3).
452
+ \]
453
+
454
+ The optimized implementation reproduces the original point-by-point calculations to floating-point precision.
455
+
456
+
457
+ ## Validation
458
+
459
+ PULSUS is tested against independently validated coupled-dimer calculations, frozen reference spectra, and explicit time-domain propagation.
460
+
461
+ For the finite-pulse development benchmark at
462
+
463
+ \[
464
+ \sigma=1.25,
465
+ \qquad
466
+ T=20,
467
+ \qquad
468
+ \eta=0.02,
469
+ \]
470
+
471
+ the production finite-pulse calculation gives complex spectral-shape discrepancies relative to an explicit finite-pulse time-domain ODE calculation of approximately
472
+
473
+ \[
474
+ 0.61\%
475
+ \quad \text{(NR)}
476
+ \]
477
+
478
+ and
479
+
480
+ \[
481
+ 0.64\%
482
+ \quad \text{(R)}.
483
+ \]
484
+
485
+ For comparison:
486
+
487
+ | Model | NR error | R error |
488
+ | --- | ---: | ---: |
489
+ | Finite-width PULSUS | 0.61% | 0.64% |
490
+ | Short-pulse RWA | 5.51% | 5.81% |
491
+ | Impulsive RWA | 9.60% | 9.83% |
492
+
493
+ These values characterize this development benchmark and are not universal accuracy bounds.
494
+
495
+
496
+ ## Time-domain versus frequency-domain validation
497
+
498
+ For impulsive linear RWA response, numerical time propagation followed by an FFT agrees with the direct frequency-domain resolvent calculation with a relative complex error of approximately
499
+
500
+ \[
501
+ 0.0035\%.
502
+ \]
503
+
504
+ For impulsive third-order NR response, two-dimensional time propagation followed by a 2D FFT agrees with the direct frequency-domain result with a relative complex error of approximately
505
+
506
+ \[
507
+ 0.015\%.
508
+ \]
509
+
510
+ These comparisons independently validate the time/frequency sign and transform conventions used in PULSUS.
511
+
512
+
513
+ ## Test suite
514
+
515
+ The current test suite contains **63 passing unit and regression tests** covering:
516
+
517
+ - Liouville-space vectorization and superoperators
518
+ - Lindblad Liouvillian construction
519
+ - stationary states
520
+ - resolvent actions
521
+ - Gaussian pulse dressing
522
+ - pulse-integral identities
523
+ - linear response
524
+ - third-order response
525
+ - R and NR sign conventions
526
+ - arbitrary field-sign signatures
527
+ - finite-pulse, impulsive, short-pulse, and RWA models
528
+ - two-dimensional spectrum construction
529
+ - optimized versus point-by-point evaluation
530
+ - plotting and array orientation
531
+ - frozen finite-pulse regression data
532
+ - impulsive time-domain propagation
533
+ - time-domain pathway polarization
534
+
535
+
536
+ ## Examples
537
+
538
+ The `examples/` directory contains the current development and validation examples.
539
+
540
+ ### Main examples
541
+
542
+ `01_finite_pulse_dimer.py`
543
+
544
+ Builds the coupled dimer and calculates finite-pulse NR and R spectra through the PULSUS API.
545
+
546
+ `03_reproduce_figure6.py`
547
+
548
+ Compares finite-pulse, short-pulse RWA, and impulsive RWA spectra.
549
+
550
+ `06_all_third_order_signatures.py`
551
+
552
+ Calculates all eight third-order field-sign sectors and checks the sign-reversed conjugation relation.
553
+
554
+ `09_linear_td_fft_vs_fd.py`
555
+
556
+ Validates impulsive linear time-domain propagation and FFT against the direct frequency-domain resolvent calculation.
557
+
558
+ `10_third_order_td_fft_vs_fd.py`
559
+
560
+ Validates third-order NR time-domain propagation and a 2D FFT against the direct frequency-domain calculation.
561
+
562
+ `11_impulsive_polarization_traces.py`
563
+
564
+ Visualizes the selected impulsive pathway in laboratory time and separates first-, second-, and third-order polarization stages.
565
+
566
+
567
+ ### Validation and diagnostic examples
568
+
569
+ `02_compare_notebook04.py`
570
+
571
+ Compares the production finite-pulse implementation with frozen explicit-ODE validation data.
572
+
573
+ `04_linear_response_comparison.py`
574
+
575
+ Compares full-interaction and RWA linear spectra.
576
+
577
+ `05_linear_rwa_quadratures.py`
578
+
579
+ Examines real and imaginary quadratures of the linear full-interaction and RWA responses.
580
+
581
+ `07_full_vs_rwa_signatures.py`
582
+
583
+ Compares finite-pulse full-interaction and short-pulse RWA results across third-order signatures.
584
+
585
+ `08_approximation_ladder.py`
586
+
587
+ Separates the effects of the full-interaction, RWA, short-pulse, and impulsive approximations.
588
+
589
+
590
+ ## Current scope
591
+
592
+ PULSUS `v0.1.1` assumes:
593
+
594
+ - finite-dimensional quantum systems
595
+ - time-independent Liouvillian dynamics
596
+ - Markovian Lindblad evolution
597
+ - electric-dipole light-matter coupling
598
+ - Gaussian finite-duration pulses for the finite-pulse frequency-domain formulation
599
+ - temporally ordered, separated pulses
600
+ - linear and third-order response
601
+ - full-interaction and RWA calculations
602
+ - arbitrary third-order field-sign signatures
603
+ - impulsive time-domain propagation
604
+
605
+ Finite-duration driven time-domain propagation is not currently part of the public production API.
606
+
607
+
608
+ ## Public API philosophy
609
+
610
+ The principal user-facing objects and functions are:
611
+
612
+ ```python
613
+ pulsus.SpectroscopySystem
614
+ pulsus.GaussianPulse
615
+
616
+ pulsus.finite_pulse_spectrum
617
+ pulsus.impulsive_spectrum
618
+ pulsus.short_pulse_rwa_spectrum
619
+ pulsus.impulsive_rwa_spectrum
620
+
621
+ pulsus.finite_pulse_linear_spectrum
622
+ pulsus.impulsive_linear_spectrum
623
+ pulsus.short_pulse_linear_rwa_spectrum
624
+ pulsus.impulsive_linear_rwa_spectrum
625
+
626
+ pulsus.impulsive_linear_time_signal
627
+ pulsus.impulsive_third_order_rwa_time_signal
628
+ pulsus.impulsive_pathway_polarization
629
+
630
+ pulsus.plot_spectrum
631
+ ```
632
+
633
+ Additional lower-level response, Liouville-space, resolvent, and pulse-dressing functions remain available for advanced calculations and validation.
634
+
635
+
636
+ ## Repository structure
637
+
638
+ ```text
639
+ .
640
+ ├── src/
641
+ │ └── pulsus/ PULSUS source code
642
+ ├── tests/ unit and regression tests
643
+ ├── examples/ usage and validation examples
644
+ ├── notebooks/ numerical validation notebooks
645
+ ├── figures/ manuscript figures
646
+ ├── results/ benchmark results
647
+ ├── main.tex manuscript / technical development
648
+ ├── references.bib bibliography
649
+ └── literature_notes.md literature notes
650
+ ```
651
+
652
+ PULSUS is under active development.