# FFT spectrum

## Introduction

The `plugin-spectrum` it is a Live plugin that provides pipes functions to analyse signals in the frequency domain using FFT (*Fast Fourier Transform*).

<figure><img src="/files/3NFAjqah6hayKKQSz98P" alt=""><figcaption><p>Signal processing of plugin-spectrum from time domain to frequency domain with FFT</p></figcaption></figure>

Some of the benefits of frequency analysis are improved well safety monitoring and issue prevention:

![Benefits of analyse signal in frequency domain](/files/-MV1ajI_j1loFoOJUxBc)

Drilling systems are subject to torsional, axial, and lateral vibrations that are excited by bit-rock or by drillstring-formation interaction forces. These oscillations can be distinguished by mode shape and frequency. High-frequency torsional oscillations have natural modes reaching 400 Hz. Stick/slip oscillations are characterized by low frequencies usually below 1 Hz and affect the entire drill-string.

![Drilling modes of vibration: lateral, longitudinal and torsional](/files/-MV1amTdeRypBBPkLBkr)

The next table shows the frequency ranges of common vibration interaction forces and modes:

| Mechanism      | Mode of vibration       | Frequency range |
| -------------- | ----------------------- | --------------- |
| Stick-Slip     | Torsional               | 0-5Hz           |
| Bit Bounce     | Axial                   | 1-10Hz          |
| Bit Chatter    | Lateral                 | 50-350Hz+       |
| Bit Whirl      | Lateral/Torsional       | 5-100Hz         |
| BHA Whirl      | Lateral/Torsional       | 5-20Hz          |
| Modal Coupling | Axial/Lateral/Torsional | 0-20Hz          |

The stick-slip phenomenon is most typically related to higher compressive strength formations related to torsional vibration (0-5Hz). When drilling with too low RPM or too high WOB (weight on bit), the drill string may enter the stick-slip window:

![Drilling efficiency diagram and stick slip window](/files/-MV1arOTayS7wDsi9xWp)

## Live FFT

The `signal.FFT()` pipes function receives a `double array of timestamp series`, a `double array of signal`, the `sampling rate` of signal and a `boolean convertToDecibel` that flags whether or not to convert the output magnitude to decibel:

![Pipe function to calculate FFT](/files/-MV3ELa15kmFuNosSv5v)

The example below shows generated sine wave signals in the left charts and their FFTs to the right. The first with one harmonic, the second with three harmonics increasing amplitudes, and the third with noised sine signal.

![Generated sine harmonic signals with calculated FFT](/files/-MV1dpIDkP2gvdN-J7P1)

With a Cartesian chart, it is possible to plot the FFT signal based on the example query below. It is also possible to replace the generated signal with a real signal:

```
=> over last 10 min every sec 
=> count() as times, random() as rand over all every item 
=> times, 20*sin(2/10*pi()*times) as sin every item
=> signal.FFT(times, sin, 1,false) as fftResultData 
over last 20 min every 1 min 

=> fftResultData:json():jsonparse() as result 
=> result->magnitudes:seq as mag, result->frequencies:seq as freq 
=> @for range(freq:len()) as i, mag, freq => mag[i] as y, freq[i] as x
=> @set '#106621' as color => @set 1 as lineWidth
=> @set true as __clear
```

The next images show each example with its related FFT:

![Left: sine wave with 10 seconds period. Right output with 0.1Hz peak frequency](https://lh3.googleusercontent.com/8xwRL47XBJewDKu558fhm-ESB0aCH6LNmdz3Ec6mvgU0O85aNa2b-N4_-OUk8YuwJEJWTL8aKcyDtFqVubLERW6d0DGnyZYgxoEZ4XqVtguV8ctpkR_kkCCyEZ5F0fVIZZxST55Pl7I)

In a temporal chart with the query bellow it is possible to generate a sine signal:

```
=> over last 10 min every sec 
=> count() as times, random() as rand over all every item
=> sin(2/10*pi()*times) as sin every item
```

![Example of generated sine](/files/-MV2JA0xzzte8xCa87Pn)

In a Cartesian chart with the query bellow it is possible to generate the fft of the sine signal:

```
=> over last 10 min every sec 
=> count() as times, random() as rand over all every item
=> times, sin(2/10*pi()*times) as sin every item
=> signal.FFT(times, sin, 1,false) as fftResultData 
over last 10 min every 1 min

=> fftResultData:json():jsonparse() as result
=> result->magnitudes:seq as mag, result->frequencies:seq as freq
=> @for range(freq:len()) as i, mag, freq
=> mag[i] as y, freq[i] as x

=> @set '#106621' as __color
=> @set 1 as __lineWidth
=> @set true as __clear
```

![FFT calculated based on generated sine signal](/files/-MV2pmEVtv1uOKbpEynJ)

In a temporal chart with the query bellow it is possible to generate sine with harmonics:

```
=> over last 10 min every sec 
=> count() as times, random() as rand over all every item
=> sin(2/10*pi()*times) + 2*sin(3/10*pi()*times)  
+ 3*sin(4/10*pi()*times) as sin every item
```

![Sine signal generated with harmonics](/files/-MV2LF5p6N9ig27X7Shm)

In a Cartesian chart with the query bellow it is possible to generate the FFT of the harmonics sine signal:

```
=> over last 10 min every sec 
=> count() as times, random() as rand over all every item
=> times, sin(2/10*pi()*times) + 2*sin(3/10*pi()*times)  + 
3*sin(4/10*pi()*times) as sin every item

=> signal.FFT(times, sin, 1,false) as fftResultData over all every 10 min
=> fftResultData:json():jsonparse() as result
=> result->magnitudes:seq as mag, result->frequencies:seq as freq
=> @for range(freq:len()) as i, mag, freq
=> mag[i] as y, freq[i] as x

=> @set '#106621' as __color
=> @set 1 as __lineWidth
=> @set true as __clear
```

![FFT calculated with harmonics](/files/-MV2KogNPyS38ENu_rjb)

In a temporal chart with the query bellow it is possible to generate sine with noise:

```
=> over last 10 min every sec 
=> count() as times, random() as rand over all every item
=> 20*sin(2/10*pi()*times) +20*random() as sin every item
```

![Sine signal generated with noise](/files/-MV2Kycy4y2w7ulh6rfM)

In a Cartesian chart with the query bellow it is possible to generate the FFT of the noised sine signal:

```
=> over last 10 min every sec 
=> count() as times, random() as rand over all every item
=> times, 20*sin(2/10*pi()*times) +20*random() as sin every item


=> signal.FFT(times, sin, 1,false) as fftResultData over all every 10 min
=> fftResultData:json():jsonparse() as result
=> result->magnitudes:seq as mag, result->frequencies:seq as freq
=> @for range(freq:len()) as i, mag, freq
=> mag[i] as y, freq[i] as x

=> @set '#106621' as __color
=> @set 1 as __lineWidth
=> @set true as __clear
```

![FFT calculated based on noised sine](/files/-MV2L6QgDd59cfF7e7S5)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://drilling.intelie.com/whats-new/fft-spectrum-plugin.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
