# Spectral Coherence in Julia

**URL:** https://discourse.julialang.org/t/spectral-coherence-in-julia/106144
**Category:** Signal and Image Processing
**Tags:** dsp, signal-processing
**Created:** [November 13, 2023, 9:49am UTC](https://discourse.julialang.org/t/spectral-coherence-in-julia/106144 "2023-11-13T09:49:13Z")
**Posts on this page:** 8
**Page:** 2

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [November 14, 2023, 6:15am UTC](https://discourse.julialang.org/t/spectral-coherence-in-julia/106144/21 "2023-11-14T06:15:32Z")

</div>

You are essentially trying to perform clustering of the signals, group similar signals together. Since you have a relatively small number of signals, you can use a wide range of tools, including computing all pairwise distances between signals etc.

Without having much insight into the actual properties of the signals, it’s hard to judge whether or not DTW is a suitable metric in this case, but you could attempt to compute the DTW cost matrix using something like (naive)

```julia
d = DTW(radius=radius, dist=SqEuclidean())
D = [d(a,b) for a in signals, b in signals]

```

For a slightly more efficient version, see [`SpectralDistances.distmat`](https://baggepinnen.github.io/SpectralDistances.jl/latest/distances/#SpectralDistances.distmat-Tuple%7BAny,%20AbstractVector%7D) (may not be needed in your case).

If you want to further process the distance matrix `D` into a clustering, you could pass it into any of the methods from Clustering.jl that accept a distance matrix, such as

```julia
using Clustering
cr = hclust(Symmetric(sqrt.(D)))
assignments = cutree(cr,k=3) # k is desired number of clusters

```

You could also try the built-in clustering `dbaclust` in DynamicAxisWarping

> **[GitHub - baggepinnen/DynamicAxisWarping.jl: Dynamic Time Warping (DTW) and...](https://github.com/baggepinnen/DynamicAxisWarping.jl#clustering-and-barycenter-averaging)**
>
> Dynamic Time Warping (DTW) and related algorithms in Julia, at Julia speeds - GitHub - baggepinnen/DynamicAxisWarping.jl: Dynamic Time Warping (DTW) and related algorithms in Julia, at Julia speeds

I do not think that MatrixProfile is a suitable tool in this case, at least not the standard techniques associated with the matrix profile. You are certainly looking for something more towards computing distances/similarity and clustering.

---

<div class="post-metadata">

### Author: ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)
#### Post date: [November 14, 2023, 6:40pm UTC](https://discourse.julialang.org/t/spectral-coherence-in-julia/106144/22 "2023-11-14T18:40:48Z")

</div>

@baggepinnen

Thanks a lot for the recomendation. I will check all of this out and give it a try.

Just in case is matters. My signals happened randomly in time (they are little earthquakes). There should be between 2 and 5 sources located in different locations, and the signals arrives to my receivers located a few meters away from the sources. In theory each source should produce exactly the same signal, that travels a constant path to the receivers, hence the waveform should be exactly the same (except for randomly occurring noise). This is not entirely true as the source-time function differs slightly for every earthquake, but our hope is to be able to cluster the signals and say, “well all this events look similar so they should be from source A”.

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [November 15, 2023, 10:22am UTC](https://discourse.julialang.org/t/spectral-coherence-in-julia/106144/23 "2023-11-15T10:22:53Z")

</div>

> [@marianoarnaiz](#):
>
> hence the waveform should be exactly the same (except for randomly occurring noise)

I’m by no means a seismologist, but I’m not sure if this is correct. Each signal will be colored by the transfer function from the source to the receiver, and unless all signals propagate through exactly the same path, they will differ even without the presence of any random noise.

Since you were originally considering coherence-based measures, I assume that the propagation path is reasonably linear (an LTI system). If that’s the case, you could potentially try to fit pairwise linear models between each pair of signals, with one signal as input and one as output. If you account for the delay between the signals, there should be a linear system that relates each pair of signals that originates from the same event. In spirit, this would be similar to a coherence analysis, but could potentially perform better in this low-data regime where you only have a single transient event to compare. The metric you would compare would then be, e.g., the prediction error that the estimated model makes on the data (normalized to account for length of data record etc.)

---

<div class="post-metadata">

### Author: ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)
#### Post date: [November 22, 2023, 8:22am UTC](https://discourse.julialang.org/t/spectral-coherence-in-julia/106144/24 "2023-11-22T08:22:36Z")

</div>

Hello again @baggepinnen.

Ok this is quite deeper that I thought hehehe.

Yes, you are right, the path is rather linear and uncomplicated (no weird stuff that would make scattered signals), the source time function is similar, and signals propagate through a path that is very similar.

Here a quick example of some signals selected by coherence. Some signals are very similar to each other, but I “see” at least two families here.

 ![19th oct_templatefailmy_waves](https://global.discourse-cdn.com/julialang/original/3X/1/d/1d3697e9a678b6d6e55d74351f003f58cedade6f.png)

I thought maybe something out of DynamicAxisWarping or SpectralDistances could give me a measure of how similar they are, and help me differentiate them. I am not really familiar with pairwise models, can you suggest any tool in julia I can use to make some test?

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [November 22, 2023, 9:08am UTC](https://discourse.julialang.org/t/spectral-coherence-in-julia/106144/25 "2023-11-22T09:08:09Z")

</div>

My suggestion is still to do something like this

> [@Spectral Coherence in Julia](https://discourse.julialang.org/t/spectral-coherence-in-julia/106144/21):
>
> You are essentially trying to perform clustering of the signals, group similar signals together. Since you have a relatively small number of signals, you can use a wide range of tools, including computing all pairwise distances between signals etc. Without having much insight into the actual properties of the signals, it’s hard to judge whether or not DTW is a suitable metric in this case, but you could attempt to compute the DTW cost matrix using something like (naive) d = DTW(radius=radius, …

---

<div class="post-metadata">

### Author: ![Jake](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jake/32/46007_2.png) [@Jake](https://discourse.julialang.org/u/Jake)
#### Post date: [November 22, 2023, 5:10pm UTC](https://discourse.julialang.org/t/spectral-coherence-in-julia/106144/26 "2023-11-22T17:10:34Z")

</div>

A good explanation of coherence and how to calculate it is given about 2/3 of the way down this [page](https://sandialabs.github.io/sdynpy/modal_tutorials/Modal_05_Experimental_Modal_Analysis/Modal_05a_Computing_FRF_from_Time_Data.html). I assume this is what DSP.jl does.

It looks like the [cross-correlation](https://en.wikipedia.org/wiki/Cross-correlation) function should also be considered for what you are doing. It looks like [DSP.jl](https://docs.juliadsp.org/stable/convolutions/) is your friend here, though I have not used this function.

A friend did research on [syncro-squeezing](https://github.com/jrvmalik/time-frequency-analysis/blob/master/SST_J.m) for the medical field. This was described as a time-frequency approach. I am not at all sure if it would be helpful, but may be worth taking a look at.

---

<div class="post-metadata">

### Author: ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)
#### Post date: [November 23, 2023, 9:13am UTC](https://discourse.julialang.org/t/spectral-coherence-in-julia/106144/27 "2023-11-23T09:13:56Z")

</div>

@baggepinnen  
Dear Frederik thanks a lot for all your input 🙂  
I will review all of this information and I am sure I will come up with some nice results.  
Thanks again and cheers!

---

<div class="post-metadata">

### Author: ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)
#### Post date: [November 23, 2023, 9:14am UTC](https://discourse.julialang.org/t/spectral-coherence-in-julia/106144/28 "2023-11-23T09:14:14Z")

</div>

Hi Jake  
This is nice input, thanks a lot 🙂

[Previous page](https://discourse.julialang.org/t/spectral-coherence-in-julia/106144.md?page=1)
