# RF iterative deconvolution

**URL:** <https://discourse.obspy.org/t/rf-iterative-deconvolution/1221>\
**Category:** Related: rf\
**Created:** [April 13, 2021, 2:16pm UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221 "2021-04-13T14:16:28Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thea92](https://discourse.obspy.org/user_avatar/discourse.obspy.org/thea92/32/408_2.png) [@Thea92](https://discourse.obspy.org/u/Thea92)\
**Post date:** [April 13, 2021, 2:16pm UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/1 "2021-04-13T14:16:28Z")

</div>

Hi there,

I’m using this nice rf tool with obspy. I’m trying to deconvolve the data using the iterative deconvolution. I followed the documentation:

```python
RF=rf.deconvolve.deconvolve(RF, method='iterative', gauss=0.25, itmax=1000, normalize=0, source_components='LZ', response_components=None, winsrc='P')

```

The length of the input data is 110s, but the RF result is plotted for 100s but only calculated for 50s, so until that delay time, spikes are added, but no more spikes afterwards, which is weird since I would at least expect the 660 to be visible in the data.

If I change the winsrc by myself, for example winsrc=(-5, 150-5,0) (following the code), The Data is deconvolved up to around 70s…so I wonder what is actually happening during the iterative deconvolution? Do I have to calculate twice the wished data length in order to observe the conversion I’d like to observe?

Any suggestions and help is highly appreciated! Thanks in advance,  
Thea

---

<div class="post-metadata">

**Author:** ![trichter](https://discourse.obspy.org/user_avatar/discourse.obspy.org/trichter/32/226_2.png) [@trichter](https://discourse.obspy.org/u/trichter)\
**Post date:** [April 13, 2021, 4:44pm UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/2 "2021-04-13T16:44:03Z")

</div>

Hi Thea,

on first glance this looks like a bug. Iterative deconvolution was only incorporated recently into `rf`. I will have a look in the following days.

The other methods are working for you?

---

<div class="post-metadata">

**Author:** ![trichter](https://discourse.obspy.org/user_avatar/discourse.obspy.org/trichter/32/226_2.png) [@trichter](https://discourse.obspy.org/u/trichter)\
**Post date:** [April 13, 2021, 4:59pm UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/3 "2021-04-13T16:59:28Z")

</div>

This snippet illustrates the issue with the example stream. Is it possibly inherent to the `'iterative'` method? Can you have a look, @hfmark?

```py
import matplotlib.pyplot as plt
from rf import read_rf, rfstats
stream = read_rf()
rfstats(stream)
stream.rf(deconvolve='iterative')
stream.plot_rf()
plt.show()

```

 ![test](https://discourse.obspy.org/uploads/default/original/1X/58c89f5657178ffcb56af59c8ce096cfebadd1ea.png)

---

<div class="post-metadata">

**Author:** ![hfmark](https://discourse.obspy.org/letter_avatar_proxy/v4/letter/h/85f322/32.png) [@hfmark](https://discourse.obspy.org/u/hfmark)\
**Post date:** [April 13, 2021, 6:08pm UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/4 "2021-04-13T18:08:00Z")

</div>

Yes, it’s definitely an `'iterative'` bug. Thanks for catching it! It’s coming from the parameter `maxlag` in the `deconv_iterative()` function. To be honest, I don’t remember why I had that set to `maxlag=0.5*nfft` but at the moment what that means is it’ll only try to add to the spike train for half the length of the trace, starting at the onset time. I guess one benefit of that is that in most cases, you’ll get super-clean zeros before the onset time, but if more than half a trace is before the onset time the outputs will look a bit strange.

Off the top of my head it seems like it would be fine to just set `maxlag=nfft`? For the test data it seems to work fine. Otherwise we could set `maxlag` based on trace length so the spike train is nonzero only from onset to the end.

---

<div class="post-metadata">

**Author:** ![trichter](https://discourse.obspy.org/user_avatar/discourse.obspy.org/trichter/32/226_2.png) [@trichter](https://discourse.obspy.org/u/trichter)\
**Post date:** [April 14, 2021, 7:02am UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/5 "2021-04-14T07:02:28Z")

</div>

Thanks for this hint. I added a fix in [improvements for iterative deconvolution by trichter · Pull Request #33 · trichter/rf · GitHub](https://github.com/trichter/rf/pull/33).  
Thea, you can install and test this branch with `pip install https://github.com/trichter/rf/archive/iter_patch.zip`

---

<div class="post-metadata">

**Author:** ![Thea92](https://discourse.obspy.org/user_avatar/discourse.obspy.org/thea92/32/408_2.png) [@Thea92](https://discourse.obspy.org/u/Thea92)\
**Post date:** [April 14, 2021, 8:24am UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/6 "2021-04-14T08:24:45Z")

</div>

Thank you guys so much for the fast responses and solutions!  
Its working now. Although the command RF.deconvolve.deconvolve… is not working with the new package. But it’s running perfectly with RF.rf(deconvolve=‘iterative’…). So thanks a lot! 🙂

---

<div class="post-metadata">

**Author:** ![trichter](https://discourse.obspy.org/user_avatar/discourse.obspy.org/trichter/32/226_2.png) [@trichter](https://discourse.obspy.org/u/trichter)\
**Post date:** [April 14, 2021, 9:27am UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/7 "2021-04-14T09:27:42Z")

</div>

I think you mixed the module name and your variable name. The `rf` in `rf.deconvolve.deconvolve()` is the module. If you want to use the deconvolve method just do `stream.deconvolve()'.

---

<div class="post-metadata">

**Author:** ![Thea92](https://discourse.obspy.org/user_avatar/discourse.obspy.org/thea92/32/408_2.png) [@Thea92](https://discourse.obspy.org/u/Thea92)\
**Post date:** [April 14, 2021, 9:30am UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/8 "2021-04-14T09:30:13Z")

</div>

Hups, yeah, I mixed it. Thanks

---

<div class="post-metadata">

**Author:** ![Thea92](https://discourse.obspy.org/user_avatar/discourse.obspy.org/thea92/32/408_2.png) [@Thea92](https://discourse.obspy.org/u/Thea92)\
**Post date:** [April 14, 2021, 2:10pm UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/9 "2021-04-14T14:10:20Z")

</div>

I still have one open question considering the iterative deconvolution:

1. within the ZRT system, the deconvolved R component is showing an up- or downwards trend in the very beginning…I assume this is an artefact, probably because of the changed length?
2. I observed various spikes on the Z-component at later delay times, they are very tiny compared to the main spike at 0s, but still… Maybe I misunderstood the method, but I thought this was the trick of the iterative deconvolution, that the Z or L component has one spike with an amplitude of 1 at 0s.  
I can reduce the spikes on the Z component by setting the minderr to 1, but this also reduces the peaks on the R and T component.

---

<div class="post-metadata">

**Author:** ![hfmark](https://discourse.obspy.org/letter_avatar_proxy/v4/letter/h/85f322/32.png) [@hfmark](https://discourse.obspy.org/u/hfmark)\
**Post date:** [April 14, 2021, 2:54pm UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/10 "2021-04-14T14:54:36Z")

</div>

Hi Thea,

I’m not quite sure about your first question - could you post a figure?

For the second point, in theory, yes, the RF for the source component should be a spike of amplitude 1 at 0s lag, since you’re effectively trying to deconvolve it from itself. I think the reason you still see some non-zero values at other delay times is that the spikes used to build up the RF have a nonzero width, from the Gaussian filter.

I think you already have a sense of this from setting `minderr` to 1, but that parameter is the main control on how “messy,” or detailed, you want your spiky RFs to be. For each spike added to the RF, it calculates how much the error is reduced between the input response and the predicted response, and if that error reduction is below the threshold `minderr` it stops iterating. So, if you set `minderr` to a larger value, like 1, it’ll give you an RF with the major features (hopefully) picked out, and less noise, but for small `minderr` (and the default value is pretty small, I think) it has to work a bit harder to meet the threshold. So, for the source component, that spike at 0 lag gets added first, but since it’s not a delta function it isn’t quite perfect and the algorithm will continue to try adding spikes as long as the error reduction in each iteration is large enough.

I hope that helps!

---

<div class="post-metadata">

**Author:** ![Thea92](https://discourse.obspy.org/user_avatar/discourse.obspy.org/thea92/32/408_2.png) [@Thea92](https://discourse.obspy.org/u/Thea92)\
**Post date:** [April 14, 2021, 4:32pm UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/11 "2021-04-14T16:32:58Z")

</div>

Hi Hannah,

thank you for your help and detailed answer, I do have a better understanding of the mechanisms behind the function now and especially of this minderr.

So, I’m attaching an example for the upward trend of the R-RF. It’s like the very first second, but I’d like to avoid any problems that are affecting the resulting RFs.

Many thanks in advance!

 ![R_comp](https://discourse.obspy.org/uploads/default/original/1X/2aeb2d23bf9f9eef323147adc7051699d9f3b706.png)

---

<div class="post-metadata">

**Author:** ![hfmark](https://discourse.obspy.org/letter_avatar_proxy/v4/letter/h/85f322/32.png) [@hfmark](https://discourse.obspy.org/u/hfmark)\
**Post date:** [April 14, 2021, 6:08pm UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/12 "2021-04-14T18:08:44Z")

</div>

Thanks, I see what you mean. Yes, I think you’re right that it’s an artifact. In the patch, @trichter set `maxlag` so spikes are added to the RF from the onset time to the end of the trace. My guess is when the trace is shifted to put 0s lag _at_ 0, a little bit from the end is wrapping around. Probably goes back, again, to the Gaussian filter and the width of the spikes - it looks like you’ve got ~half a spike or less aliased into the beginning there.

---

<div class="post-metadata">

**Author:** ![trichter](https://discourse.obspy.org/user_avatar/discourse.obspy.org/trichter/32/226_2.png) [@trichter](https://discourse.obspy.org/u/trichter)\
**Post date:** [April 14, 2021, 7:19pm UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/13 "2021-04-14T19:19:58Z")

</div>

Hannah put it in a nutshell. The time shift wraps the end of the RF to the beginning. What you see is the half of a Gaussian, the other half is at the end. These points can be simply set to 0. Or even better, we can adapt maxlag once more.

I think the Z or L component should indeed be a spike, but only if you choose the whole trace as source. You also have to make sure to not use any taper, which is not the default. If you use the default, you will have some energy left at the end, where additional spikes will be added.

Should the default time window be changed to not use any tapering for iterative deconvolution?

I always tend to not use the whole Z/L trace as source, but I remember that at least for waterlevel deconvolution better results were obtained when the whole trace was used. (Therefore the different default windows.)

---

<div class="post-metadata">

**Author:** ![hfmark](https://discourse.obspy.org/letter_avatar_proxy/v4/letter/h/85f322/32.png) [@hfmark](https://discourse.obspy.org/u/hfmark)\
**Post date:** [April 15, 2021, 2:09am UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/14 "2021-04-15T02:09:01Z")

</div>

Oh, right, I forgot about the taper. Turning that off for the iterative deconvolution might be a good idea - it’s certainly not a necessary step.

Anyway, the aliasing can definitely be fixed with maxlag - if we take a few extra samples off to account for the width of the gaussian filter it should be ok.

---

<div class="post-metadata">

**Author:** ![trichter](https://discourse.obspy.org/user_avatar/discourse.obspy.org/trichter/32/226_2.png) [@trichter](https://discourse.obspy.org/u/trichter)\
**Post date:** [April 15, 2021, 8:33am UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/15 "2021-04-15T08:33:01Z")

</div>

I now refactored the whole beast again. See the changelog. The traces are now padded with zeros to completely get rid of any wrap-around effects. Therefore I see no need to mute the beginning of the trace anymore and turned it off. These wiggles before the onset are a feature 😉 . For convenience I added a kwarg `mute_shift` to get the muting back.

---

<div class="post-metadata">

**Author:** ![hfmark](https://discourse.obspy.org/letter_avatar_proxy/v4/letter/h/85f322/32.png) [@hfmark](https://discourse.obspy.org/u/hfmark)\
**Post date:** [April 15, 2021, 2:13pm UTC](https://discourse.obspy.org/t/rf-iterative-deconvolution/1221/16 "2021-04-15T14:13:07Z")

</div>

Looks good to me! Thanks for working that out.
