Skip to content

Conversation

krisvanneste
Copy link
Collaborator

Claudio,

Here is my pull request to fix the interpolation issue when residual correction is applied. As you suggested, I created the branch from the fix_source_residuals branch, but now it says that it can't automatically merge... Let me know if I need to do it differently.

I ran the fix with my test case and it appears to work, but you should be aware that in the spectrum returned by the station_correction function, the linear-spaced and log-spaced versions may not have the same length and frequency range. The linear one is truncated to the common frequency range with the station residual, while the logarithmic one keeps the original length, with values outside the common frequency range set to NaN. I'm not sure if this could cause any problems further in the code, but I did not notice anything.

@krisvanneste
Copy link
Collaborator Author

Note that I won't be in the office tomorrow. We can continue on Thursday or Friday.

@claudiodsf claudiodsf force-pushed the fix_ssp_correction branch from 146d642 to 8d6f0e6 Compare May 7, 2025 08:45
@claudiodsf
Copy link
Member

Dear Kris, thanks for the PR.

There were indeed many conflicts (my suggestion to start from the previous branch was bad).
To fix that, I started a new branch from current upstream/main and "cherry-picked" the three commits, then renamed the branch to fix_ssp_correction and force-pushed.
Please force-pull on your side.

I can now check the PR contents... 😉

@claudiodsf
Copy link
Member

I added a couple of commits to move common interpolation code to a function and to remove the unnecessary return spec_st (spec_st is altered in place)

@krisvanneste
Copy link
Collaborator Author

I force-pulled the branch.

@claudiodsf
Copy link
Member

There is still a problem in my tests when computing spectral weights from S/N: signal spectrum and noise spectrum sometimes do not have the same length.

Today's is holiday in France and tomorrow I'll take the day off.
I'll be back working on this PR on Monday 😉

@krisvanneste
Copy link
Collaborator Author

On my side it still works.
Are the spectral weights computed before or after the residual correction?

@claudiodsf
Copy link
Member

I think the problem is here:

specnoise is computed independently of spec, based on the assumption that both are computed from a time window that has the same length, and therefore they must have the same frequencies.

This assumption is no longer valid if the frequency range spec is modified during the correction.

A possible solution would be to pass the frequency range as an extra optional argument when calling _build_spectrum() for spec_noise, and interpolate spec_noise to this new frequency range.

So something like:

specnoise = _build_spectrum(config, trace_noise, interpolate_freqs=spec.freqs)

@krisvanneste
Copy link
Collaborator Author

OK, I will have a look as well. Enjoy your long weekend!

@krisvanneste
Copy link
Collaborator Author

I understand the problem now. I think it would be better not to change the frequency range of the signal spectrum, and set NaN values outside the frequency range of the residual for the linear-spaced spectrum as well, thus also keeping linear-spaced and log-spaced versions in sync. We then need to check if the NaN values do not give any problem when calculating spectral SNR. I will improve the ssp_correction.station_correction function.

@krisvanneste
Copy link
Collaborator Author

Claudio, I changed the station correction function in a way that the original frequency range is not modified. Can you check if this solves your problem with noise weighting?

@claudiodsf
Copy link
Member

Hi Kris, thanks for this additional work.

I had to make some further modifications:

  • replace NaNs in the weight spectrum with small values: otherwise the logspaced spectrum becomes all NaNs
  • replace np.min() and np.max() with np.nanmin() and np.nanmax() in stacked spectral plotting

Now it seems to work, but I need to test it more extensively.

Could you also check on your side?

@krisvanneste
Copy link
Collaborator Author

OK

@claudiodsf
Copy link
Member

One more commit related to NaN data 😉

@krisvanneste
Copy link
Collaborator Author

My results look identical.
Note that you can't use scipy.interpolate.interp1d with arrays containing NaN values. I had to ignore these to interpolate the log-spaced spectrum in station_correction.

@claudiodsf
Copy link
Member

My results look identical.

Great!

Note that you can't use scipy.interpolate.interp1d with arrays containing NaN values. I had to ignore these to interpolate the log-spaced spectrum in station_correction.

Ok, so maybe I can use a similar approach for weight computation, instead of replacing NaN with 1e-9...

@krisvanneste
Copy link
Collaborator Author

Ok, so maybe I can use a similar approach for weight computation, instead of replacing NaN with 1e-9...

I did it like this:

nan_idxs = np.isnan(spec_corr.data_mag)
f = interp1d(spec_corr.freq[~nan_idxs], spec_corr.data_mag[~nan_idxs],
             bounds_error=False)
spec_corr.data_mag_logspaced = f(spec_corr.freq_logspaced)

This is possible because we know the NaN values only occur at the start and/or end. The interpolated spectrum will also be NaN where the original one is NaN, because we don't allow extrapolation.

krisvanneste and others added 4 commits May 16, 2025 16:25
…quency range before correcting in station_correction function.

Note that the logspaced version of the corrected spectrum is not truncated, but filled with NaN values outside the common frequency range.
…ight before fitting in _spec_inversion function.
@claudiodsf claudiodsf force-pushed the fix_ssp_correction branch from c7cdfeb to e818baa Compare May 19, 2025 12:48
@claudiodsf
Copy link
Member

claudiodsf commented May 19, 2025

Hi Kris,

I just force-pushed to this branch a commit that moves all the interpolation into the Spectrum class, so that everything that depends on interp1d is in there.

I still have to rework the weighting part (where I replaced NaN with small values), but I would like you to test this implementation, whenever you have time.

In particular, I reimplemented your search and removal of NaN values before interpolation, which is now made by making sure that only NaN values at the edges are removed. However, I found that in my tests this removal is not essential. You can test with or without the removal by setting nan_idxs = [] at line 434 in spectrum.py.

Oh, and if you have better names for the new methods in the Spectrum class, don't hesitate to propose!

Looking forward to your feedback 😉

P.S. You must force-pull since I rebased this PR over a few additional commits added to main (which are unrelated)

@krisvanneste
Copy link
Collaborator Author

Claudio,

I ran my test case again after force-pulling the branch. The results (in terms of source parameters) are practically the same. However, there again appear some edge effects that were mostly gone in the previous version.

Previous run:
17540 ssp 00

New run:
17540 ssp 00

I also noticed that the frequency ranges of the corrected spectra reported in the log file are not the same:

Previous run:

2025-05-12 14:19:03,360 ssp_correction       INFO     BE.BEBN..HHH: corrected, frequency range is: 4.00 38.29 Hz
2025-05-12 14:19:03,363 ssp_correction       INFO     BE.MRG..EHH: corrected, frequency range is: 0.59 44.94 Hz
2025-05-12 14:19:03,366 ssp_correction       INFO     BE.MOL2..HHH: corrected, frequency range is: 0.60 74.33 Hz
2025-05-12 14:19:03,369 ssp_correction       INFO     BE.SKQ..EHH: corrected, frequency range is: 2.13 39.06 Hz
2025-05-12 14:19:03,371 ssp_correction       INFO     BE.MOL3..HHH: corrected, frequency range is: 0.80 47.75 Hz
2025-05-12 14:19:03,374 ssp_correction       INFO     BE.TNL..EHH: corrected, frequency range is: 0.60 44.92 Hz
2025-05-12 14:19:03,377 ssp_correction       INFO     BE.HOU..HHH: corrected, frequency range is: 1.63 22.63 Hz
2025-05-12 14:19:03,380 ssp_correction       INFO     BE.MOLS..HHH: corrected, frequency range is: 0.60 39.92 Hz
2025-05-12 14:19:03,383 ssp_correction       INFO     BE.MEMS..EHH: corrected, frequency range is: 0.55 44.92 Hz
2025-05-12 14:19:03,386 ssp_correction       INFO     BE.MOL4..HHH: corrected, frequency range is: 0.80 57.34 Hz
2025-05-12 14:19:03,388 ssp_correction       INFO     BE.DOU..HHH: corrected, frequency range is: 1.30 30.31 Hz
2025-05-12 14:19:03,392 ssp_correction       INFO     BE.RCHB..HHH: corrected, frequency range is: 0.51 40.00 Hz
2025-05-12 14:19:03,396 ssp_correction       INFO     BE.MOL5..HHH: corrected, frequency range is: 0.80 56.74 Hz
2025-05-12 14:19:03,398 ssp_correction       INFO     BE.MOLT..HHH: corrected, frequency range is: 0.80 44.91 Hz
2025-05-12 14:19:03,402 ssp_correction       INFO     BE.OPTB..EHH: corrected, frequency range is: 1.40 23.15 Hz
2025-05-12 14:19:03,404 ssp_correction       INFO     BE.UCCB..HHH: corrected, frequency range is: 0.49 40.05 Hz
2025-05-12 14:19:03,407 ssp_correction       INFO     BE.MOL1..HHH: corrected, frequency range is: 0.80 49.35 Hz

New run:

