Module mjoindices.omi.postprocessing_rotation_approach¶
Contains the post-processing of the EOFs as described in Weidman et al. (2022). This is an alternative post-processing approach and does not lead to the same results as shown in Kiladis et al. (2014). It reduces noise and avoids potential degeneracy issues.
The post-processing procedure follows the below steps:
Corrects spontaneous sign changes in the EOFs (same as the original procedure)
Projects EOFs at DOY = n-1 onto EOF space for DOY = n. This is done to reduce spurious oscillations between EOFs on sequential days
Rotate the projected EOFs by 1/366 (or 1/365) per day to ensure continuity across January to December
Renormalize the EOFs to have a length of 1 (this is a small adjustment to account for small numerical errors).
- mjoindices.omi.postprocessing_rotation_approach.angle_between_eofs(reference: ~mjoindices.empirical_orthogonal_functions.EOFData, target=<class 'mjoindices.empirical_orthogonal_functions.EOFData'>)[source]¶
Calculates angle between two EOF vectors to determine their “closeness” \(theta = arccos(t . r / (||r||*||t||))\).
- Parameters:
reference – The reference-EOFs. This is usually the EOF pair of the previous or “first” DOY.
target – The EOF data from the target DOY.
- Returns:
A tuple of the angles between the reference and target EOFs for both EOF1 and EOF2
- mjoindices.omi.postprocessing_rotation_approach.angle_btwn_vectors(vector1, vector2)[source]¶
Calculates the angle between vectors, \(theta = arccos(t . r / (||r||*||t||))\).
- Parameters:
vector1 – 1d vector, generally corresponding to EOF1 or 2 from some DOY
vector2 – 1d vector, generally corresponding to EOF1 or 2 from a different DOY
- Returns:
scalar angle between vectors 1 and 2, in radians.
- mjoindices.omi.postprocessing_rotation_approach.calculate_angle_from_discontinuity(orig_eofs: EOFDataForAllDOYs)[source]¶
Project the matrix to align with the EOFs from the previous DOY and calculate the resulting discontinuity between January 1 and January 1 after one year of projections. Divide by the number of days in one year to determine the discontinuity used for rotation.
- Parameters:
orig_eofs – calculated EOFs, after signs have been changed via spontaneous_sign_changes
- Returns:
float of angular discontinuity between EOF1 on DOY1 and EOF1 on DOY1 after a full year of projection, divided by the length of the year.
- mjoindices.omi.postprocessing_rotation_approach.normalize_eofs(orig_eofs: EOFDataForAllDOYs) EOFDataForAllDOYs [source]¶
Normalize all EOFs to have a magnitude of 1.
- Parameters:
eofdata – The rotated EOF series.
- Returns:
normalized EOFdata for all days.
- mjoindices.omi.postprocessing_rotation_approach.post_process_eofs_rotation(eofdata: EOFDataForAllDOYs, sign_doy1reference: bool = True) EOFDataForAllDOYs [source]¶
Executes the complete post-processing of a series of EOF pairs for all DOYs according to the alterntive procedure described by Weidman et al. (2022).
Postprocessing includes an alignment of EOF signs and a rotation algorithm that rotates the EOFs in three steps:
Projects EOFs at DOY = n-1 onto EOF space for DOY = n. This is done to reduce spurious oscillations between EOFs on sequential days
Rotate the projected EOFs by 1/366 (or 1/365) of the December –> January discontinuity each day to ensure continuity across December to January
Renormalize the EOFs to have a length of 1 (this is a small adjustment to account for small numerical errors).
See documentation of the methods
correct_spontaneous_sign_changes_in_eof_series()
for EOF sign flippingNote that it is recommended to use the function
calc_eofs_from_olr()
to cover the complete algorithm.- Parameters:
eofdata – The EOF series, which should be post processed.
sign_doy1reference – See
correct_spontaneous_sign_changes_in_eof_series()
.
- Returns:
The postprocessed series of EOFs
- mjoindices.omi.postprocessing_rotation_approach.rotate_each_eof_by_delta(orig_eofs: EOFDataForAllDOYs, delta: float) EOFDataForAllDOYs [source]¶
Use delta calculated by optimization function to rotate original EOFs by delta. First projects EOFs from DOY n-1 onto EOF space for DOY n, then rotates projected EOFs by small angle delta.
- Parameters:
orig_eofs – calculated EOFs, signs have been changed via spontaneous_sign_changes
delta – scalar by which to rotate EOFs. Calculated as the angular discontinuity between EOF1 on DOY1 and EOF1 on DOY1 after a full year of projection, divided by the length of the year.
- Returns:
new EOFdata with projected and rotated EOFs.
- mjoindices.omi.postprocessing_rotation_approach.rotate_eofs(orig_eofs: EOFDataForAllDOYs) EOFDataForAllDOYs [source]¶
Rotate EOFs at each DOY to
align with the EOFs of the previous day and
be continuous across December to January boundary.
Described more in detail in :py:func:’post_process_eofs_rotation’
- Parameters:
orig_eofs – Calculated EOFs, which already has algined signs between neighboring DOYs.
- Returns:
set of rotated EOFs.
- mjoindices.omi.postprocessing_rotation_approach.rotation_matrix(delta)[source]¶
Creates a 2d rotation matrix for corresponding delta.
- Parameters:
delta – Scalar angle, in radians, of desired rotation.
- Returns:
2x2 rotation matrix that can be used to rotate an Nx2 matrix in the x-y plane counterclockwise by delta.