Conversation
…ot detected correctly
|
|
||
| # if there are multiple candidates, take the one with the highest cross correlation | ||
| if len(candidates) == 1: | ||
| lag = candidates[0] |
There was a problem hiding this comment.
Would lag = candidates[0] always select the highest cross correlation or is the first in the list of candidates not necessarily always the highest?
There was a problem hiding this comment.
I expect only 1 or 2 candidates ever, because the search space is two breath lengths around the peak of the global timing.
Let's say a breath is 50 frames long. If there is no lag, there will be a peak at -50 (one breath ahead), 0 (the current breath) and 50 (the next breath). The peak detection won't detect peaks that are at the edges due to prominence requirement (peaks have to stick out a minimum above their surroundings; without surroundings, they are not detected). So in that case, only the middle one (at 0) will be detected.
If lag is very low, then the edge peaks still won't be detected, and only the peak near 0 will be detected, due to prominence requirements.
In the case there is more lag, let's say 15, there will be a peak at -35 and 15 (the one at -85 and 65 are outside the search space). The peak at 15 is closest, so that one will be chosen.
The extreme case is when the lag is exactly half the breath (a phase shift of 180 degrees). There is a peak at -25 and one at 25. The timing does not inform us on which one is most probably the related one. In that case, we choose the one with the highest peak, because that indicates better cross correlation between those peaks.
| # take the lag with the highest cross correlation | ||
| lag = candidates[np.argmax(xcorr[np.searchsorted(lags, candidates)])] | ||
| else: | ||
| msg = "Too many peaks found in cross correlation." |
There was a problem hiding this comment.
For my understanding, you would expect 2 peaks if the lag is similar to left as to right, correct? What could be an explanation for more than 2 peaks found?
There was a problem hiding this comment.
There can never be more than two. The candidates indicate peaks with the shortest distance to 0. This can either be a peak before 0 or after 0. So unless scipy.find_peaks makes a mistake, this should never trigger. However, just to be sure, I do check for a length of 2.
PixelBreath skipped entire pixels if only a single breath in a period could not be matched. However, in longer datasets, it is better to skip a few breaths than to fail entirely.
Also, PixelBreath chose single pixel lag based on the maximum cross correlation within 0.75 breaths. This works well if the signal is long and regular, but less so for shorter or slightly irregular data. In this update, PixelBreath detects peaks in the cross correlation signal, and finds the peak that is closest. Only if two peaks have equal distance, the highest value is used.
These issues are difficult to test, other than during real life analysis. No additional tests have been added.