Skip to content

Commit

Permalink
Merge pull request #54 from BirdVox/export-context
Browse files Browse the repository at this point in the history
Export context
  • Loading branch information
Vincent Lostanlen authored Jul 24, 2020
2 parents 54c1916 + 33f2054 commit b867458
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 3 deletions.
38 changes: 36 additions & 2 deletions birdvoxdetect/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def process_file(
output_dir=None,
export_clips=False,
export_confidence=False,
export_context=False,
export_faults=False,
export_logger=False,
threshold=50.0,
Expand Down Expand Up @@ -223,10 +224,14 @@ def process_file(
if not os.path.exists(clips_dir):
os.makedirs(clips_dir)

# Append confidence to list of per-chunk confidences.
# Initialize list of per-chunk confidences.
if export_confidence:
chunk_confidences = []

# Initialize list of context arrays.
if export_context:
contexts = []

# Print chunk duration.
logger.info("Chunk duration: {} seconds".format(chunk_duration))
logger.info("")
Expand Down Expand Up @@ -254,6 +259,10 @@ def process_file(
deque_context = np.percentile(
concat_deque, percentiles, axis=1, overwrite_input=True)

# Append context.
if export_context:
contexts.append(deque_context)

# Compute sensor fault features.
# Median is 4th order statistic. Restrict to lowest 120 mel-freq bins
context_median = deque_context[4, :120]
Expand Down Expand Up @@ -415,6 +424,10 @@ def process_file(
concat_deque, percentiles,
axis=1, out=deque_context, overwrite_input=True)

# Append context.
if export_context:
contexts.append(deque_context)

# Compute sensor fault features.
# Median is 4th order statistic. Restrict to lowest 120 mel-freq bins
context_median = deque_context[4, :120]
Expand Down Expand Up @@ -580,7 +593,7 @@ def process_file(
chunk_confidence_length = int(frame_rate*full_length/sr)
chunk_confidence = np.full(chunk_confidence_length, np.nan)

if has_context and (n_chunks==1):
if (export_context or has_context) and (n_chunks==1):
deque_context = np.percentile(
chunk_pcen, percentiles, axis=1, overwrite_input=True)
logging.warning(
Expand All @@ -601,6 +614,9 @@ def process_file(
concat_deque, percentiles,
axis=1, out=deque_context, overwrite_input=True)

# Append context.
if export_context:
contexts.append(deque_context)

if not has_sensor_fault:
# Define trimming length for last chunk.
Expand Down Expand Up @@ -734,6 +750,21 @@ def process_file(
# Increment pointer.
chunk_pointer = next_chunk_pointer

# Export context.
if export_context:
# Define output path for context.
context_path = get_output_path(
filepath, suffix + "context.hdf5", output_dir=output_dir)

# Stack context over time.
context_array = np.stack(contexts, axis=0)

# Export context.
with h5py.File(context_path, "w") as f:
f["context"] = context_array
f["chunk_duration"] = chunk_duration
f["frame_rate"] = frame_rate

# Print final messages.
if threshold is not None:
df = pd.read_csv(checklist_path)
Expand All @@ -747,6 +778,9 @@ def process_file(
if export_confidence:
event_str = "The event detection curve is available at: {}"
logger.info(event_str.format(confidence_path))
if export_context:
event_str = "The context array is available at: {}"
logger.info(event_str.format(context_path))
if export_faults:
event_str = "The list of sensor faults is available at: {}"
logger.info(event_str.format(faultlist_path))
Expand Down
2 changes: 1 addition & 1 deletion birdvoxdetect/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
short_version = '0.2'
version = '0.3.0a3'
version = '0.3.0a4'
13 changes: 13 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,19 @@ def test_process_file():
assert confidence.shape == (199,)
shutil.rmtree(tmpdir)

# export context
tmpdir = tempfile.mkdtemp()
process_file(
os.path.join(TEST_AUDIO_DIR, POSITIVE_MD5 + '.wav'),
output_dir=tmpdir,
export_context=True)
context_path = os.path.join(
tmpdir, POSITIVE_MD5 + '_context.hdf5')
assert os.path.exists(context_path)
with h5py.File(context_path, "r") as f:
confidence = f["context"][()]
shutil.rmtree(tmpdir)

# export list of sensor faults
tmpdir = tempfile.mkdtemp()
process_file(
Expand Down

0 comments on commit b867458

Please sign in to comment.