Skip to content

Latest commit

 

History

History
110 lines (87 loc) · 10.2 KB

File metadata and controls

110 lines (87 loc) · 10.2 KB

SPECULA Changelog

[Next version]

New processing and data objects

  • ...

Interface changes

  • Added pyr_max_side_ld to ModulatedPyramid and its derived classes to cap the radial support of the pyramid surface in lambda/D units, forcing values outside the support radius to zero and enabling a central fifth pupil.
  • Added compute_single_im (bool, default True) to ImCalibrator to optionally skip populating the out_single_im per-mode output (the output itself is always present, empty when disabled). When True (default, unchanged behavior) this costs an O(nmodes) Python loop on every trigger_code() call (not just push-pull events) plus roughly double the fixed memory (one extra Intmat per mode); set to False to skip that loop/memory when nothing downstream consumes out_single_im (only out_intmat is used elsewhere in this codebase) -- needed for large-nmodes, long calibrations.

Other

  • IFunc.inverse() now computes the pseudoinverse via the smaller of the two Gram matrices (specula.lib.fast_pinv) instead of calling xp.linalg.pinv directly on the full influence-function matrix. Mathematically identical result (including in the rank-deficient case), but substantially faster for the typical case of many pixels and few modes -- measured 3x-8x on real KL/zonal influence-function bases, with the speedup growing with pixel count. Added test_fast_pinv.py.

[1.0.4] - 2026-08-19

New processing and data objects

  • Added IntValue, FloatValue and StringValue as specialized containers for scalars and strings, to be used in place of BaseValue where needed.
  • Added DisplayRecorder processing object
  • Added Phasescreen data object.
  • Added Phase Extractor processing object.
  • Added CLOSE gain optimizer processing object.
  • Added RoundToMultiple processing object.
  • Added EfReplay class (specula.ef_replay): replays a list of existing ElectricField/Layer outputs (e.g. an ElectricFieldCombinator or a DM's out_layer) exactly as they were in a past run, by targeting the existing object(s) directly with Simul.build_targeted_replay instead of synthesizing new off-axis sources like FieldAnalyser does. Complements FieldAnalyser for cases where a disturbance was injected downstream of AtmoPropagation (see FieldAnalyser's new "Limitation" tutorial section) and the exact original direction/sensor is what's needed. Added docs/tutorials/ef_replay_tutorial.rst and test_ef_replay.py

Interface changes

  • Removed simul_params argument from IirFilter, Integrator and other related processing objects
  • Outputs for SpeculaInput and derived objects like TerminalInput must be typed with :int, :float or :str
  • Added "window" and "subplot" arguments to all displays to enable multi-plot windows
  • Renamed MmsePistonUnwrapper to SoftLimiter and moved the module to specula.processing_objects.soft_limiter
  • Added stroke thresholding for dm class
  • Added open_loop_estimate parameter to OpticalGainEstimator.
  • Enabled start and end time (start_time and end_time parameters) in FieldAnalyser.
  • Added "out_window_id" output to all displays to support video recording
  • Added "beam_center" for uplink beam in pixel. Used for Fresnel propagation to indicate if beam is not located in the center.
  • Added pupil_mask parameter to SprintShSynim, forwarded to BaseSprintEstimator as the WFS-side pupil (previously silently fell back to dm.mask, e.g. missing spider obscuration); added regression test in test_sprint.py
  • Enabled pyr_tlt_coeffs for the modulated_pyramid, allowing to correctly set different tilt coefficients for the pyramid faces
  • Extracted FieldAnalyser's shared replay machinery (params loading, replay precision/downsampling checks, temp-simulation execution) into a new BaseReplayAnalyser base class, reused by EfReplay; pure refactor, no behavior change (mock patch targets for Simul/specula in test_field_analyser.py moved to specula.base_replay_analyser accordingly)
  • Added "out_slopes_map" output to Slopec (and thus to all its subclasses, e.g. PyrSlopec, ShSlopec): a 2d remap of the slopes vector (shape (2, size_x, size_y) for a single subaperture, reusing the existing single_mask/display_map/get2d() machinery), useful to store slopes in DataStore with a (timesteps, 2, size_x, size_y) shape instead of a flat vector. Added "out_pixels_subap" (raw, pre-threshold pixel intensities of the 4 pyramid pupils, shape (4, size_x, size_y)) and "out_pixels_subap_sum" (their sum, shape (size_x, size_y), e.g. for scintillation analysis) outputs to PyrSlopec. Added PupData.local_display_map() helper. No changes needed to DataStore, which already saves whatever shape an output's get_value() returns.

