Explanations of warnings and how to get rid of them#

Sometimes when you’re working with thebeat you’ll encounter warnings. While useful, they can of course become annoying at some point. Even though it’s possible to simply disable all these warnings (see at the bottom of this page), we believe it’s better practice to look into the origin of the warning, and solve it there.

Below you’ll find a number of common warnings and an explanation of where they originate.

Frame rounding#

What does the warning look like?#

For one or more of the used sounds, the exact start or end positions in frames (i.e. samples) were rounded off to the neirest integer ceiling. This shouldn’t be a problem. To get rid of this warning, try rounding off the onsets in the passed Sequence object by calling Sequence.round_onsets() before passing the object to the SoundSequence constructor.

When can you encounter this warning?#

You can encounter this warning when creating a SoundSequence object.

What is the reason for this warning?#

Digital sounds contain a certain number of ‘samples’. The samples are the points at which the amplitude of the sound is specified. There is a fixed number of samples per second (the default in thebeat is 48000, another common value is 44100). When creating a SoundSequence object, thebeat tries to place each individual sound at its respective onset (i.e. t value). The onset is then calculated in terms of the specific sample at which the sound should start, but if the onsets specified in the passed Sequence object do not correspond to a round-number sample (i.e. it falls in between two samples), the exact sample onset is rounded off.

What is the solution?#

As the warning specifies, try rounding off the Sequence object’s onsets before constructing the SoundSequence object.

Example with warning#

[27]:
from thebeat import Sequence, SoundStimulus, SoundSequence

sound = SoundStimulus.generate()
sequence = Sequence.generate_random_normal(n_events=10, mu=500, sigma=25)
print(sequence)
ss = SoundSequence(sound, sequence)
Object of type Sequence (ends with event)
10 events
IOIs: [498.94789451 488.24352484 525.18103599 510.17418851 497.01293299
 479.7327817  462.86352676 518.29654558 478.19439456]
Onsets: [   0.          498.94789451  987.19141935 1512.37245534 2022.54664384
 2519.55957683 2999.29235853 3462.15588529 3980.45243087 4458.64682544]
Sequence name: Not provided

/Users/jellevanderwerff/thebeat-package/thebeat/core/soundsequence.py:360: Warning: thebeat: For one or more of the used sounds, the exact start or end positions in frames (i.e. samples) were rounded off to the neirest integer ceiling. This shouldn't be a problem. To get rid of this warning, try rounding off the onsets in the passed Sequence objectby calling Sequence.round_onsets() before passing the object to the SoundSequence constructor.

  warnings.warn(thebeat._warnings.framerounding_soundseq)

Example without warning#

[28]:
from thebeat import Sequence, SoundStimulus, SoundSequence

sound = SoundStimulus.generate()
sequence = Sequence.generate_random_normal(n_events=10, mu=500, sigma=25)
sequence.round_onsets(decimals=2)
print(sequence)
ss = SoundSequence(sound, sequence)
Object of type Sequence (ends with event)
10 events
IOIs: [483.88 495.13 498.04 483.6  515.44 529.2  559.45 459.8  491.27]
Onsets: [   0.    483.88  979.01 1477.05 1960.65 2476.09 3005.29 3564.74 4024.54
 4515.81]
Sequence name: Not provided

Normalization#

What does the warning look like?#

Sound was normalized to avoid distortion. If undesirable, change the amplitude of the sounds.

When can you encounter this warning?#

You can encounter this warning when creating a SoundSequence, Melody, or SoundStimulus object. The most common is when overlaying sounds. Consider the following code:

[29]:
from thebeat import SoundStimulus

stim_0 = SoundStimulus.generate()
stim_0.plot_waveform(title="stim_0")
stim_1 = SoundStimulus.generate()
stim_1.plot_waveform(title="stim_1")

stim_overlayed = stim_0 + stim_1
/Users/jellevanderwerff/thebeat-package/thebeat/helpers.py:254: Warning: thebeat: Sound was normalized to avoid distortion. If undesirable, change the amplitude of the sounds.
  warnings.warn(thebeat._warnings.normalization)