2025-05-21 16:05:12,801 ssp_correction       INFO     BE.MOLS..HHH: corrected, frequency range is: 0.60 39.92 Hz
2025-05-21 16:05:12,803 ssp_correction       INFO     BE.HOU..HHH: corrected, frequency range is: 1.63 22.63 Hz
2025-05-21 16:05:12,806 ssp_correction       INFO     BE.MEMS..EHH: corrected, frequency range is: 0.55 44.92 Hz
2025-05-21 16:05:12,808 ssp_correction       INFO     BE.BEBN..HHH: corrected, frequency range is: 4.00 38.29 Hz
2025-05-21 16:05:12,810 ssp_correction       INFO     BE.MOL3..HHH: corrected, frequency range is: 0.80 47.75 Hz
2025-05-21 16:05:12,813 ssp_correction       INFO     BE.MOL1..HHH: corrected, frequency range is: 0.80 49.35 Hz
2025-05-21 16:05:12,816 ssp_correction       INFO     BE.MOL2..HHH: corrected, frequency range is: 0.60 74.33 Hz
2025-05-21 16:05:12,818 ssp_correction       INFO     BE.MOLT..HHH: corrected, frequency range is: 0.80 44.91 Hz
2025-05-21 16:05:12,821 ssp_correction       INFO     BE.UCCB..HHH: corrected, frequency range is: 0.49 40.05 Hz
2025-05-21 16:05:12,823 ssp_correction       INFO     BE.TNL..EHH: corrected, frequency range is: 0.60 44.92 Hz
2025-05-21 16:05:12,825 ssp_correction       INFO     BE.MRG..EHH: corrected, frequency range is: 0.59 44.94 Hz
2025-05-21 16:05:12,828 ssp_correction       INFO     BE.SKQ..EHH: corrected, frequency range is: 2.13 39.06 Hz
2025-05-21 16:05:12,830 ssp_correction       INFO     BE.MOL4..HHH: corrected, frequency range is: 0.80 57.34 Hz
2025-05-21 16:05:12,833 ssp_correction       INFO     BE.MOL5..HHH: corrected, frequency range is: 0.80 56.74 Hz
2025-05-21 16:05:12,836 ssp_correction       INFO     BE.DOU..HHH: corrected, frequency range is: 1.30 30.31 Hz
2025-05-21 16:05:12,839 ssp_correction       INFO     BE.OPTB..EHH: corrected, frequency range is: 1.40 23.15 Hz
2025-05-21 16:05:12,841 ssp_correction       INFO     BE.RCHB..HHH: corrected, frequency range is: 0.51 40.00 Hz

Any idea what could be causing this?

@claudiodsf
Copy link
Member

Thanks, Kris for the test.

The frequency ranges are actually the same, when you sort the two files 😉

I need to think on why there is again this edge case on BE.MOLT...

@krisvanneste
Copy link
Collaborator Author

The frequency ranges are actually the same, when you sort the two files 😉

Oops, I didn't see that...

@krisvanneste
Copy link
Collaborator Author

I need to think on why there is again this edge case on BE.MOLT...

Note that it's not just BE.MOLT. Also BE.MOL1, and a number of other stations (I did not include all the plots).

@claudiodsf
Copy link
Member

Note that it's not just BE.MOLT. Also BE.MOL1, and a number of other stations (I did not include all the plots).

Probably the best would be if you can send me a working example

@krisvanneste
Copy link
Collaborator Author

Claudio,

Sorry, I have been very busy the past few weeks.

I had another look at the issue, and I think the edge effects are still due to extrapolation.
If I modify ssp_plot_spectra.py to plot the linear spectra instead of the log-spaced ones, the problem is much less.
Next, I could verify that the problem occurs in the make_logspaced_from_linear method of the Spectrum class, when there are no NaN values at the start or end. In this case, it is still possible that the outermost logspaced frequencies are (slightly) outside the linear frequency range, in which case extrapolation occurs. However, when I try set these values to NaN after the interpolation, an error occurs elsewhere in the code. So, this should only be done in this specific case. I temporarily solved it by adding an 'extrapolate' argument with default value True, which overrides the value based on nan_idxs.size, and calling make_logspaced_from_linear with extrapolate=False from the station_correction function. Then the edge effects largely disappear.

We can discuss next week if this solution is OK for you or if we can further improve it.

@claudiodsf
Copy link
Member

I suppose I need to force-pull as well?

Yes! (I just force-pushed again, but just to fix a typo in a commit message 😉 )

@krisvanneste
Copy link
Collaborator Author

OK, I will update and test.

@krisvanneste
Copy link
Collaborator Author

I force-pulled and ran again.
Everything seems to work, but the results are not exactly the same. Do you know why this could be?

@claudiodsf
Copy link
Member

That's surprising! Let's continue tomorrow, if that's ok for you

@krisvanneste
Copy link
Collaborator Author

OK!

@krisvanneste
Copy link
Collaborator Author

Here are the different outputs:

Before force-push:

   BE.BEBN..HHH broadb	  Mw  1.967   fc 14.387   t_star  0.044   Qo   395.3   Mo 1.124e+12   ssd 1.994e+00   ra   62.711   hyp_dist  61.563   az 139.384   Er 6.302e+06 
            --- errmin	  Mw  0.013   fc  3.693   t_star  0.005   Qo    40.9   Mo 5.104e+10   ssd 1.212e+00   ra   12.809   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.013   fc  3.693   t_star  0.005   Qo    51.6   Mo 5.347e+10   ssd 2.152e+00   ra   21.657   hyp_dist     nan   az     nan   Er       nan 
    BE.CLA..HHH broadb	  Mw  1.972   fc  6.342   t_star  0.023   Qo  1128.9   Mo 1.141e+12   ssd 1.734e-01   ra  142.260   hyp_dist  89.884   az 171.324   Er 5.064e+05 
            --- errmin	  Mw  0.017   fc  0.749   t_star  0.003   Qo   132.2   Mo 6.601e+10   ssd 6.133e-02   ra   15.019   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.017   fc  0.749   t_star  0.003   Qo   172.6   Mo 7.007e+10   ssd 8.383e-02   ra   19.039   hyp_dist     nan   az     nan   Er       nan 
    BE.DOU..HHH broadb	  Mw  2.070   fc 15.030   t_star  0.045   Qo   851.2   Mo 1.602e+12   ssd 3.239e+00   ra   60.028   hyp_dist 130.151   az 196.551   Er 6.261e+06 
            --- errmin	  Mw  0.022   fc  9.145   t_star  0.013   Qo   189.4   Mo 1.151e+11   ssd 3.059e+00   ra   22.709   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.022   fc  9.145   t_star  0.013   Qo   341.1   Mo 1.240e+11   ssd 1.129e+01   ra   93.297   hyp_dist     nan   az     nan   Er       nan 
   BE.DSLS..HHH broadb	  Mw  2.404   fc 13.965   t_star  0.024   Qo    97.9  *Mo 5.087e+12   ssd 8.254e+00   ra   64.606   hyp_dist   7.062   az 297.213   Er 2.524e+08 
            --- errmin	  Mw  0.030   fc 11.111   t_star  0.015   Qo    38.4  *Mo 5.080e+11   ssd 8.190e+00   ra   28.627   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.030   fc 11.111   t_star  0.015   Qo   178.1  *Mo 5.644e+11   ssd 4.484e+01   ra  251.580   hyp_dist     nan   az     nan   Er       nan 
    BE.GES..HHH broadb	  Mw  2.110   fc  5.231   t_star  0.013   Qo  1984.8   Mo 1.842e+12   ssd 1.570e-01   ra  172.484   hyp_dist  92.755   az 181.105   Er 7.068e+05 
            --- errmin	  Mw  0.016   fc  1.141   t_star  0.010   Qo   861.6   Mo 9.680e+10   ssd 8.594e-02   ra   30.895   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.016   fc  1.141   t_star  0.010   Qo  6537.7   Mo 1.022e+11   ssd 1.426e-01   ra   48.141   hyp_dist     nan   az     nan   Er       nan 
    BE.HOU..HHH broadb	  Mw  2.174   fc  8.412   t_star  0.048   Qo   695.6   Mo 2.294e+12   ssd 8.136e-01   ra  107.250   hyp_dist 114.983   az 146.383   Er 4.885e+07 
            --- errmin	  Mw  0.012   fc  1.747   t_star  0.007   Qo    84.0   Mo 9.195e+10   ssd 4.251e-01   ra   18.441   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.012   fc  1.747   t_star  0.007   Qo   110.7   Mo 9.579e+10   ssd 6.791e-01   ra   28.106   hyp_dist     nan   az     nan   Er       nan 
    BE.KLB..HHH broadb	  Mw  2.044   fc 14.015   t_star  0.053   Qo   777.4   Mo 1.465e+12   ssd 2.403e+00   ra   64.372   hyp_dist 142.930   az 150.044   Er 9.089e+06 
            --- errmin	  Mw  0.040   fc 12.635   t_star  0.022   Qo   229.5   Mo 1.908e+11   ssd 2.401e+00   ra   30.518   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.040   fc 12.635   t_star  0.022   Qo   560.2   Mo 2.194e+11   ssd 1.659e+01   ra  588.969   hyp_dist     nan   az     nan   Er       nan 
   BE.MEMS..EHH broadb	  Mw  2.132   fc  7.103   t_star  0.038   Qo   713.1   Mo 1.989e+12   ssd 4.246e-01   ra  127.019   hyp_dist  92.703   az 136.614   Er 3.129e+05 
            --- errmin	  Mw  0.011   fc  0.900   t_star  0.003   Qo    59.5   Mo 7.681e+10   ssd 1.527e-01   ra   14.282   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.011   fc  0.900   t_star  0.003   Qo    71.4   Mo 7.990e+10   ssd 2.071e-01   ra   18.425   hyp_dist     nan   az     nan   Er       nan 
   BE.MOL1..HHH broadb	  Mw  2.151   fc 16.705   t_star  0.036   Qo    44.1   Mo 2.123e+12   ssd 5.895e+00   ra   54.009   hyp_dist   6.170   az 257.490   Er 3.840e+07 
            --- errmin	  Mw  0.014   fc  5.657   t_star  0.005   Qo     5.7   Mo 1.018e+11   ssd 4.272e+00   ra   13.664   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.014   fc  5.657   t_star  0.005   Qo     7.7   Mo 1.069e+11   ssd 8.959e+00   ra   27.659   hyp_dist     nan   az     nan   Er       nan 
   BE.MOL2..HHH broadb	  Mw  2.404   fc 14.830   t_star  0.034   Qo    45.1  *Mo 5.087e+12   ssd 9.884e+00   ra   60.838   hyp_dist   6.071   az 257.621   Er 1.278e+08 
            --- errmin	  Mw  0.013   fc  2.463   t_star  0.002   Qo     2.7  *Mo 2.300e+11   ssd 4.411e+00   ra    8.664   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.013   fc  2.463   t_star  0.002   Qo     3.1  *Mo 2.409e+11   ssd 6.530e+00   ra   12.115   hyp_dist     nan   az     nan   Er       nan 
   BE.MOL3..HHH broadb	  Mw  2.224   fc 19.642   t_star  0.042   Qo    36.1   Mo 2.726e+12   ssd 1.231e+01   ra   45.931   hyp_dist   6.069   az 258.704   Er 1.909e+08 
            --- errmin	  Mw  0.009   fc  5.877   t_star  0.004   Qo     3.4   Mo 8.769e+10   ssd 8.208e+00   ra   10.577   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.009   fc  5.877   t_star  0.004   Qo     4.1   Mo 9.061e+10   ssd 1.558e+01   ra   19.608   hyp_dist     nan   az     nan   Er       nan 
   BE.MOL4..HHH broadb	  Mw  2.219   fc 17.119   t_star  0.041   Qo    37.7   Mo 2.686e+12   ssd 8.027e+00   ra   52.703   hyp_dist   6.070   az 259.478   Er 8.759e+07 
            --- errmin	  Mw  0.010   fc  4.005   t_star  0.004   Qo     3.1   Mo 8.799e+10   ssd 4.537e+00   ra    9.993   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.010   fc  4.005   t_star  0.004   Qo     3.6   Mo 9.097e+10   ssd 7.567e+00   ra   16.098   hyp_dist     nan   az     nan   Er       nan 
   BE.MOL5..HHH broadb	  Mw  2.176   fc 18.587   t_star  0.039   Qo    38.8   Mo 2.312e+12   ssd 8.846e+00   ra   48.539   hyp_dist   6.069   az 261.461   Er 1.130e+08 
            --- errmin	  Mw  0.009   fc  4.093   t_star  0.003   Qo     2.8   Mo 6.972e+10   ssd 4.778e+00   ra    8.760   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.009   fc  4.093   t_star  0.003   Qo     3.3   Mo 7.188e+10   ssd 7.724e+00   ra   13.707   hyp_dist     nan   az     nan   Er       nan 
   BE.MOLA..HNH    acc	  Mw  2.404   fc 25.797   t_star  0.044   Qo    36.0  *Mo 5.087e+12  *ssd 5.203e+01   ra   34.973   hyp_dist   6.282   az 261.461  *Er 1.026e+09 
            --- errmin	  Mw  0.020   fc 18.422   t_star  0.008   Qo     5.5  *Mo 3.453e+11  *ssd 5.090e+01   ra   14.570   hyp_dist     nan   az     nan  *Er       nan 
            --- errmax	  Mw  0.020   fc 18.422   t_star  0.008   Qo     7.9  *Mo 3.704e+11  *ssd 2.291e+02   ra   87.355   hyp_dist     nan   az     nan  *Er       nan 
   BE.MOLB..HNH    acc	  Mw  2.222  *fc 35.803   t_star  0.046   Qo    32.8   Mo 2.713e+12  *ssd 7.416e+01   ra   25.199   hyp_dist   6.069   az 261.461  *Er 6.256e+08 
            --- errmin	  Mw  0.019  *fc 31.197   t_star  0.008   Qo     4.7   Mo 1.743e+11  *ssd 7.402e+01   ra   11.733   hyp_dist     nan   az     nan  *Er       nan 
            --- errmax	  Mw  0.019  *fc 31.197   t_star  0.008   Qo     6.5   Mo 1.863e+11  *ssd 4.453e+02   ra  170.677   hyp_dist     nan   az     nan  *Er       nan 
   BE.MOLK..HHH broadb	  Mw  2.404   fc 10.405   t_star  0.015   Qo   141.9  *Mo 5.087e+12   ssd 3.415e+00   ra   86.705   hyp_dist   6.121   az 266.667   Er 5.818e+07 
            --- errmin	  Mw  0.020   fc  3.061   t_star  0.006   Qo    41.0  *Mo 3.371e+11   ssd 2.293e+00   ra   19.708   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.020   fc  3.061   t_star  0.006   Qo    97.2  *Mo 3.611e+11   ssd 4.512e+00   ra   36.136   hyp_dist     nan   az     nan   Er       nan 
   BE.MOLS..HHH broadb	  Mw  2.269   fc 12.895   t_star  0.044   Qo    51.8   Mo 3.188e+12   ssd 4.073e+00   ra   69.964   hyp_dist   6.311   az 259.063  *Er 1.699e+09 
            --- errmin	  Mw  0.006   fc  1.989   t_star  0.003   Qo     3.6   Mo 6.272e+10   ssd 1.658e+00   ra    9.350   hyp_dist     nan   az     nan  *Er       nan 
            --- errmax	  Mw  0.006   fc  1.989   t_star  0.003   Qo     4.1   Mo 6.398e+10   ssd 2.316e+00   ra   12.760   hyp_dist     nan   az     nan  *Er       nan 
   BE.MOLT..HHH broadb	  Mw  2.227   fc 25.141   t_star  0.040   Qo    47.3   Mo 2.760e+12  *ssd 2.613e+01   ra   35.885   hyp_dist   6.070   az 259.735   Er 1.091e+08 
            --- errmin	  Mw  0.017   fc 16.637   t_star  0.009   Qo     8.3   Mo 1.607e+11  *ssd 2.518e+01   ra   14.290   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.017   fc 16.637   t_star  0.009   Qo    12.7   Mo 1.707e+11  *ssd 1.012e+02   ra   70.199   hyp_dist     nan   az     nan   Er       nan 
   BE.MRCA..HNH    acc	  Mw  2.282   fc  5.961   t_star  0.010  *Qo  2817.3   Mo 3.333e+12   ssd 4.205e-01   ra  151.352   hyp_dist 103.506   az 207.298   Er 3.676e+06 
            --- errmin	  Mw  0.013   fc  0.533   t_star  0.002  *Qo   497.0   Mo 1.511e+11   ssd 1.174e-01   ra   12.417   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.013   fc  0.533   t_star  0.002  *Qo   767.9   Mo 1.583e+11   ssd 1.490e-01   ra   14.854   hyp_dist     nan   az     nan   Er       nan 
    BE.MRD..HHH broadb	  Mw  2.087   fc  2.965   t_star  0.010  *Qo  3061.0   Mo 1.701e+12   ssd 2.640e-02  *ra  304.324   hyp_dist 104.722   az 193.559   Er 1.219e+05 
            --- errmin	  Mw  0.033   fc  0.548   t_star  0.009  *Qo  1434.5   Mo 1.811e+11   ssd 1.363e-02  *ra   47.505   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.033   fc  0.548   t_star  0.009  *Qo 22863.9   Mo 2.027e+11   ssd 2.276e-02  *ra   69.069   hyp_dist     nan   az     nan   Er       nan 
    BE.MRG..EHH broadb	  Mw  2.140   fc  3.969   t_star  0.010  *Qo  2984.9   Mo 2.044e+12   ssd 7.615e-02  *ra  227.307   hyp_dist 103.850   az 138.821   Er 1.084e+06 
            --- errmin	  Mw  0.022   fc  0.437   t_star  0.003  *Qo   624.1   Mo 1.485e+11   ssd 2.639e-02  *ra   22.557   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.022   fc  0.437   t_star  0.003  *Qo  1072.6   Mo 1.601e+11   ssd 3.620e-02  *ra   28.143   hyp_dist     nan   az     nan   Er       nan 
   BE.OPTB..EHH broadb	  Mw  2.201   fc 14.257   t_star  0.052   Qo   220.3   Mo 2.518e+12   ssd 4.347e+00   ra   63.281   hyp_dist  38.872   az 107.461   Er 2.940e+06 
            --- errmin	  Mw  0.022   fc  8.415   t_star  0.014   Qo    46.7   Mo 1.820e+11   ssd 4.069e+00   ra   23.487   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.022   fc  8.415   t_star  0.014   Qo    81.0   Mo 1.962e+11   ssd 1.449e+01   ra   91.145   hyp_dist     nan   az     nan   Er       nan 
   BE.RCHB..HHH broadb	  Mw  2.056   fc  9.832   t_star  0.041   Qo   841.2   Mo 1.530e+12   ssd 8.662e-01   ra   91.763   hyp_dist 118.493   az 176.029   Er 2.305e+06 
            --- errmin	  Mw  0.013   fc  1.745   t_star  0.004   Qo    74.9   Mo 6.649e+10   ssd 4.052e-01   ra   13.833   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.013   fc  1.745   t_star  0.004   Qo    91.1   Mo 6.951e+10   ssd 6.122e-01   ra   19.803   hyp_dist     nan   az     nan   Er       nan 
    BE.SKQ..EHH broadb	  Mw  2.134   fc  8.097   t_star  0.029   Qo   965.8   Mo 1.998e+12   ssd 6.318e-01   ra  111.426   hyp_dist  96.404   az 229.370   Er 2.821e+07 
            --- errmin	  Mw  0.010   fc  0.695   t_star  0.002   Qo    62.5   Mo 6.852e+10   ssd 1.656e-01   ra    8.802   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.010   fc  0.695   t_star  0.002   Qo    71.8   Mo 7.096e+10   ssd 2.056e-01   ra   10.454   hyp_dist     nan   az     nan   Er       nan 
    BE.SNF..HHH broadb	  Mw  2.039   fc 21.312   t_star  0.042   Qo   667.9   Mo 1.441e+12   ssd 8.311e+00   ra   42.333   hyp_dist  98.316   az 216.862   Er 2.884e+07 
            --- errmin	  Mw  0.048   fc 27.961   t_star  0.021   Qo   221.3   Mo 2.210e+11   ssd 8.305e+00   ra   24.022   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.048   fc 27.961   t_star  0.021   Qo   655.7   Mo 2.610e+11   ssd 1.130e+02   ra  398.176   hyp_dist     nan   az     nan   Er       nan 
    BE.TGA..HHH broadb	  Mw  2.120   fc 23.865   t_star  0.036   Qo   637.3   Mo 1.905e+12   ssd 1.543e+01   ra   37.804   hyp_dist  79.936   az 211.594   Er 8.394e+07 
            --- errmin	  Mw  0.026   fc 18.564   t_star  0.011   Qo   145.6   Mo 1.660e+11   ssd 1.527e+01   ra   16.540   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.026   fc 18.564   t_star  0.011   Qo   267.9   Mo 1.819e+11   ssd 7.953e+01   ra  132.369   hyp_dist     nan   az     nan   Er       nan 
    BE.TNL..EHH broadb	  Mw  2.060   fc  8.180   t_star  0.032   Qo   913.0   Mo 1.548e+12   ssd 5.050e-01   ra  110.290   hyp_dist 100.396   az 134.013   Er 6.134e+06 
            --- errmin	  Mw  0.016   fc  2.750   t_star  0.011   Qo   231.3   Mo 8.127e+10   ssd 3.650e-01   ra   27.747   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.016   fc  2.750   t_star  0.011   Qo   469.1   Mo 8.578e+10   ssd 7.663e-01   ra   55.847   hyp_dist     nan   az     nan   Er       nan 
   BE.UCCB..HHH broadb	  Mw  1.967   fc  5.171   t_star  0.017   Qo  1214.8   Mo 1.124e+12   ssd 9.256e-02   ra  174.490   hyp_dist  70.670   az 228.822   Er 9.801e+05 
            --- errmin	  Mw  0.011   fc  0.292   t_star  0.001   Qo    88.1   Mo 4.039e+10   ssd 1.760e-02   ra    9.324   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.011   fc  0.292   t_star  0.001   Qo   103.1   Mo 4.190e+10   ssd 2.065e-02   ra   10.440   hyp_dist     nan   az     nan   Er       nan 
   BQ.DREG..HHH broadb	  Mw  2.057   fc 12.806   t_star  0.039   Qo   735.4   Mo 1.535e+12   ssd 1.921e+00   ra   70.449   hyp_dist 100.118   az 127.691   Er 7.106e+06 
            --- errmin	  Mw  0.066   fc 19.833   t_star  0.043   Qo   383.2   Mo 3.144e+11   ssd 1.918e+00   ra   42.807   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.066   fc 19.833   t_star  0.043   Qo 28143.6   Mo 3.954e+11   ssd 3.807e+01   ra  508.964   hyp_dist     nan   az     nan   Er       nan 
    BQ.KLL..EHH shortp	  Mw  2.002   fc 11.144   t_star  0.027   Qo  1124.8   Mo 1.269e+12   ssd 1.046e+00   ra   80.961   hyp_dist 105.664   az 126.494   Er 3.425e+06 
            --- errmin	  Mw  0.017   fc  3.144   t_star  0.007   Qo   225.9   Mo 7.166e+10   ssd 6.808e-01   ra   17.817   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.017   fc  3.144   t_star  0.007   Qo   377.7   Mo 7.595e+10   ssd 1.291e+00   ra   31.825   hyp_dist     nan   az     nan   Er       nan 

