; The purpose of this program is to check the FOM structure to make sure that ; it is within acceptable boundaries for submission to the SOC. ; Additionally, we will provide warnings to the user when the FOM values or ; number of buffers starts to reach "unusually large" values, as defined ; by the error tables within this program. ; The errors and warnings will be reported in two ways: a flags array and ; a warnings array, each of which will have the same number of elements. ; Each element of these arrays will correspond to a different test in ; the warning/error tables. The 'flags' array will have either a value of '0' ; (passed) or '1' (failed), where 'failed" implies there is an error. This ; will be for internal use within EVA. The 'messages' array will contain a ; corresponding error message for each element of the flags array, allowing ; ease of use within EVA to print the messages for the user. ; We need a series of errors and warnings ; I'll make a structure which includes different error classes ; the elements of each sub-array will be the indices of the FOM_str ; where we have errors. ; --------------------------------------- ; ERRORS ; ; Seg_size ; ; ;---------------------------------------- pro mms_check_fom_structure, new_fomstr, old_fomstr, error_flags, orange_warning_flags, $ yellow_warning_flags, error_msg, orange_warning_msg, yellow_warning_msg, $ error_times, orange_warning_times, yellow_warning_times, $ error_indices, orange_warning_indices, yellow_warning_indices, $ valstruct=valstruct ; Define parameters that lead to errors and warnings on_error, 2 if n_elements(valstruct) eq 0 then valstruct = mms_load_fom_validation() if typename(valstruct) eq 'INT' then message, 'ERROR: Unable to load FOM validation parameters ' + $ 'from SDC. Check your internet connection.' fom_gmax = valstruct.fom_gmax fom_bounds = valstruct.fom_bounds seg_bounds = valstruct.seg_bounds buff_max = valstruct.buff_max p1_percent = valstruct.p1_percent nominal_seg_range = valstruct.nominal_seg_range type1_range = valstruct.type1_range type2_range = valstruct.type2_range type3_range = valstruct.type3_range type4_range = valstruct.type4_range fom_min_str = strtrim(string(fom_bounds(0)), 2) fom_max_str = strtrim(string(fom_bounds(1)), 2) fom_gmax_str = strtrim(string(fom_gmax), 2) buff_max_str = strtrim(string(buff_max), 2) seg_min_str = strtrim(string(seg_bounds(0)), 2) seg_max_str = strtrim(string(seg_bounds(1)), 2) nom_seg_min_str = strtrim(string(nominal_seg_range(0)), 2) nom_seg_max_str = strtrim(string(nominal_seg_range(1)), 2) ;---------------------------------------------------------------------------- ; Define error arrays ;---------------------------------------------------------------------------- old_evaltime = old_fomstr.metadataevaltime new_evaltime = new_fomstr.metadataevaltime loc_fom_error = where(new_fomstr.fom lt fom_bounds(0) or new_fomstr.fom gt fom_bounds(1), count_fom_error) loc_seg_error = where(new_fomstr.seglengths lt seg_bounds(0) or new_fomstr.seglengths gt seg_bounds(1), $ count_seg_error) loc_start_error = where(new_fomstr.start gt new_fomstr.stop, count_start_error) error_flags = [count_fom_error gt 0, $ count_seg_error gt 0, $ count_start_error gt 0, $ new_evaltime ne old_evaltime] error_times = ptrarr(n_elements(error_flags), /allocate_heap) error_indices = ptrarr(n_elements(error_flags), /allocate_heap) ; Generate strings that represent the errors ; First, we need to get the appropriate times if count_fom_error gt 0 then begin fom_error_times = strarr(count_fom_error) convert_time_stamp, new_fomstr.cyclestart, new_fomstr.start(loc_fom_error), fom_error_times endif else begin fom_error_times = '' endelse if count_seg_error gt 0 then begin seg_error_times = strarr(count_seg_error) convert_time_stamp, new_fomstr.cyclestart, new_fomstr.start(loc_seg_error), seg_error_times endif else begin seg_error_times = '' endelse if count_start_error gt 0 then begin start_error_times = strarr(count_start_error) convert_time_stamp, new_fomstr.cyclestart, new_fomstr.start(loc_start_error), start_error_times endif else begin start_error_times = '' endelse ; Now we create the warnings that will actually be output fom_error_txt = 'ERROR: FOM value at following times out of bounds (' + fom_min_str + $ ' to ' + fom_max_str + '): ' seg_error_txt = 'ERROR: Segment lengths at following times out of bounds (' + $ seg_min_str + ' to ' + seg_max_str + '): ' start_error_txt = 'ERROR: Start time must be less than stop time for following selections: ' eval_error_txt = 'ERROR: The evaluation times for the automated system and SITL selections do not match!' error_msg = [fom_error_txt, $ seg_error_txt, $ start_error_txt, $ eval_error_txt] ; Provides a list of time strings, as well as array indices for the fomstr.start where errors were found *(error_times[0]) = fom_error_times *(error_times[1]) = seg_error_times *(error_times[2]) = start_error_times *(error_times[3]) = 'Orbit-wide error - no error times' *(error_indices[0]) = loc_fom_error *(error_indices[1]) = loc_seg_error *(error_indices[2]) = !values.f_nan *(error_indices[3]) = loc_start_error ;------------------------------------------------------------------------------ ; Define orange warning arrays ;------------------------------------------------------------------------------ loc_fom_approve = where(new_fomstr.fom gt fom_gmax, count_fom_appr) ;loc_fom_percentage = orange_warning_flags = [count_fom_appr gt 0, $ total(new_fomstr.seglengths) gt buff_max] orange_warning_times = ptrarr(n_elements(orange_warning_flags), /allocate_heap) orange_warning_indices = ptrarr(n_elements(orange_warning_flags), /allocate_heap) ; Create time array for warnings if count_fom_appr gt 0 then begin fom_appr_times = strarr(count_fom_appr) convert_time_stamp, new_fomstr.cyclestart, new_fomstr.start(loc_fom_approve), fom_appr_times endif else begin fom_appr_times = '' endelse Appr_msg = 'Submission needs SuperSITL Approval! ' fom_gwarning_txt = Appr_msg + 'FOM value at the following times exceeds recommended value (' + fom_gmax_str + ') and should ' + $ 'be reserved for the highest priority events or FPI calibrations: ' buff_warning_txt = Appr_msg + 'Number of buffers exceeds maximum (' + buff_max_str + ')!' orange_warning_msg = [fom_gwarning_txt, $ buff_warning_txt] (*orange_warning_times[0]) = fom_appr_times (*orange_warning_times[1]) = 'Orbit-wide error - no error times' (*orange_warning_indices[0]) = loc_fom_approve (*orange_warning_indices[1]) = !values.f_nan ;----------------------------------------------------------------------------- ; Define yellow warnings ;----------------------------------------------------------------------------- ; Note - also makes sure segment isn't already in error. loc_seg_warning = where((new_fomstr.seglengths lt nominal_seg_range(0) $ or new_fomstr.seglengths gt nominal_seg_range(1)) and $ (new_fomstr.seglengths ge seg_bounds(0) and new_fomstr.seglengths le seg_bounds(1)), $ count_seg_warning) ; Now check the number of buffers with priority 1 events loc_p1 = where(new_fomstr.fom ge type1_range(0) and new_fomstr.fom lt type1_range(1), count_p1) if count_p1 gt 0 then begin num_p1_buffs = total(new_fomstr.seglengths(loc_p1)) endif else begin num_p1_buffs = 0 endelse ; Create time array for warnings if count_seg_warning gt 0 then begin seg_warning_times = strarr(count_seg_warning) convert_time_stamp, new_fomstr.cyclestart, new_fomstr.start(loc_seg_warning), seg_warning_times endif else begin seg_warning_times = '' endelse seg_warning_text = 'Warning - segment lengths outside of nominal bounds (' + $ nom_seg_min_str + ' to ' + nom_seg_max_str + $ ') at the following time_stamps, requires justification: ' p1_warning_text = 'Warning - number of buffers with priority 1 events larger than nominal. Priority 1 events are reserved for ' + $ 'the events most likely to be diffusion region crossings. This selection requires justification!' yellow_warning_flags = [count_seg_warning gt 0, $ num_p1_buffs/buff_max gt p1_percent/100.] yellow_warning_times = ptrarr(n_elements(yellow_warning_flags), /allocate_heap) yellow_warning_indices = ptrarr(n_elements(yellow_warning_flags), /allocate_heap) yellow_warning_msg = [seg_warning_text, $ p1_warning_text] ; Now we are going to pass this into our new submit fom structure - it should get rejected (*yellow_warning_times[0]) = seg_warning_times (*yellow_warning_times[1]) = 'Orbit-wide warning - no warning times' (*yellow_warning_indices[0]) = loc_seg_warning (*yellow_warning_indices[1]) = !values.f_nan; Orbit wide warning, no warning times end