../../_images/examples_tipstricks_warnings_17_1.png
../../_images/examples_tipstricks_warnings_17_2.png

As you can see the amplitudes of the two stimuli run from -1 to 1. When these sounds are overlayed both sounds’ amplitudes are summed. The overlayed sound would therefore have amplitudes that run from -2 to 2, resulting in distorted sound. thebeat automatically normalizes the sound so that the amplitudes run from -1 to 1 again.

What is the solution?#

As the warning specifies, you can change the amplitude of the sounds before overlaying them. This also ensures that sounds with a different frequency will be equally loud, for instance:

[30]:
from thebeat import SoundStimulus
stim_0 = SoundStimulus.generate(freq=220)
stim_0.change_amplitude(factor=0.7)
stim_1 = SoundStimulus.generate(freq=440)
stim_1.change_amplitude(factor=0.3)

stim_overlayed = stim_0 + stim_1

Phase difference discarded#

What does the warning look like?#

The first onset of the test sequence was at t = 0. This would result in a phase difference that is always 0, which is not very informative. As such, the first onset was discarded. If you want the first onset at a different time than zero, use the Sequence.from_onsets() method to create the Sequence object.

When can you encounter this warning?#

You can encounter this warning when using the get_phase_differences() function or the plot_phase_differences() function.

What is the reason for this warning?#

Consider the following sequences:

[31]:
from thebeat import Sequence
from thebeat.visualization import plot_multiple_sequences

test_sequence = Sequence(iois=[470, 530, 500], name="Test")
reference_sequence = Sequence(iois=[500, 500, 500], name="Reference")

plot_multiple_sequences([test_sequence, reference_sequence], figsize=(8, 3));
../../_images/examples_tipstricks_warnings_25_0.png

Because we create the sequences using IOIs, for both sequences the first event onset is at t=0 (see thebeat.core.Sequence.__init__()). If we then plot or calculate the phase differences we would always get a phase difference of 0, which is not very informative, so we get a warning, like below:

[32]:
from thebeat.visualization import plot_phase_differences

plot_phase_differences(test_sequence=test_sequence,
                       reference_sequence=reference_sequence);
/Users/jellevanderwerff/thebeat-package/thebeat/utils.py:203: Warning: thebeat: The first onset of the test sequence was at t=0.
This would result in a phase difference that is always 0, which is not very informative.
Therefore, the first phase difference was discarded.
If you want the first onset at a different time than zero, use the Sequence.from_onsets() method to create the Sequence object.

  warnings.warn(phases_t_at_zero)
../../_images/examples_tipstricks_warnings_27_1.png

What is the solution?#

Likely, you’re comparing e.g. stimulus and response finger-tapping data. When creating the test_sequence sequences, use the from_onsets() class method to construct the objects, rather than IOIs, as below:

[33]:
test_sequence = Sequence.from_onsets([50, 550, 1031, 1500], name="Test")
plot_multiple_sequences([test_sequence, reference_sequence], figsize=(8, 3));
../../_images/examples_tipstricks_warnings_30_0.png

Now we can plot the phase differences and not get the warning:

[34]:
plot_phase_differences(test_sequence=test_sequence,
                       reference_sequence=reference_sequence);
../../_images/examples_tipstricks_warnings_32_0.png

Getting rid of a specific warning#

While it is better to find the cause of the warning and to solve it there, during development it might be frustrating to get these warnings, especially if you they are not relevant to your situation. To disable a specific warning use the message attribute in `warnings.filterwarnings() <https://docs.python.org/3/library/warnings.html#warnings.filterwarnings>`__. You don’t have to type the whole message, just part of it, for instance:

[35]:
import warnings
warnings.filterwarnings('ignore', message="thebeat: For one or more of the used sounds")

Getting rid of all of thebeat’s warnings#

All of thebeat’s warnings start with the message ‘thebeat’. You can that contain a specific message, like below:

[36]:
import warnings
warnings.filterwarnings('ignore', message="thebeat: ")

Resetting warnings#

To reset the warnings back to their original behaviour, use:

[37]:
warnings.resetwarnings()