*** Average source parameters ***
*** Note: averages computed after removing outliers ****
Mw: 2.16 +/- 0.13
Mw (weighted): 2.18 +/- 0.11
Mo: 1.901e+12 /- 5.130e+11 /+ 7.025e+11 N·m
Mo (weighted): 2.181e+12 /- 6.296e+11 /+ 8.851e+11 N·m
fc: 11.212 /- 4.775 /+ 8.316 Hz
fc (weighted): 6.824 /- 2.368 /+ 3.626 Hz
t_star: 0.034 +/- 0.013 s
t_star (weighted): 0.026 +/- 0.012 s
Qo: 536.2 +/- 495.6
Qo (weighted): 43.1 +/- 37.6
Source radius: 70.934 /- 27.884 /+ 45.945 m
Source radius (weighted): 123.105 /- 39.889 /+ 59.009 m
Static stress drop: 1.445e+00 /- 1.185e+00 /+ 6.589e+00 MPa
Static stress drop (weighted): 3.941e-01 /- 3.113e-01 /+ 1.480e+00 MPa
Er: 9.984e+06 /- 8.775e+06 /+ 7.246e+07 N·m

*** SourceSpec: 1.8+133.g2d734f8.dirty
*** Run completed on: 2025-08-20 17:38:39.830387 CEST
*** Run ID: test_residuals4

