diff --git a/wetb/prepost/Simulations.py b/wetb/prepost/Simulations.py index fa0cc7fe14424e3054ae6f9be50c742bcb3f116c..533c9fc1c9b8237f4ab3b6511936fd3b518b5f53 100755 --- a/wetb/prepost/Simulations.py +++ b/wetb/prepost/Simulations.py @@ -3584,6 +3584,18 @@ class Cases(object): return beam, body, eigen_body, eigen_struct, struct_inertia + def load_errorlogs(self): + """Load error log analysis + """ + + fpath = os.path.join(self.post_dir, self.sim_id + '_ErrorLogs.h5') + try: + df_err = pd.read_hdf(fpath, 'table') + except FileNotFoundError: + df_err = pd.read_csv(fpath.replace('.h5', '.csv')) + + return df_err + def change_results_dir(self, forcedir, post_dir=False): """ if the post processing concerns simulations done by thyra/gorm, and @@ -3770,6 +3782,66 @@ class Cases(object): return np.array(zvals), np.array(yvals) + def find_failed(self, df_cases=None, df_err=None, save=True, + rem_failed=None): + """Given the log file analysis and the Cases tag list, generate a list + of failed cases. This is usefull when either some cases have been + re-run or when the post-processing is done at the same time as the + simulations (e.g. zipchunks approach). + + Parameters + ---------- + + df_cases : df, default=None + If None the current cases dict object is converted to a dataframe + using self.cases2df() + + df_err : df, default=None + If None the current error log is converted to a dataframe using + self.load_errorlogs() + + save : boolean, default=True + save the failed cases dict using pickle. + + rem_failed : boolean, default=None + if None the already set value self.rem_failed is used. Otherwise + self.rem_failed is overwritten. If True, failed cases are removed + from self.cases. + """ + + if df_cases is None: + df_cases = self.cases2df() + if df_err is None: + df_err = self.load_errorlogs() + if rem_failed is None: + rem_failed = self.rem_failed + else: + self.rem_failed = rem_failed + + self.cases_fail = {} + + # convert case_id to log file names + # logids = pd.DataFrame(columns=['']) + df_cases['logid'] = df_cases['[log_dir]'] + df_cases['[case_id]'] + '.log' + # we only need to merge with errorlogs using a portion of the data + # join error logs and df_cases on the logid + df = pd.merge(df_cases[['logid', '[case_id]']], df_err[['file_name']], + left_on='logid', right_on='file_name', how='outer') + # missing files: those present in df_cases but not in the error log + # this means file_name is a nan or empty + # logids_missing2 = set(df_cases['logid']) - set(df_err['file_name']) + logids_missing = df[pd.isna(df['file_name']) | (df['file_name']=='')] + for case_id in logids_missing['[case_id]']: + cname = case_id + '.htc' + self.cases_fail[cname] = copy.copy(self.cases[cname]) + + if rem_failed: + self.rem_failed() + + if save: + save_pickle(os.path.join(self.post_dir, self.sim_id + '_fail.pkl'), + self.cases_fail) + def remove_failed(self): # don't do anything if there is nothing defined