From 2c00ad8df50a7ae36ee4b0f78b4796af128ea268 Mon Sep 17 00:00:00 2001 From: Coda Phillips <cphillips@sean.ssec.wisc.edu> Date: Thu, 30 Jun 2016 14:16:38 -0500 Subject: [PATCH] Add qc_notes column --- electronic_checks.py | 3 +++ main.py | 43 +++++++++++++++++++++++++++++++++++++-- scene_checks.py | 12 +++++++---- state_checks.py | 9 ++++++--- test.py | 26 +++++++++++++++++++++++- util.py | 48 +++++++++++++++++++++++++------------------- 6 files changed, 110 insertions(+), 31 deletions(-) diff --git a/electronic_checks.py b/electronic_checks.py index 5761ff3..2f65033 100644 --- a/electronic_checks.py +++ b/electronic_checks.py @@ -68,6 +68,7 @@ def test_hbb_temp_outlier_check(): 'HBBapexTemp':[0,1,10,1], 'HBBbottomTemp':[1,1,1,1], 'HBBtopTemp':[0,1,10,1], + 'qc_notes':'' }) assert hbb_temp_outlier_check(frame, {})['hbb_temp_outlier_check'].values.tolist() == [0,0,1,0] @@ -76,11 +77,13 @@ def test_abb_temp_outlier_check(): 'ABBapexTemp':[0,1,10,1], 'ABBbottomTemp':[1,1,1,1], 'ABBtopTemp':[0,1,10,1], + 'qc_notes':'' }) assert abb_temp_outlier_check(frame, {})['abb_temp_outlier_check'].values.tolist() == [0,0,1,0] def test_calibrationambienttemp_temp_outlier_check(): frame = pd.DataFrame({ 'calibrationAmbientTemp':[0,1,10,1], + 'qc_notes':'' }) assert calibrationambienttemp_outlier_check(frame, {})['calibrationambienttemp_outlier_check'].values.tolist() == [0,0,1,0] diff --git a/main.py b/main.py index 497bd77..e6df9e0 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,8 @@ +import os +from glob import glob +import re +#from aeri_tools.io.dmv.housekeeping import get_all_housekeeping + import electronic_checks import global_checks import radiometric_checks @@ -14,12 +19,46 @@ levels = [ thermal_checks.CheckList() ] -def read_frame(path): - pass +def read_frame(cxs_file, sum_file): + return get_all_housekeeping(cxs_file).combine_first( + get_all_housekeeping(sum_file)) def check_frame(frame, parameters): frame['qc_percent'] = 0 + frame['qc_notes'] = None for level in levels: level.set_params(parameters) frame = level.compute(frame) return frame + +def update_all(ftp_dir, parameters=None): + cxs_files = glob(os.path.join(ftp_dir,'AE*','*B1.CXS')) + for qc_file, cxs_file, sum_file in files_to_update(cxs_files): + hk = read_frame(cxs_file, sum_file) + if parameters is None: + parameters = {} + check_frame(frame, parameters) + +def files_to_update(cxs_files): + for cxs_file in cxs_files: + possible_sum = os.path.join(os.path.dirname(cxs_file), cxs_file.replace('B1.CXS','.SUM')) + possible_qc = os.path.join(os.path.dirname(cxs_file), cxs_file.replace('B1.CXS','.qc')) + + if os.path.isfile(possible_sum): + sum_file = possible_sum + + if os.path.isfile(possible_qc): + qc_file = possible_qc + if max(os.path.getmtime(sum_file), os.path.getmtime(cxs_file)) > os.path.getmtime(qc_file): + yield (qc_file, cxs_file, sum_file) + else: + yield (qc_file, cxs_file, sum_file) + +if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('ftp') + + args = parser.parse_args() + + update_all(args.ftp) diff --git a/scene_checks.py b/scene_checks.py index 8a3fe88..e974f33 100644 --- a/scene_checks.py +++ b/scene_checks.py @@ -42,13 +42,15 @@ class CheckList(BaseCheckList): def test_hatch_check(): frame = pd.DataFrame({ 'hatchOpen':[1,1,0], - 'sceneMirrorPosition':[ord('H'), ord('A'), ord('S')] + 'sceneMirrorPosition':[ord('H'), ord('A'), ord('S')], + 'qc_notes':'' }) assert hatch_check(frame, {})['hatch_check'].values.tolist() == [0,0,1] frame = pd.DataFrame({ 'hatchOpen':[1,0,1], - 'sceneMirrorPosition':[ord('H'), ord('A'), ord('S')] + 'sceneMirrorPosition':[ord('H'), ord('A'), ord('S')], + 'qc_notes':'' }) assert hatch_check(frame, {})['hatch_check'].values.tolist() == [0,0,0] @@ -56,13 +58,15 @@ def test_hatch_check(): def test_safing_check(): frame = pd.DataFrame({ 'hatchOpen':[0,0,0], - 'sceneMirrorPosition':[ord('H'), ord('A'), ord('S')] + 'sceneMirrorPosition':[ord('H'), ord('A'), ord('S')], + 'qc_notes':'' }) assert safing_check(frame, {})['safing_check'].values.tolist() == [0,0,0] frame = pd.DataFrame({ 'hatchOpen':[1,-3,0,0], - 'sceneMirrorPosition':[ord('S'), ord('H'), ord('A'), ord('S')] + 'sceneMirrorPosition':[ord('S'), ord('H'), ord('A'), ord('S')], + 'qc_notes':'' }) assert safing_check(frame, {})['safing_check'].values.tolist() == [1,1,0,1] diff --git a/state_checks.py b/state_checks.py index df3f374..b852123 100644 --- a/state_checks.py +++ b/state_checks.py @@ -40,7 +40,8 @@ def test_hbb_thermistor_check(): 'HBBbottomTemp':[300,333,336], 'HBBapexTemp':[300,333,336], 'HBBtopTemp':[300,333,336], - 'sceneMirrorPosition':[ord('H'), ord('A'), ord('S')] + 'sceneMirrorPosition':[ord('H'), ord('A'), ord('S')], + 'qc_notes':'' }), {}) assert all(frame['hbb_thermistor_check'] == [1,0,1]) @@ -49,14 +50,16 @@ def test_hbb_thermistor_check2(): 'HBBbottomTemp':[300,333,333], 'HBBapexTemp':[300,333,333], 'HBBtopTemp':[300,333,333], - 'sceneMirrorPosition':[ord('H'), ord('A'), ord('S')] + 'sceneMirrorPosition':[ord('H'), ord('A'), ord('S')], + 'qc_notes':'' }), {}) assert all(frame['hbb_thermistor_check'] == [1,0,1]) def test_detector_check(): frame = detector_check(pd.DataFrame({ 'detectorTemp':[50,100], - 'sceneMirrorPosition':[ord('H'), ord('A')] + 'sceneMirrorPosition':[ord('H'), ord('A')], + 'qc_notes':'' }), {}) assert all(frame['detector_check'] == [0,1]) diff --git a/test.py b/test.py index 5e759c1..ce085cc 100644 --- a/test.py +++ b/test.py @@ -27,6 +27,7 @@ def test_invalidate_record(): corrupt_cal = three_scenes.copy() invalidated = invalidate_record(corrupt_cal, 3, 'test', .5) assert invalidated.iloc[2].test == .5, invalidated.test + assert invalidated.iloc[4].test != .5, invalidated.test assert invalidated.iloc[5].test == .5, invalidated.test @@ -37,6 +38,29 @@ def test_invalidate_records(): invalidated = invalidate_records(corrupt_cal, 'test') assert invalidated.iloc[2].test == 1, invalidated.test + assert invalidated.iloc[4].test == 0, invalidated.test assert invalidated.iloc[5].test == 1, invalidated.test -three_scenes = pd.DataFrame({'sceneMirrorPosition': list(map(ord, 'HASAHSAHSAH'))}) +def test_invalidate_record_and_annotate(): + invalidated = invalidate_record(three_scenes.copy(), 2, 'test', .5, 'test annotation') + assert invalidated.iloc[2].test == .5 + assert pd.np.isnan(invalidated.iloc[3].test) + assert pd.np.isnan(invalidated.iloc[1].test) + assert invalidated.iloc[2].qc_notes == 'test annotation' + + tricky_index = three_scenes.copy() + tricky_index.index = tricky_index.index - 1 + invalidated = invalidate_record(tricky_index, 2, 'test', .5, 'test annotation') + assert invalidated.iloc[2].test == .5, invalidated.test + assert pd.np.isnan(invalidated.iloc[3].test) + assert pd.np.isnan(invalidated.iloc[1].test) + assert invalidated.iloc[2].qc_notes == 'test annotation' + + corrupt_cal = three_scenes.copy() + invalidated = invalidate_record(corrupt_cal, 3, 'test', .5) + assert invalidated.iloc[2].test == .5, invalidated.test + assert invalidated.iloc[2].qc_notes == 'invalid calibration:3' + assert invalidated.iloc[5].test == .5, invalidated.test + assert invalidated.iloc[5].qc_notes == 'invalid calibration:3' + +three_scenes = pd.DataFrame({'sceneMirrorPosition': list(map(ord, 'HASAHSAHSAH')), 'qc_notes':''}) diff --git a/util.py b/util.py index a99954c..8269df5 100644 --- a/util.py +++ b/util.py @@ -7,39 +7,45 @@ def invalidate_records(frame, check_name): invalidate_record(frame, index, check_name, percent) return frame -def invalidate_record(frame, index, check_name, value): +def invalidate_record(frame, index, check_name, value, annotation=''): frame.ix[frame.index[index], check_name] = value + if annotation: + if frame.ix[frame.index[index], 'qc_notes']: + frame.ix[frame.index[index], 'qc_notes'] = ','.join([frame.ix[frame.index[index],'qc_notes'], annotation]) + else: + frame.ix[frame.index[index], 'qc_notes'] = annotation + corrupt_view = frame.iloc[index].sceneMirrorPosition if corrupt_view in [ord('H'),ord('A')]: + + def invalidate_neighbor(neighbor): + if frame.sceneMirrorPosition.iloc[neighbor] == corrupt_view: + # Made one cycle, break + return True + elif frame.sceneMirrorPosition.iloc[neighbor] in [ord('H'), ord('A')]: + # Skip opposite calibration views + return + else: + # Invalidate non-calibration views + frame.ix[frame.index[neighbor], check_name] = value + previous_notes = frame.ix[frame.index[neighbor], 'qc_notes'] + if previous_notes: + frame.ix[frame.index[neighbor], 'qc_notes'] = ','.join([previous_notes, 'invalid calibration:{:d}'.format(index)]) + else: + frame.ix[frame.index[neighbor], 'qc_notes'] = 'invalid calibration:{:d}'.format(index) # Corrupt calibration view, must also invalidate neighboring scenes _idx = index + 1 while _idx < len(frame): - if frame.sceneMirrorPosition.iloc[_idx] == corrupt_view: - # Made one cycle + if invalidate_neighbor(_idx): break - elif frame.sceneMirrorPosition.iloc[_idx] in [ord('H'), ord('A')]: - # Skip opposite calibration views - _idx += 1 - continue - else: - # Invalidate non-calibration views - frame.ix[frame.index[_idx], check_name] = value - _idx += 1 + _idx += 1 _idx = index - 1 while _idx >= 0: - if frame.sceneMirrorPosition.iloc[_idx] == corrupt_view: - # Made one cycle + if invalidate_neighbor(_idx): break - elif frame.sceneMirrorPosition.iloc[_idx] in [ord('H'), ord('A')]: - # Skip opposite calibration views - _idx -= 1 - continue - else: - # Invalidate non-calibration views - frame.ix[frame.index[_idx], check_name] = value - _idx -= 1 + _idx -= 1 return frame -- GitLab