After force-push:

   BE.BEBN..HHH broadb	  Mw  1.967   fc  9.622   t_star  0.035   Qo   504.3   Mo 1.124e+12   ssd 5.965e-01   ra   93.766   hyp_dist  61.563   az 139.384   Er 1.942e+06 
            --- errmin	  Mw  0.021   fc  1.478   t_star  0.003   Qo    38.7   Mo 7.848e+10   ssd 2.600e-01   ra   12.482   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.021   fc  1.478   t_star  0.003   Qo    45.7   Mo 8.437e+10   ssd 3.879e-01   ra   17.012   hyp_dist     nan   az     nan   Er       nan 
    BE.CLA..HHH broadb	  Mw  1.975   fc  5.863   t_star  0.020   Qo  1268.3   Mo 1.156e+12   ssd 1.388e-01   ra  153.893   hyp_dist  89.884   az 171.324   Er 4.240e+05 
            --- errmin	  Mw  0.018   fc  0.585   t_star  0.002   Qo   128.0   Mo 6.912e+10   ssd 4.361e-02   ra   13.970   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.018   fc  0.585   t_star  0.002   Qo   160.4   Mo 7.352e+10   ssd 5.760e-02   ra   17.069   hyp_dist     nan   az     nan   Er       nan 
    BE.DOU..HHH broadb	  Mw  2.070   fc 15.030   t_star  0.045   Qo   851.2   Mo 1.602e+12   ssd 3.239e+00   ra   60.028   hyp_dist 130.151   az 196.551   Er 6.261e+06 
            --- errmin	  Mw  0.022   fc  9.145   t_star  0.013   Qo   189.4   Mo 1.151e+11   ssd 3.059e+00   ra   22.709   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.022   fc  9.145   t_star  0.013   Qo   341.1   Mo 1.240e+11   ssd 1.129e+01   ra   93.297   hyp_dist     nan   az     nan   Er       nan 
   BE.DSLS..HHH broadb	  Mw  2.404   fc 16.520   t_star  0.032   Qo    72.4  *Mo 5.087e+12   ssd 1.367e+01   ra   54.611   hyp_dist   7.062   az 297.213  *Er 5.384e+08 
            --- errmin	  Mw  0.034   fc 15.995   t_star  0.016   Qo    24.0  *Mo 5.644e+11   ssd 1.367e+01   ra   26.864   hyp_dist     nan   az     nan  *Er       nan 
            --- errmax	  Mw  0.034   fc 15.995   t_star  0.016   Qo    71.5  *Mo 6.349e+11   ssd 1.035e+02   ra 1662.054   hyp_dist     nan   az     nan  *Er       nan 
    BE.GES..HHH broadb	  Mw  2.130   fc 10.729   t_star  0.044   Qo   613.2   Mo 1.973e+12   ssd 1.452e+00   ra   84.087   hyp_dist  92.755   az 181.105   Er 7.615e+06 
            --- errmin	  Mw  0.033   fc  9.263   t_star  0.027   Qo   234.2   Mo 2.126e+11   ssd 1.449e+00   ra   38.961   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.033   fc  9.263   t_star  0.027   Qo   991.8   Mo 2.382e+11   ssd 9.076e+00   ra  531.375   hyp_dist     nan   az     nan   Er       nan 
    BE.HOU..HHH broadb	  Mw  2.174   fc  8.412   t_star  0.048   Qo   695.6   Mo 2.294e+12   ssd 8.136e-01   ra  107.250   hyp_dist 114.983   az 146.383   Er 4.885e+07 
            --- errmin	  Mw  0.012   fc  1.747   t_star  0.007   Qo    84.0   Mo 9.195e+10   ssd 4.251e-01   ra   18.441   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.012   fc  1.747   t_star  0.007   Qo   110.7   Mo 9.579e+10   ssd 6.791e-01   ra   28.106   hyp_dist     nan   az     nan   Er       nan 
    BE.KLB..HHH broadb	  Mw  2.035   fc 12.634   t_star  0.050   Qo   826.9   Mo 1.420e+12   ssd 1.706e+00   ra   71.411   hyp_dist 142.930   az 150.044   Er 6.326e+06 
            --- errmin	  Mw  0.028   fc  8.147   t_star  0.017   Qo   209.5   Mo 1.321e+11   ssd 1.637e+00   ra   27.997   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.028   fc  8.147   t_star  0.017   Qo   424.6   Mo 1.457e+11   ssd 6.665e+00   ra  129.678   hyp_dist     nan   az     nan   Er       nan 
   BE.MEMS..EHH broadb	  Mw  2.132   fc  7.103   t_star  0.038   Qo   713.1   Mo 1.989e+12   ssd 4.246e-01   ra  127.019   hyp_dist  92.703   az 136.614   Er 3.129e+05 
            --- errmin	  Mw  0.011   fc  0.900   t_star  0.003   Qo    59.5   Mo 7.681e+10   ssd 1.527e-01   ra   14.282   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.011   fc  0.900   t_star  0.003   Qo    71.4   Mo 7.990e+10   ssd 2.071e-01   ra   18.425   hyp_dist     nan   az     nan   Er       nan 
   BE.MOL1..HHH broadb	  Mw  2.154   fc 17.966   t_star  0.037   Qo    42.6   Mo 2.143e+12   ssd 7.403e+00   ra   50.216   hyp_dist   6.170   az 257.490   Er 4.822e+07 
            --- errmin	  Mw  0.015   fc  7.010   t_star  0.006   Qo     5.9   Mo 1.052e+11   ssd 5.807e+00   ra   14.094   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.015   fc  7.010   t_star  0.006   Qo     8.1   Mo 1.107e+11   ssd 1.351e+01   ra   32.130   hyp_dist     nan   az     nan   Er       nan 
   BE.MOL2..HHH broadb	  Mw  2.404   fc 14.830   t_star  0.034   Qo    45.1  *Mo 5.087e+12   ssd 9.885e+00   ra   60.835   hyp_dist   6.071   az 257.621   Er 1.278e+08 
            --- errmin	  Mw  0.013   fc  2.463   t_star  0.002   Qo     2.7  *Mo 2.300e+11   ssd 4.412e+00   ra    8.665   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.013   fc  2.463   t_star  0.002   Qo     3.1  *Mo 2.409e+11   ssd 6.531e+00   ra   12.116   hyp_dist     nan   az     nan   Er       nan 
   BE.MOL3..HHH broadb	  Mw  2.225   fc 19.603   t_star  0.042   Qo    36.1   Mo 2.735e+12   ssd 1.227e+01   ra   46.025   hyp_dist   6.069   az 258.704   Er 1.915e+08 
            --- errmin	  Mw  0.009   fc  5.837   t_star  0.004   Qo     3.3   Mo 8.783e+10   ssd 8.160e+00   ra   10.560   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.009   fc  5.837   t_star  0.004   Qo     4.1   Mo 9.074e+10   ssd 1.544e+01   ra   19.516   hyp_dist     nan   az     nan   Er       nan 
   BE.MOL4..HHH broadb	  Mw  2.218   fc 16.299   t_star  0.040   Qo    38.6   Mo 2.673e+12   ssd 6.896e+00   ra   55.354   hyp_dist   6.070   az 259.478   Er 7.404e+07 
            --- errmin	  Mw  0.009   fc  2.973   t_star  0.003   Qo     2.5   Mo 8.404e+10   ssd 3.245e+00   ra    8.539   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.009   fc  2.973   t_star  0.003   Qo     2.8   Mo 8.676e+10   ssd 4.873e+00   ra   12.349   hyp_dist     nan   az     nan   Er       nan 
   BE.MOL5..HHH broadb	  Mw  2.176   fc 18.587   t_star  0.039   Qo    38.8   Mo 2.312e+12   ssd 8.846e+00   ra   48.539   hyp_dist   6.069   az 261.461   Er 1.130e+08 
            --- errmin	  Mw  0.009   fc  4.093   t_star  0.003   Qo     2.8   Mo 6.972e+10   ssd 4.778e+00   ra    8.760   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.009   fc  4.093   t_star  0.003   Qo     3.3   Mo 7.188e+10   ssd 7.724e+00   ra   13.707   hyp_dist     nan   az     nan   Er       nan 
   BE.MOLA..HNH    acc	  Mw  2.404   fc 25.797   t_star  0.044   Qo    36.0  *Mo 5.087e+12  *ssd 5.203e+01   ra   34.973   hyp_dist   6.282   az 261.461  *Er 1.026e+09 
            --- errmin	  Mw  0.020   fc 18.422   t_star  0.008   Qo     5.5  *Mo 3.453e+11  *ssd 5.090e+01   ra   14.570   hyp_dist     nan   az     nan  *Er       nan 
            --- errmax	  Mw  0.020   fc 18.422   t_star  0.008   Qo     7.9  *Mo 3.704e+11  *ssd 2.291e+02   ra   87.355   hyp_dist     nan   az     nan  *Er       nan 
   BE.MOLB..HNH    acc	  Mw  2.224  *fc 34.653   t_star  0.046   Qo    33.0   Mo 2.726e+12  *ssd 6.758e+01   ra   26.035   hyp_dist   6.069   az 261.461  *Er 5.680e+08 
            --- errmin	  Mw  0.019  *fc 29.908   t_star  0.008   Qo     4.8   Mo 1.744e+11  *ssd 6.742e+01   ra   12.061   hyp_dist     nan   az     nan  *Er       nan 
            --- errmax	  Mw  0.019  *fc 29.908   t_star  0.008   Qo     6.7   Mo 1.863e+11  *ssd 3.993e+02   ra  164.082   hyp_dist     nan   az     nan  *Er       nan 
   BE.MOLK..HHH broadb	  Mw  2.404   fc 10.405   t_star  0.015   Qo   141.9  *Mo 5.087e+12   ssd 3.415e+00   ra   86.705   hyp_dist   6.121   az 266.667   Er 5.818e+07 
            --- errmin	  Mw  0.020   fc  3.061   t_star  0.006   Qo    41.0  *Mo 3.371e+11   ssd 2.293e+00   ra   19.708   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.020   fc  3.061   t_star  0.006   Qo    97.2  *Mo 3.611e+11   ssd 4.512e+00   ra   36.136   hyp_dist     nan   az     nan   Er       nan 
   BE.MOLS..HHH broadb	  Mw  2.270   fc 13.535   t_star  0.045   Qo    50.6   Mo 3.199e+12   ssd 4.726e+00   ra   66.656   hyp_dist   6.311   az 259.063  *Er 2.266e+09 
            --- errmin	  Mw  0.005   fc  1.758   t_star  0.003   Qo     2.6   Mo 5.880e+10   ssd 1.670e+00   ra    7.663   hyp_dist     nan   az     nan  *Er       nan 
            --- errmax	  Mw  0.005   fc  1.758   t_star  0.003   Qo     3.0   Mo 5.990e+10   ssd 2.219e+00   ra    9.951   hyp_dist     nan   az     nan  *Er       nan 
   BE.MOLT..HHH broadb	  Mw  2.220   fc 21.685   t_star  0.038   Qo    50.5   Mo 2.693e+12   ssd 1.636e+01   ra   41.606   hyp_dist   6.070   az 259.735   Er 6.781e+07 
            --- errmin	  Mw  0.014   fc 10.667   t_star  0.007   Qo     7.8   Mo 1.229e+11   ssd 1.431e+01   ra   13.719   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.014   fc 10.667   t_star  0.007   Qo    11.3   Mo 1.288e+11   ssd 4.057e+01   ra   40.285   hyp_dist     nan   az     nan   Er       nan 
   BE.MRCA..HNH    acc	  Mw  2.282   fc  5.960  *t_star  0.010  *Qo  2817.3   Mo 3.334e+12   ssd 4.204e-01   ra  151.377   hyp_dist 103.506   az 207.298   Er 3.676e+06 
            --- errmin	  Mw  0.013   fc  0.533  *t_star  0.002  *Qo   496.9   Mo 1.512e+11   ssd 1.173e-01   ra   12.417   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.013   fc  0.533  *t_star  0.002  *Qo   767.8   Mo 1.584e+11   ssd 1.489e-01   ra   14.855   hyp_dist     nan   az     nan   Er       nan 
    BE.MRD..HHH broadb	  Mw  2.087   fc  2.965  *t_star  0.010  *Qo  3061.0   Mo 1.701e+12   ssd 2.640e-02  *ra  304.324   hyp_dist 104.722   az 193.559   Er 1.219e+05 
            --- errmin	  Mw  0.033   fc  0.548  *t_star  0.009  *Qo  1434.5   Mo 1.811e+11   ssd 1.363e-02  *ra   47.505   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.033   fc  0.548  *t_star  0.009  *Qo 22863.9   Mo 2.027e+11   ssd 2.276e-02  *ra   69.069   hyp_dist     nan   az     nan   Er       nan 
    BE.MRG..EHH broadb	  Mw  2.140   fc  3.968  *t_star  0.010  *Qo  2984.9   Mo 2.045e+12   ssd 7.612e-02  *ra  227.356   hyp_dist 103.850   az 138.821   Er 1.084e+06 
            --- errmin	  Mw  0.022   fc  0.437  *t_star  0.003  *Qo   624.0   Mo 1.485e+11   ssd 2.638e-02  *ra   22.560   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.022   fc  0.437  *t_star  0.003  *Qo  1072.5   Mo 1.601e+11   ssd 3.619e-02  *ra   28.146   hyp_dist     nan   az     nan   Er       nan 
   BE.OPTB..EHH broadb	  Mw  2.197   fc 13.882   t_star  0.051   Qo   224.7   Mo 2.484e+12   ssd 3.958e+00   ra   64.992   hyp_dist  38.872   az 107.461   Er 2.663e+06 
            --- errmin	  Mw  0.020   fc  7.710   t_star  0.013   Qo    46.8   Mo 1.694e+11   ssd 3.634e+00   ra   23.207   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.020   fc  7.710   t_star  0.013   Qo    80.3   Mo 1.818e+11   ssd 1.203e+01   ra   81.190   hyp_dist     nan   az     nan   Er       nan 
   BE.RCHB..HHH broadb	  Mw  2.056   fc  9.800   t_star  0.041   Qo   843.0   Mo 1.529e+12   ssd 8.575e-01   ra   92.060   hyp_dist 118.493   az 176.029   Er 2.280e+06 
            --- errmin	  Mw  0.013   fc  1.732   t_star  0.004   Qo    74.9   Mo 6.650e+10   ssd 3.998e-01   ra   13.825   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.013   fc  1.732   t_star  0.004   Qo    91.1   Mo 6.952e+10   ssd 6.031e-01   ra   19.759   hyp_dist     nan   az     nan   Er       nan 
    BE.SKQ..EHH broadb	  Mw  2.134   fc  8.774   t_star  0.032   Qo   891.9   Mo 1.998e+12   ssd 8.038e-01   ra  102.832   hyp_dist  96.404   az 229.370   Er 4.650e+07 
            --- errmin	  Mw  0.011   fc  0.775   t_star  0.002   Qo    49.7   Mo 7.208e+10   ssd 2.167e-01   ra    8.344   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.011   fc  0.775   t_star  0.002   Qo    55.9   Mo 7.478e+10   ssd 2.711e-01   ra    9.961   hyp_dist     nan   az     nan   Er       nan 
    BE.SNF..HHH broadb	  Mw  2.057   fc 22.532   t_star  0.045   Qo   630.3   Mo 1.535e+12   ssd 1.046e+01   ra   40.042   hyp_dist  98.316   az 216.862   Er 4.698e+07 
            --- errmin	  Mw  0.038   fc 24.443   t_star  0.016   Qo   165.8   Mo 1.900e+11   ssd 1.045e+01   ra   20.835   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.038   fc 24.443   t_star  0.016   Qo   350.0   Mo 2.168e+11   ssd 9.772e+01   ra  400.467   hyp_dist     nan   az     nan   Er       nan 
    BE.TGA..HHH broadb	  Mw  2.120   fc 23.865   t_star  0.036   Qo   637.3   Mo 1.905e+12   ssd 1.543e+01   ra   37.804   hyp_dist  79.936   az 211.594   Er 8.394e+07 
            --- errmin	  Mw  0.026   fc 18.564   t_star  0.011   Qo   145.6   Mo 1.660e+11   ssd 1.527e+01   ra   16.540   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.026   fc 18.564   t_star  0.011   Qo   267.9   Mo 1.819e+11   ssd 7.953e+01   ra  132.369   hyp_dist     nan   az     nan   Er       nan 
    BE.TNL..EHH broadb	  Mw  2.060   fc  8.180   t_star  0.032   Qo   913.0   Mo 1.548e+12   ssd 5.050e-01   ra  110.290   hyp_dist 100.396   az 134.013   Er 6.134e+06 
            --- errmin	  Mw  0.016   fc  2.750   t_star  0.011   Qo   231.3   Mo 8.127e+10   ssd 3.650e-01   ra   27.747   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.016   fc  2.750   t_star  0.011   Qo   469.1   Mo 8.578e+10   ssd 7.663e-01   ra   55.847   hyp_dist     nan   az     nan   Er       nan 
   BE.UCCB..HHH broadb	  Mw  1.967   fc  5.171   t_star  0.017   Qo  1214.6   Mo 1.124e+12   ssd 9.259e-02   ra  174.473   hyp_dist  70.670   az 228.822   Er 9.806e+05 
            --- errmin	  Mw  0.011   fc  0.292   t_star  0.001   Qo    88.1   Mo 4.039e+10   ssd 1.761e-02   ra    9.324   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.011   fc  0.292   t_star  0.001   Qo   103.1   Mo 4.189e+10   ssd 2.065e-02   ra   10.440   hyp_dist     nan   az     nan   Er       nan 
   BQ.DREG..HHH broadb	  Mw  2.035   fc  9.255   t_star  0.027   Qo  1072.3   Mo 1.418e+12   ssd 6.698e-01   ra   97.483   hyp_dist 100.118   az 127.691   Er 2.656e+06 
            --- errmin	  Mw  0.019   fc  3.985   t_star  0.014   Qo   366.4   Mo 9.189e+10   ssd 5.542e-01   ra   29.343   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.019   fc  3.985   t_star  0.014   Qo  1156.8   Mo 9.825e+10   ssd 1.427e+00   ra   73.729   hyp_dist     nan   az     nan   Er       nan 
    BQ.KLL..EHH shortp	  Mw  2.007   fc 12.698   t_star  0.031   Qo  1000.6   Mo 1.288e+12   ssd 1.571e+00   ra   71.053   hyp_dist 105.664   az 126.494   Er 5.217e+06 
            --- errmin	  Mw  0.018   fc  4.610   t_star  0.008   Qo   216.3   Mo 7.583e+10   ssd 1.189e+00   ra   18.926   hyp_dist     nan   az     nan   Er       nan 
            --- errmax	  Mw  0.018   fc  4.610   t_star  0.008   Qo   381.2   Mo 8.057e+10   ssd 2.657e+00   ra   40.503   hyp_dist     nan   az     nan   Er       nan 

