def _decode_post(post, stay_pen=0.0, skip_pen=0.0, local_pen=2.0, use_slip=False): """Decode a posterior using Viterbi algorithm for transducer. :param post: a `ScrappyMatrix` containing transducer posteriors. :param stay_pen: penalty for staying. :param skip_pen: penalty for skipping a base. :param local_pen: penalty for local basecalling. :param use_slip: allow slipping (movement more than 2 bases). :returns: tuple containing (call, score, call positions per raw block). """ nblock, nstate = post.shape path = ffi.new("int[{}]".format(nblock + 1)) score = lib.decode_transducer(post.data(), stay_pen, skip_pen, local_pen, path, use_slip) pos = np.zeros(nblock + 1, dtype=np.int32) p_pos = ffi.cast("int *", pos.ctypes.data) basecall = lib.overlapper(path, nblock + 1, nstate - 1, p_pos) return ffi.string(basecall).decode(), score, pos
def _decode_post_crf(post): """Decode a posterior using Viterbi algorithm for conditional random field. :param post: a `ScrappyMatrix` containing CRF transitions. :returns: tuple containing (basecall, score, call positions per raw data block). """ nblock, nstate = post.shape path = ffi.new("int[{}]".format(nblock + 1)) score = lib.decode_crf(post.data(), path) pos = np.ascontiguousarray(np.zeros(nblock + 1, dtype=np.int32)) p_pos = ffi.cast("int *", ffi.from_buffer(pos)) basecall = lib.crfpath_to_basecall(path, nblock, p_pos) return ffi.string(basecall).decode(), score, pos