Skip to content

Commit

Permalink
use nb_std to save .005 second, provide fallback @Profile decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
happycube committed Jun 10, 2023
1 parent 5dab680 commit 4b284c4
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 15 deletions.
41 changes: 26 additions & 15 deletions lddecode/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from .utils import LRUupdate, clb_findbursts, angular_mean, phase_distance
from .utils import build_hilbert, unwrap_hilbert, emphasis_iir, filtfft
from .utils import fft_do_slice, fft_determine_slices, StridedCollector, hz_to_output_array
from .utils import Pulse
from .utils import Pulse, nb_std, nb_gt

try:
# If Anaconda's numpy is installed, mkl will use all threads for fft etc
Expand All @@ -44,6 +44,12 @@
# and ld-decode. Probably should just bring all logging in here...
logger = None

try:
profile
except:
def profile(fn):
return fn


def calclinelen(SP, mult, mhz):
if type(mhz) == str:
Expand Down Expand Up @@ -1497,7 +1503,7 @@ def __init__(
# this is eventually set to 262/263 and 312/313 for audio timing
self.linecount = None

@profile
#@profile
def process(self):
self.linelocs1, self.linebad, self.nextfieldoffset = self.compute_linelocs()
#print(self.readloc, self.linelocs1, self.nextfieldoffset)
Expand Down Expand Up @@ -1553,7 +1559,6 @@ def usectoinpx(self, x, line=None):
def inpxtousec(self, x, line=None):
return x / self.get_linefreq(line)

@profile
def lineslice(self, l, begin=None, length=None, linelocs=None, begin_offset=0):
""" return a slice corresponding with pre-TBC line l, begin+length are uSecs """

Expand Down Expand Up @@ -1604,7 +1609,7 @@ def output_to_ire(self, output):
(output - self.rf.SysParams["outputZero"]) / self.out_scale
) + self.rf.DecoderParams["vsync_ire"]

@profile

def lineslice_tbc(self, l, begin=None, length=None, linelocs=None, keepphase=False):
""" return a slice corresponding with pre-TBC line l """