Other

  • Fixed Simul.build_targeted_replay/FieldAnalyser silently dropping disturbances injected downstream of the replay target via ElectricFieldCombinator/PhaseScreenCube (SPECULA #696: e.g. a phase screen summed onto an AtmoPropagation source's output before the WFS), which could bias off-axis FieldAnalyser results with a spurious, direction-independent term. build_targeted_replay now raises ValueError by default (opt-out via on_missing_downstream_consumers='warn'/'ignore') when such a silently-dropped ElectricField/Layer-producing consumer is detected; FieldAnalyser exposes the same on_missing_downstream_consumers parameter (default 'error'). Added regression tests in test_simul.py and test_field_analyser.py, and a new "Limitation" section in docs/tutorials/field_analyser_tutorial.rst
  • Fixed RandomGenerator objects with no explicit seed not being reproducible across a replay (e.g. via Simul.build_targeted_replay/FieldAnalyser): the actually-resolved seed is now recorded in replay_params.yml at the end of a run and re-injected on replay (Simul.inject_recorded_seeds), leaving fresh, non-replay runs unaffected (still ambient-random by default). Added RandomGenerator.get_resolved_seed() / BaseProcessingObj.get_resolved_seed() hook and DataSource random_seeds parameter; added tests in test_generators.py, test_simul.py and test_field_analyser.py
  • Fixed BaseOperation using stale/uninitialized input values when in_value1 or in_value2 had never been generated
  • Fixed vecWeiPixRadT extraction in ShSlopec
  • Fixed output_names in PhaseScreenCube
  • Fixed PhaseScreenCube crash on GPU due to np.searchsorted called on a cupy array
  • Fixed start_time bug in WindowedIntegration
  • Fixed SprintShSynim's _plot_debug_info passing GPU (cupy) arrays directly to matplotlib without cpuArray() conversion, crashing on GPU
  • Corrected SprintShSynim's docstring/perturbation labels for enable_wpup_magn_xy: params [4]/[5] are anamorphosis_90/anamorphosis_45 (functional in SynIM via compute_im_synim), not independent magn_x/magn_y as previously (incorrectly) documented as "not yet implemented"
  • Added regression test (test_sprint_anamorphic_magnification_is_functional) verifying enable_wpup_magn_xy's anamorphosis_90/anamorphosis_45 parameters actually affect the computed nominal IM
  • SPRINT logger lever changed to debug for intermediate steps
  • Bumped synim requirement to 1.2.3 (was 1.1.3)
  • Optimization of the compute_ifs_covmat function
  • Added Fraunhofer far field propagation
  • Fixed silent misparsing/confusing errors in split_output() when an object, alias or output name contained a reserved '.', '-' or ':' character; added early validation of YAML section names in Simul
  • Fixed A size in get_pyr_tlt, adding a round (rather than flooring by default) to avoid cases where the pyramid tilt mask (pyr_tlt) and the focal plane mask (fp_mask) could be of different sizes when using an odd number of pixels across the pupil
  • Updated calculation of power loss such that reference PSF also uses Fresnel propagation
  • Fixed ModulatedPyramid/ModulatedDoubleRoof.calc_pyr_geometry producing pupils smaller than the requested pup_diam pixels whenever pup_dist was large enough to trigger the fft_res_min increase (roughly pup_dist > 1.73 * pup_diam with default pup_margin): fft_totsize grew with the bumped fft_res, but toccd_side (the internal CCD side the FFT-plane pupils are rebinned to via toccd()) stayed frozen at the value computed from the pre-bump, nominal fft_res, shrinking the sub-pupils after rebinning. toccd_side is now recomputed from the final fft_res returned by calc_geometry. Added regression test in test_pyr.py

[1.0.3] - 2026-05-18

New processing and data objects:

  • CiaoCiao WFS and slope computer
  • Chromatic effects in atmospheric propagation
  • Phasescreen cube processing object
  • SpatioTempArray data object
  • Interactive inputs, dynamic versions of pupil calibrators and dark calibrators for hardware-in-the-loop simulations
  • Multi-rate modal reconstructor: selection of multiple reconstruction matrices depending on which inputs are valid at a given time
  • Multi-rate complementary filter
  • Separated modal reconstructor with explicit Pseudo-Open Loop algorithm into its own processing object
  • PupilstopController: processing object for generation of pupilstop-like layers
  • MMSE piston unwrapper processing object
  • Added script to plot influence functions
  • New parameters and interface changes:

New parameters and interface changes

  • Using the standard Python logging module instead of print(), verbose parameters removed, added --log-level command line argument
  • Added optional downsampling in DataStore
  • FieldAnalyzer support custom influence functions and optional displays
  • Added band limit factor in AtmoPropagation
  • Added layer height parameter in AtmoRandomPhase
  • ElectrictFieldCombinator optionally accepts an input EF list instead of two separate EFs
  • Added scaling factor to PhaseScreenCube
  • Added computation of PSF profile and metrics to Psf and PsfCoronograph
  • Added optional wavelength parameter (and tolerance) in ElectricField
  • Removed value2_is_shorter parameter from BaseOperation, now automatically derived
  • Removed unused parameters tag_template from rec, subap and sn calibrators.
  • Other updates and bugfixes:

Other updates and bugfixes

  • Support for python 3.14
  • Changed phase unwrapping algorithm in ModalAnalysis, can run on GPU as well
  • Fixed SH-like normalzation in pyramid slope computer
  • Fixed #380 (wrong error message during initialization)
  • Calculation precision handling
  • Fixed SynIM dependency to version 1.1.3
  • remove_piston flag in IFunc inverse method
  • Many other minor bugfixes