.. _changes: Change Log ========== v2.0.3 ~~~~~~ Refactor of how we define ions and atoms. We now define a subclass of ``AtomFactory`` for each atom / ion definition. Pre-defined levels are now attributes of these classes. This change is partly motivated by making it easier to write species-agnostic code (makes it easier to write things like ``factory.S12`` rather than having to access module-level attributes as well as the factory object). v2.0 ~~~~ This version gives the ``atomic_physics`` API a much needed tidy up. A major design goal for the tidy up was to make things more obvious for the user. This comes at the expense of some function names now being quite a bit more verbose, but that feels like a worthwhile price to pay for clarity! Misc: * We now have a documentation build. Closes `#32 <https://github.com/OxfordIonTrapGroup/atomic_physics/issues/32>`_ * States are now ordered in *decreasing* energy order, not increasing! This change allows the Pauli matrices to take on their customary meanings and signs, for example with :math:`\sigma_+` being the raising operator and energies being represented by :math:`+\frac{1}{2}\omega\sigma_z`. * Formatting and linting moved from flake8 and black to ruff * CI now checks type annotations using pytype * Fix assorted type annotation and docstring bugs * Significantly expanded test coverage * Significantly expanded documentation * Added helper functions to convert between different polarization representations * Added a helper function to calculate the Rayleigh range of a beam * Added a new ``polarizations`` module for representing and manipulating polarizations. * Added a new ``RFDrive`` class. This is a bit heavyweight for just calculating AC Zeeman shifts (which is all we use it for at present) but it is mainly intended for a future optical bloch equations solver. * Added a simple ``TwoStateAtom`` class to help making simple tests and simulations. Bug fixes: * Calculate derivatives properly in transition sensitivity calculations. Closes `#24 <https://github.com/OxfordIonTrapGroup/atomic_physics/issues/24>`_ * Fix indexing in AC Zeeman shift calculation. Closes `#78 <https://github.com/OxfordIonTrapGroup/atomic_physics/issues/78>`_ * Fix incorrect transition frequencies for calcium API refactor: * Named tuples have been replaced with data classes * We no longer export classes at the module level. Replace `import atomic_physics as ap` with `from atomic_physics.core import Atom` * General push to avoid "partially constructed objects" - i.e. objects where we can't set all the fields at construction time so rely on mutating them in non-obvious ways over the object's lifetime. This makes the code easier to follow and removes the need for a bunch of checks to see if fields have been initialised. * General push to make variable and function names more explicit, even at the cost of increased verbosity (optimizing for least surprise not fewest keystrokes!). Closes `#30 <https://github.com/OxfordIonTrapGroup/atomic_physics/issues/30>`_ * ``LevelData`` now only contains the atomic structure data; information about the energy-ordering of states is now in a separate ``LevelStates`` object. * ``Atom.slice`` has been renamed to ``Atom.get_slice_for_level``. This avoids shadowing the name of a built-in python type. * ``Atom.detuning`` has been renamed to ``Atom.get_transition_frequency_for_states``. This method supports an additional ``relative`` keyword to calculate absolute transition frequencies. Closes `#29 <https://github.com/OxfordIonTrapGroup/atomic_physics/issues/29>`_ * ``Atom.index`` has been split into ``get_states_for_M``, ``get_state_for_F``, ``get_state_for_MI_MJ``. This avoids having one function which does lots of different jobs and has a return type which depends in non-obvious ways on the input parameters. * ``Atom.level`` has been renamed ``get_level_for_state`` * added a new ``Atom.get_transition_for_levels`` helper function * ``Atom.population`` has been removed as it wasn't particularly useful * ``Atom.I0`` has been renamed ``Atom.get_saturation_intensity`` * ``Atom.P0`` has been renamed ``intensity_to_power`` * ``Laser.q`` has been renamed to ``Laser.polarization`` * ``Laser.I`` has been renamed to ``Laser.intensity`` * ``Atom.B`` has been renamed to ``Atom.magnetic_field`` * ``Atom.I`` has been renamed to ``Atom.nuclear_spin`` * ``Laser.delta`` has been renamed to ``Laser.detuning`` * ``RateEquations.get_spont`` has been renamed to ``RateEquations.get_spont_matrix``. * ``RateEquations.get_stim`` has been renamed to ``RateEquations.get_stim_matrix``. * ``RateEquations.get_transitions`` has been renamed to ``RateEquations.get_transitions_matrix``. * ``RateEquations.steady_state`` has been renamed to ``RateEquations.get_steady_state_populations``. * ``RateEquations.get_steady_state_populations`` now only takes a transitions matrix as an input, not a transitions matrix or a set of lasers (supporting multiple input types saved a little boiler plate at the expense of making things complex/confusing). * angular frequencies are denoted ``w`` not ``f`` * Methods where we don't care about the orderings of states / levels now take a tuple of states / levels rather than asking for an "upper" and "lower" one * The AC Zeeman shift code now takes a ``RFDrive`` object * Polarizations are new represented by Jones vectors rather than +-1 or 0. The old system was relatively easy once one understood it, but only worked for the simple case of rate equations. Anticipating doing more complex things like optical bloch equations, I've started moving us over to Jones vectors. * Add ``operators.expectation_value`` helper method. * Add ``Atom.levels`` field. * Add new ``Atom.get_states_for_level`` method. * ``utils.field_insensitive_point`` now works with values of ``F`` and ``M_F`` instead of state indices.