*** Average source parameters ***
*** Note: averages computed after removing outliers ****
Mw: 2.16 +/- 0.13
Mw (weighted): 2.18 +/- 0.11
Mo: 1.903e+12 /- 5.122e+11 /+ 7.008e+11 N·m
Mo (weighted): 2.242e+12 /- 6.338e+11 /+ 8.837e+11 N·m
fc: 11.265 /- 4.677 /+ 7.997 Hz
fc (weighted): 7.020 /- 2.481 /+ 3.837 Hz
t_star: 0.037 +/- 0.009 s
t_star (weighted): 0.030 +/- 0.011 s
Qo: 499.5 +/- 420.1
Qo (weighted): 43.8 +/- 37.7
Source radius: 70.673 /- 26.692 /+ 42.891 m
Source radius (weighted): 119.789 /- 39.528 /+ 58.994 m
Static stress drop: 1.627e+00 /- 1.341e+00 /+ 7.641e+00 MPa
Static stress drop (weighted): 4.330e-01 /- 3.469e-01 /+ 1.745e+00 MPa
Er: 9.011e+06 /- 7.838e+06 /+ 6.025e+07 N·m

*** SourceSpec: 1.8+128.g0ad5908
*** Run completed on: 2025-08-20 18:09:12.798659 CEST
*** Run ID: test_residuals5

@claudiodsf
Copy link
Member

Hi Kris,

From your outputs, I could see that the "pre force-push" version was SourceSpec: 1.8+133.g2d734f8.dirty.

So I made a diff with that version through git diff 2d734f8. Note that:

  1. I have locally an extra commit regarding the CHANGELOG
  2. Your version was in a "dirty" state (i.e. local changes uncommitted).

Anyway, this is the ouptut of the diff

diff --git a/CHANGELOG.md b/CHANGELOG.md
index d412158..8a43c5d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,7 +25,7 @@ Copyright (c) 2011-2025 Claudio Satriano <[email protected]>
   trace amplitude below which the trace is not checked for clipping
 - Use spectral interpolation to compute and apply station residuals
 - Limit spectrum and residual to common frequency range when applying