Expand All @@ -1623,7 +1628,7 @@ def lineslice_tbc(self, l, begin=None, length=None, linelocs=None, keepphase=Fal

return slice(nb_round(_begin), nb_round(_begin + _length))

@profile

def get_timings(self):
pulses = self.rawpulses
hsync_typical = self.usectoinpx(self.rf.SysParams["hsyncPulseUS"])
Expand Down Expand Up @@ -1688,7 +1693,7 @@ def pulse_qualitycheck(self, prevpulse: Pulse, pulse: Pulse):

return inorder

@profile
#@profile
def run_vblank_state_machine(self, pulses, LT):
""" Determines if a pulse set is a valid vblank by running a state machine """

Expand Down Expand Up @@ -1779,7 +1784,7 @@ def run_vblank_state_machine(self, pulses, LT):

return done, validpulses

@profile
#@profile
def refinepulses(self):
LT = self.get_timings()

Expand Down Expand Up @@ -1819,7 +1824,7 @@ def refinepulses(self):

return valid_pulses

@profile
#@profile
def getBlankRange(self, validpulses, start=0):
vp_type = np.array([p[0] for p in validpulses])

Expand Down Expand Up @@ -1960,7 +1965,7 @@ def processVBlank(self, validpulses, start, limit=None):

return None, None, None, 0

@profile
#@profile
def computeLineLen(self, validpulses):
# determine longest run of 0's
longrun = [-1, -1]
Expand Down Expand Up @@ -2026,7 +2031,7 @@ def skip_check(self):
# pull the above together into a routine that (should) find line 0, the last line of
# the previous field.

@profile
#@profile
def getLine0(self, validpulses, meanlinelen):
# Gather the local line 0 location and projected from the previous field

Expand Down Expand Up @@ -2189,7 +2194,7 @@ def getpulses(self):

return findpulses(self.data["video"]["demod_05"], pulse_hz_min, pulse_hz_max)

@profile
#@profile
def compute_linelocs(self):

self.rawpulses = self.getpulses()
Expand Down Expand Up @@ -2348,7 +2353,7 @@ def compute_linelocs(self):

return rv_ll, rv_err, nextfield

@profile
#@profile
def refine_linelocs_hsync(self):
linelocs2 = self.linelocs1.copy()

Expand Down Expand Up @@ -2541,6 +2546,7 @@ def downscale(

return dsout, self.dsaudio, self.efmout

@profile
def rf_tbc(self, linelocs=None):
""" This outputs a TBC'd version of the input RF data, mostly intended
to assist in audio processing. Outputs a uint16 array.
Expand Down Expand Up @@ -2645,13 +2651,14 @@ def get_vsync_lines(self):

return rv

@profile
def dropout_detect_demod(self):
# current field
f = self

isPAL = self.rf.system == "PAL"

rfstd = np.std(f.data["rfhpf"])
rfstd = nb_std(f.data["rfhpf"])
# iserr_rf = np.full(len(f.data['video']['demod']), False, dtype=np.bool)
iserr_rf1 = (f.data["rfhpf"] < (-rfstd * 3)) | (
f.data["rfhpf"] > (rfstd * 3)
Expand All @@ -2663,6 +2670,7 @@ def dropout_detect_demod(self):

# detect absurd fluctuations in pre-deemp demod, since only dropouts can cause them
# (current np.diff has a prepend option, but not in ubuntu 18.04's version)
#iserr1 = nb_gt(f.data["video"]["demod_raw"], self.rf.freq_hz_half)
iserr1 = f.data["video"]["demod_raw"] > self.rf.freq_hz_half
# This didn't work right for PAL (issue #471)
# iserr1 |= f.data['video']['demod_hpf'] > 3000000
Expand Down Expand Up @@ -2713,6 +2721,7 @@ def dropout_detect_demod(self):

return iserr

@profile
def build_errlist(self, errmap):
errlist = []

Expand All @@ -2733,6 +2742,7 @@ def build_errlist(self, errmap):

return errlist

@profile
def dropout_errlist_to_tbc(field, errlist):
"""Convert data from raw data coordinates to tbc coordinates, and splits up
multi-line dropouts.
Expand Down Expand Up @@ -2799,6 +2809,7 @@ def dropout_errlist_to_tbc(field, errlist):

return dropouts

@profile
def dropout_detect(self):
""" returns dropouts in three arrays, to line up with the JSON output """

Expand Down Expand Up @@ -3584,7 +3595,7 @@ def writeout(self, dataset):
if audio is not None and self.outfile_audio is not None:
self.outfile_audio.write(audio)

#@profile
@profile
def decodefield(self, initphase=False, redo=False):
""" returns field object if valid, and the offset to the next decode """
self.readloc = int(self.fdoffset - self.rf.blockcut)
Expand Down Expand Up @@ -3642,7 +3653,7 @@ def decodefield(self, initphase=False, redo=False):

return f, f.nextfieldoffset - (self.readloc - self.rawdecode["startloc"])

#@profile
@profile
def readfield(self, initphase=False):
# pretty much a retry-ing wrapper around decodefield with MTF checking
self.prevfield = self.curfield
Expand Down
50 changes: 50 additions & 0 deletions lddecode/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,51 @@ def findpulses(sync_ref, _, high):
)
return _to_pulses_list(pulses_starts, pulses_lengths)

if False:
@njit(cache=True,nogil=True)
def numba_pulse_qualitycheck(prevpulse: Pulse, pulse: Pulse, inlinelen: int):

if prevpulse[0] > 0 and pulse[0] > 0:
exprange = (0.4, 0.6)
elif prevpulse[0] == 0 and pulse[0] == 0:
exprange = (0.9, 1.1)
else: # transition to/from regular hsyncs can be .5 or 1H
exprange = (0.4, 1.1)

linelen = (pulse[1].start - prevpulse[1].start) / inlinelen
inorder = inrange(linelen, *exprange)

return inorder

@njit(cache=True,nogil=True)
def numba_computeLineLen(validpulses, inlinelen):
# determine longest run of 0's
longrun = [-1, -1]
currun = None
for i, v in enumerate([p[0] for p in validpulses]):
if v != 0:
if currun is not None and currun[1] > longrun[1]:
longrun = currun
currun = None
elif currun is None:
currun = [i, 0]
else:
currun[1] += 1

if currun is not None and currun[1] > longrun[1]:
longrun = currun

linelens = []
for i in range(longrun[0] + 1, longrun[0] + longrun[1]):
linelen = validpulses[i][1].start - validpulses[i - 1][1].start
if inrange(linelen / inlinelen, 0.95, 1.05):
linelens.append(
validpulses[i][1].start - validpulses[i - 1][1].start
)

# Can't prepare the mean here since numba np.mean doesn't work over lists
return linelens


@njit(cache=True, nogil=True)
def findpeaks(array, low=0):
Expand Down Expand Up @@ -1007,6 +1052,11 @@ def nb_where(x):
return np.where(x)


@njit(cache=True,nogil=True)
def nb_gt(x, y):
return (x > y)


@njit(cache=True,nogil=True)
def n_orgt(a, x, y):
a |= (x > y)
Expand Down

0 comments on commit 4b284c4

Please sign in to comment.