I'm currently reading a paper (Page 23 of the PDF) about the application of the Fourier transform to standardize some climatic data to easily compare them.

I have the following text :

2.3 Standardising dates


If we subtract the phase angle of the resultant of the first frequency vectors for rainfall and temperature from all the other vectors in the set, then we have produced a rigid rotation of the vectors. This standardizes the dates for all pixels and we can transform the data back to monthly (but not calendar) values.

My main question is about the phase of the first frequency (let's assume the second frequency because the phase of the DC component is always 0). How subtracting its phase from the other "frequency vectors" is supposed to align them? And how this subtraction is related to the rotation?

My understanding is that the phase of the second frequency component is subtracted from every frequency component, in order to produce a new frequency spectrum. An inverse Fourier transform is then applied to move from this new frequency spectrum to a new vector containing rotated values.

Unfortunately, after running an experiment with the example provided by the paper, the output of the inverse Fourier transform is a set of complex numbers, instead of the set of rotated values.

import numpy as np
import cmath

north_rainfall = [18, 14, 27, 78, 92, 123, 145, 137, 120, 87, 72, 46]
south_rainfall = [137, 120, 87, 72, 46, 18, 14, 27, 78, 92, 123, 145]

north_fourier = np.fft.fft(north_rainfall)
south_fourier = np.fft.fft(south_rainfall)

# Transform the phase of the second frequency component of "north Fourier" into a complex number
magnitude = 1
phase_angle = np.angle(north_fourier[1])

divisor = cmath.rect(magnitude, phase_angle)

# Remove the computed phase in every frequency component of the "south Fourier" except the DC
new_fourier = np.hstack((south_fourier[:1], south_fourier[1:] / divisor))

# Apply the inverse Fourier transform to get the rotated values
rotated_values = np.fft.ifft(new_fourier)

print("\n Rotated values : ", rotated_values)
  • $\begingroup$ The source is highly under-specified, I've no clue what they're doing. It's an unusual but interesting idea. $\endgroup$ Jun 26, 2023 at 11:16
  • $\begingroup$ Please @OverLordGoldDragon, kindly look at the question again. I updated the source and the question to bring out my issue and my assumption more clearly. $\endgroup$ Jun 26, 2023 at 11:35

1 Answer 1


After several readings and experiments, I think that the best way to rotate data exploiting the phases is to use the DFT shifting theorem. By identifying the number of shifts required to align the second frequency components (which are the frequencies of the highest amplitudes in this specific case), we get the rotation coefficient to apply to align the set of rainfall. Find below an experiment that I did using the data provided by the paper.

import numpy as np
import cmath

north_rainfall = [137, 120, 87, 72, 46, 18, 14, 27, 78, 92, 123, 145]
south_rainfall = [18, 14, 27, 78, 92, 123, 145, 137, 120, 87, 72, 46]

north_fourier = np.fft.fft(north_rainfall)
south_fourier = np.fft.fft(south_rainfall)

# Get the phases of the fft outputs
phase1 = np.angle(north_fourier)
phase2 = np.angle(south_fourier)

# The rotation coefficient using the fact that shifting to k is equivalent to a phase shift of 2πk/N for the second frequency component
rotation_coefficient = int(round(((phase1[1] - phase2[1]) * (12 / 2)) / np.pi, 0))

rotated_south_rainfall = np.concatenate((south_rainfall[rotation_coefficient:],
                                   south_rainfall[: rotation_coefficient + 12]))
print("North Rainfall : ", north_rainfall)
print("Rotated South Rainfall : ", rotated_south_rainfall)

As you can see below, the two vectors are finally well aligned.

North Rainfall :  [137, 120, 87, 72, 46, 18, 14, 27, 78, 92, 123, 145]
Rotated South Rainfall :  [137 120  87  72  46  18  14  27  78  92 123 145]
  • 1
    $\begingroup$ You got it right, and I'll note that, without reading outside the referenced section, their approach seems like overcomplicating and unnecessary, and their descriptions incomprehensible. np.roll should suffice. $\endgroup$ Jun 28, 2023 at 18:33
  • $\begingroup$ Happy to see that even someone with a huge experience with the Fourier transform found their work hard to understand and overcomplicated. Right now, I'm looking for a better method to align the data. The current method will face issues if the highest frequencies of the signals don't occur for the same analysis frequency. In this case, it can't be possible to apply the DFT shifting on two sinusoids with different frequencies. Am I right @OverLordGoldDragon ? $\endgroup$ Jun 28, 2023 at 18:42
  • $\begingroup$ I'm not sure what you're asking, but few things. Questions should be asked in posts, unless they can be answered quickly and easily, then comments can work. Also it's fine to neutrally mention a question (post), but not great to directly ask someone to look. In this case, the answer to your comment seems to be "depends", so not quick/easy. $\endgroup$ Jun 29, 2023 at 11:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.