-  correction before fitting
+  correction before fitting (see [#69])
 
 ### Post-Inversion
 
@@ -828,3 +828,4 @@ Initial Python port.
 [#49]: https://github.com/SeismicSource/sourcespec/issues/49
 [#67]: https://github.com/SeismicSource/sourcespec/issues/67
 [#68]: https://github.com/SeismicSource/sourcespec/issues/68
+[#69]: https://github.com/SeismicSource/sourcespec/issues/69
diff --git a/sourcespec/spectrum.py b/sourcespec/spectrum.py
index e145a70..e9f9df9 100644
--- a/sourcespec/spectrum.py
+++ b/sourcespec/spectrum.py
@@ -112,7 +112,7 @@ def _find_nan_edges(data):
 
 
 def _interpolate_data_to_new_freq(
-        data, freq, new_freq, fill_value='extrapolate', fix_negative=True):
+        data, freq, new_freq, fill_value=np.nan, fix_negative=True):
     """
     Helper function to interpolate data to a new frequency range.
 
@@ -120,6 +120,7 @@ def _interpolate_data_to_new_freq(
     :param freq: The original frequency range.
     :param new_freq: The new frequency range.
     :param fill_value: The value to use for extrapolation.
+        Default is np.nan.
         If 'extrapolate', the data is extrapolated to the new frequency range.
         See scipy.interpolate.interp1d for more details.
     :param fix_negative: If True, negative values are replaced by the
@@ -393,6 +394,11 @@ class Spectrum():
         n = np.ceil((log_freq[-1] - log_freq[0]) / log_df)
         freq_logspaced =\
             np.logspace(log_freq[0], log_freq[-1], int(n)+1)
+        # Make sure first and last frequencies match exactly between
+        # logspaced and linear frequency axes (since the code above might have
+        # numerical errors)
+        freq_logspaced[0] = self.freq[0]
+        freq_logspaced[-1] = self.freq[-1]
         # If logspaced frequencies already exist,
         # reinterpolate the data to the new logspaced frequencies
         if (
@@ -432,34 +438,15 @@ class Spectrum():
             raise ValueError('Data axis is empty')
         if self.freq_logspaced.size == 0:
             raise ValueError('Logspaced frequency axis is empty')
-        # Find NaN indexes at the beginning and end of the data
+        # Find and remove NaN values at the beginning and end of the data
         nan_idxs = _find_nan_edges(data)
-        # If there are NaN values at the beginning or end,
-        # do not use extrapolation
-        fill_value = np.nan if nan_idxs.size else 'extrapolate'
         data = np.delete(data, nan_idxs)
         freq = np.delete(self.freq, nan_idxs)
         # Reinterpolate data using log10 frequencies
         data_logspaced = _interpolate_data_to_new_freq(
             data, freq, self.freq_logspaced,
-            fill_value=fill_value, fix_negative=fix_negative
+            fix_negative=fix_negative
         )
-        # If extrapolation was applied, mask (set to NaN) the values that lie
-        # outside the original frequency range to avoid relying on unreliable
-        # extrapolated data.
-        if fill_value == 'extrapolate':
-            # Spacing between the first two log-spaced frequencies.
-            # Used as a margin to identify values that fall below
-            # the valid range.
-            lower_spacing = self.freq_logspaced[1] - self.freq_logspaced[0]
-            data_logspaced[
-                self.freq_logspaced < freq[0] - lower_spacing] = np.nan
-            # Spacing between the last two log-spaced frequencies.
-            # Used as a margin to identify values that fall above
-            # the valid range.
-            upper_spacing = self.freq_logspaced[-1] - self.freq_logspaced[-2]
-            data_logspaced[
-                self.freq_logspaced > freq[-1] + upper_spacing] = np.nan
         if which == 'data':
             self.data_logspaced = data_logspaced
         else:
@@ -506,12 +493,13 @@ class Spectrum():
         else:
             self.data_mag = data
 
-    def interp_data_to_new_freq(self, new_freq, fill_value='extrapolate'):
+    def interp_data_to_new_freq(self, new_freq, fill_value=np.nan):
         """
         Interpolate the linear data to a new frequency axis.
 
         :param new_freq: The new frequency axis.
         :param fill_value: The value to use for extrapolation.
+            Default is np.nan.
             If 'extrapolate', the data is extrapolated to the new frequency
             range. See scipy.interpolate.interp1d for more details.
         """
@@ -532,13 +520,13 @@ class Spectrum():
             )
         self.freq = new_freq
 
-    def interp_data_logspaced_to_new_freq(
-            self, new_freq, fill_value='extrapolate'):
+    def interp_data_logspaced_to_new_freq(self, new_freq, fill_value=np.nan):
         """
         Interpolate the logspaced data to a new frequency axis.
 
         :param new_freq: The new frequency axis.
         :param fill_value: The value to use for extrapolation.
+            Default is np.nan.
             If 'extrapolate', the data is extrapolated to the new frequency
             range. See scipy.interpolate.interp1d for more details.
         """

The main changes are:

  1. Fixing the logspaced extreme frequencies to the corresponding linspaced frequencies
  2. Removing the masking of extrapolated values (since extrapolation is no more used)
  3. Using by default fill_value=np.nan in _interpolate_data_to_new_freq() and in Spectrum.interp_data_to_new_freq()

This later modification affects all the calls to Spectrum.make_logspaced_from_linear() and Spectrum.make_linear_from_logspaced() in sap_build_spectra.py.

However, those changes were already in the latest version before the force-push. So I think that your reference run was an older one.

Do you think that the new solution, even if different, remains acceptable? I think we should accept that this new code produces slightly different spectra and that the solutions might be slightly (hopefully) different.

Let me know your thoughts

@claudiodsf
Copy link
Member

In fact, you can make a precise diff between your two versions, SourceSpec: 1.8+133.g2d734f8.dirty and SourceSpec: 1.8+128.g0ad5908, through:

  git diff 2d734f8 0ad5908

The result is basically the same as above (without the change in CHANGELOG):

diff --git a/sourcespec/spectrum.py b/sourcespec/spectrum.py
index e145a70..e9f9df9 100644
--- a/sourcespec/spectrum.py
+++ b/sourcespec/spectrum.py
@@ -112,7 +112,7 @@ def _find_nan_edges(data):
 
 
 def _interpolate_data_to_new_freq(
-        data, freq, new_freq, fill_value='extrapolate', fix_negative=True):
+        data, freq, new_freq, fill_value=np.nan, fix_negative=True):
     """
     Helper function to interpolate data to a new frequency range.
 
@@ -120,6 +120,7 @@ def _interpolate_data_to_new_freq(
     :param freq: The original frequency range.
     :param new_freq: The new frequency range.
     :param fill_value: The value to use for extrapolation.
+        Default is np.nan.
         If 'extrapolate', the data is extrapolated to the new frequency range.
         See scipy.interpolate.interp1d for more details.
     :param fix_negative: If True, negative values are replaced by the
@@ -393,6 +394,11 @@ class Spectrum():
         n = np.ceil((log_freq[-1] - log_freq[0]) / log_df)
         freq_logspaced =\
             np.logspace(log_freq[0], log_freq[-1], int(n)+1)
+        # Make sure first and last frequencies match exactly between
+        # logspaced and linear frequency axes (since the code above might have
+        # numerical errors)
+        freq_logspaced[0] = self.freq[0]
+        freq_logspaced[-1] = self.freq[-1]
         # If logspaced frequencies already exist,
         # reinterpolate the data to the new logspaced frequencies
         if (
@@ -432,34 +438,15 @@ class Spectrum():
             raise ValueError('Data axis is empty')
         if self.freq_logspaced.size == 0:
             raise ValueError('Logspaced frequency axis is empty')
-        # Find NaN indexes at the beginning and end of the data
+        # Find and remove NaN values at the beginning and end of the data
         nan_idxs = _find_nan_edges(data)
-        # If there are NaN values at the beginning or end,
-        # do not use extrapolation
-        fill_value = np.nan if nan_idxs.size else 'extrapolate'
         data = np.delete(data, nan_idxs)
         freq = np.delete(self.freq, nan_idxs)
         # Reinterpolate data using log10 frequencies
         data_logspaced = _interpolate_data_to_new_freq(
             data, freq, self.freq_logspaced,
-            fill_value=fill_value, fix_negative=fix_negative
+            fix_negative=fix_negative
         )
-        # If extrapolation was applied, mask (set to NaN) the values that lie
-        # outside the original frequency range to avoid relying on unreliable
-        # extrapolated data.
-        if fill_value == 'extrapolate':
-            # Spacing between the first two log-spaced frequencies.
-            # Used as a margin to identify values that fall below
-            # the valid range.
-            lower_spacing = self.freq_logspaced[1] - self.freq_logspaced[0]
-            data_logspaced[
-                self.freq_logspaced < freq[0] - lower_spacing] = np.nan
-            # Spacing between the last two log-spaced frequencies.
-            # Used as a margin to identify values that fall above
-            # the valid range.
-            upper_spacing = self.freq_logspaced[-1] - self.freq_logspaced[-2]
-            data_logspaced[
-                self.freq_logspaced > freq[-1] + upper_spacing] = np.nan
         if which == 'data':
             self.data_logspaced = data_logspaced
         else:
@@ -506,12 +493,13 @@ class Spectrum():
         else:
             self.data_mag = data
 
-    def interp_data_to_new_freq(self, new_freq, fill_value='extrapolate'):
+    def interp_data_to_new_freq(self, new_freq, fill_value=np.nan):
         """
         Interpolate the linear data to a new frequency axis.
 
         :param new_freq: The new frequency axis.
         :param fill_value: The value to use for extrapolation.
+            Default is np.nan.
             If 'extrapolate', the data is extrapolated to the new frequency
             range. See scipy.interpolate.interp1d for more details.
         """
@@ -532,13 +520,13 @@ class Spectrum():
             )
         self.freq = new_freq
 
-    def interp_data_logspaced_to_new_freq(
-            self, new_freq, fill_value='extrapolate'):
+    def interp_data_logspaced_to_new_freq(self, new_freq, fill_value=np.nan):
         """
         Interpolate the logspaced data to a new frequency axis.
 
         :param new_freq: The new frequency axis.
         :param fill_value: The value to use for extrapolation.
+            Default is np.nan.
             If 'extrapolate', the data is extrapolated to the new frequency
             range. See scipy.interpolate.interp1d for more details.
         """

@claudiodsf
Copy link
Member

Digging deeper, you made your reference test before integrating commit fa0959a.

You can see it locally (it is no more on GitHub) through: git show fa0959a:

commit fa0959a09488f9b0af73de47c310e0a622a515f6
Author: Claudio Satriano <[email protected]>
Date:   Wed Aug 20 17:47:17 2025 +0200

    Use np.nan as default fill_value in Spectrum interpolation methods

diff --git a/sourcespec/spectrum.py b/sourcespec/spectrum.py
index e145a70..e9f9df9 100644
--- a/sourcespec/spectrum.py
+++ b/sourcespec/spectrum.py
@@ -112,7 +112,7 @@ def _find_nan_edges(data):
 
 
 def _interpolate_data_to_new_freq(
-        data, freq, new_freq, fill_value='extrapolate', fix_negative=True):
+        data, freq, new_freq, fill_value=np.nan, fix_negative=True):
     """
     Helper function to interpolate data to a new frequency range.
 
@@ -120,6 +120,7 @@ def _interpolate_data_to_new_freq(
     :param freq: The original frequency range.
     :param new_freq: The new frequency range.
     :param fill_value: The value to use for extrapolation.
+        Default is np.nan.
         If 'extrapolate', the data is extrapolated to the new frequency range.
         See scipy.interpolate.interp1d for more details.
     :param fix_negative: If True, negative values are replaced by the
@@ -393,6 +394,11 @@ class Spectrum():
         n = np.ceil((log_freq[-1] - log_freq[0]) / log_df)
         freq_logspaced =\
             np.logspace(log_freq[0], log_freq[-1], int(n)+1)
+        # Make sure first and last frequencies match exactly between
+        # logspaced and linear frequency axes (since the code above might have
+        # numerical errors)
+        freq_logspaced[0] = self.freq[0]
+        freq_logspaced[-1] = self.freq[-1]
         # If logspaced frequencies already exist,
         # reinterpolate the data to the new logspaced frequencies
         if (
@@ -432,34 +438,15 @@ class Spectrum():
             raise ValueError('Data axis is empty')
         if self.freq_logspaced.size == 0:
             raise ValueError('Logspaced frequency axis is empty')
-        # Find NaN indexes at the beginning and end of the data
+        # Find and remove NaN values at the beginning and end of the data
         nan_idxs = _find_nan_edges(data)
-        # If there are NaN values at the beginning or end,
-        # do not use extrapolation
-        fill_value = np.nan if nan_idxs.size else 'extrapolate'
         data = np.delete(data, nan_idxs)
         freq = np.delete(self.freq, nan_idxs)
         # Reinterpolate data using log10 frequencies
         data_logspaced = _interpolate_data_to_new_freq(
             data, freq, self.freq_logspaced,
-            fill_value=fill_value, fix_negative=fix_negative
+            fix_negative=fix_negative
         )
-        # If extrapolation was applied, mask (set to NaN) the values that lie
-        # outside the original frequency range to avoid relying on unreliable
-        # extrapolated data.
-        if fill_value == 'extrapolate':
-            # Spacing between the first two log-spaced frequencies.
-            # Used as a margin to identify values that fall below
-            # the valid range.
-            lower_spacing = self.freq_logspaced[1] - self.freq_logspaced[0]
-            data_logspaced[
-                self.freq_logspaced < freq[0] - lower_spacing] = np.nan
-            # Spacing between the last two log-spaced frequencies.
-            # Used as a margin to identify values that fall above
-            # the valid range.
-            upper_spacing = self.freq_logspaced[-1] - self.freq_logspaced[-2]
-            data_logspaced[
-                self.freq_logspaced > freq[-1] + upper_spacing] = np.nan
         if which == 'data':
             self.data_logspaced = data_logspaced
         else:
@@ -506,12 +493,13 @@ class Spectrum():
         else:
             self.data_mag = data
 
-    def interp_data_to_new_freq(self, new_freq, fill_value='extrapolate'):
+    def interp_data_to_new_freq(self, new_freq, fill_value=np.nan):
         """
         Interpolate the linear data to a new frequency axis.
 
         :param new_freq: The new frequency axis.
         :param fill_value: The value to use for extrapolation.
+            Default is np.nan.
             If 'extrapolate', the data is extrapolated to the new frequency
             range. See scipy.interpolate.interp1d for more details.
         """
@@ -532,13 +520,13 @@ class Spectrum():
             )
         self.freq = new_freq
 
-    def interp_data_logspaced_to_new_freq(
-            self, new_freq, fill_value='extrapolate'):
+    def interp_data_logspaced_to_new_freq(self, new_freq, fill_value=np.nan):
         """
         Interpolate the logspaced data to a new frequency axis.
 
         :param new_freq: The new frequency axis.
         :param fill_value: The value to use for extrapolation.
+            Default is np.nan.
             If 'extrapolate', the data is extrapolated to the new frequency
             range. See scipy.interpolate.interp1d for more details.
         """

@krisvanneste
Copy link
Collaborator Author

I'll have a look.
I think my version was in a dirty state only because I had to change the fill_value = np.nan if nan_idxs.size else 'extrapolate' line in Spectrum.make_logspaced_from_linear.

@krisvanneste
Copy link
Collaborator Author

OK, I agree this is the likely reason. I manually set the fill value to NaN, as I didn't see you had a commit for it. So it was only used in this particular call, while the general interpolation function was still using extrapolation as the default.

The differences are minimal in terms of magnitude, but more pronounced for corner frequency (and related parameters), which does raise a question how large the uncertainties are for these parameters.

@claudiodsf
Copy link
Member

The differences are minimal in terms of magnitude, but more pronounced for corner frequency (and related parameters), which does raise a question how large the uncertainties are for these parameters.

Yes, I agree that the uncertainty of single-station estimates of fc and t* is often underestimated, as these values can vary significantly with small changes in the spectral shape or with the choice of inversion method.
I think that the grid-search inversion algorithm provides a more reliable estimate of single-station uncertainty, although it is considerably slower.
An even better approach would be to derive uncertainty from multiple estimates obtained by varying aspects of the same spectrum (for example, by adjusting the smoothing factor).

On the other hand, using multiple stations largely mitigates this issue, since inter-station variability is much greater than within-station uncertainty. This is supported by the fact that your summary values for fc and t* are consistent within their respective errors:

Before:

fc: 11.212 /- 4.775 /+ 8.316 Hz
fc (weighted): 6.824 /- 2.368 /+ 3.626 Hz
t_star: 0.034 +/- 0.013 s
t_star (weighted): 0.026 +/- 0.012 s

After:

fc: 11.265 /- 4.677 /+ 7.997 Hz
fc (weighted): 7.020 /- 2.481 /+ 3.837 Hz
t_star: 0.037 +/- 0.009 s
t_star (weighted): 0.030 +/- 0.011 s

@krisvanneste
Copy link
Collaborator Author

Claudio,
Indeed, I was referring to the station estimates. The averages are much closer.

@claudiodsf
Copy link
Member

If you're curious, you can try using grid search. You should get much larger single-station uncertainties

@claudiodsf
Copy link
Member

So, are you OK to merge this PR?

@krisvanneste
Copy link
Collaborator Author

Yes, let's finalize this one.
I never tried grid search, I will investigate it when I have more time.

@claudiodsf claudiodsf merged commit 8edce74 into SeismicSource:main Aug 21, 2025
2 checks passed
@claudiodsf
Copy link
Member

Merged! That was a long ride!

Thank you so much Kris for all this work 🙏

@krisvanneste
Copy link
Collaborator Author

Yes, that was a long one. Glad we solved it!
On to the next topic...

@claudiodsf
Copy link
Member

Yes!

I'm currently directly pushing to main some improvements that I'm doing for the work that will be presented at this IAGA/IASPEI 2025 poster (I'm not attending, though, are you?)

Then, I'll:

@krisvanneste
Copy link
Collaborator Author

krisvanneste commented Aug 21, 2025

I'm currently directly pushing to main some improvements that I'm doing for the work that will be presented at this IAGA/IASPEI 2025 poster (I'm not attending, though, are you?)

Yes, I will attend the IASPEI meeting in Lisbon: https://c-in.floq.live/event/iagaiaspei-2025/search?objectClass=timeslot&objectId=685539310879475d4c6a57c6&type=detail

A pity you are not attending. I will chat with Aurore then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants