def test_SfrFile(): sfrout = SfrFile('../examples/data/sfr_examples/sfroutput2.txt') # will be None if pandas is not installed if sfrout.pd is not None: df = sfrout.get_dataframe() assert df.layer.values[0] == 1 assert df.column.values[0] == 169 assert df.Cond.values[0] == 74510.0 assert df.col18.values[3] == 1.288E+03 sfrout = SfrFile('../examples/data/sfr_examples/test1tr.flw') if sfrout.pd is not None: df = sfrout.get_dataframe() assert df.col16.values[-1] == 5.502E-02 assert df.shape == (1080, 20)
def read_sfr_output(mf2005_sfr_outputfile=None, mf2005_SfrFile_instance=None, mf6_sfr_stage_file=None, mf6_sfr_budget_file=None, model=None): """Read MF-2005 or MF-6 style SFR output; return as DataFrame. """ if model.version == 'mf6': # get the budget output df = aggregate_mf6_stress_budget(mf6_sfr_budget_file) # get the stage data if mf6_sfr_stage_file is not None: stg = read_mf6_dependent_variable_output(mf6_sfr_stage_file, text='stage') df.sort_values(by=['kstpkper', 'node'], inplace=True) stg.sort_values(by=['kstpkper', 'node'], inplace=True) na_reaches = np.isnan(df.time.values) df.loc[~na_reaches].to_csv('df.csv') stg.loc[~na_reaches].to_csv('stg.csv') #assert np.allclose(df.time.values, stg.time.values) assert np.allclose(df.loc[~na_reaches].time.values, stg.loc[~na_reaches].time.values) assert np.array_equal(df.node.values, stg.node.values) df['stage'] = stg['stage'] # get the row, column location of SFR cells if model.sfr is not None: rd = pd.DataFrame(model.sfr.packagedata.array.copy()) assert rd.rno.min() == 0 assert df.node.min() == 0 if not isinstance(rd.cellid.values[0], int): rno_cellid = dict(zip(rd.rno, rd.cellid)) for i, dim in enumerate(['k', 'i', 'j']): df[dim] = pd.to_numeric( [rno_cellid[rno][i] for rno in df.node.values], errors='coerce') df.dropna(subset=['k', 'i', 'j'], axis=0, inplace=True) # can't convert to integers if nans are present for dim in ['k', 'i', 'j']: df[dim] = df[dim].astype(int) assert 'int' in df[dim].dtype.name else: # SFR output if mf2005_sfr_outputfile is not None: sfrobj = SfrFile(mf2005_sfr_outputfile) elif mf2005_SfrFile_instance is not None: sfrobj = mf2005_SfrFile_instance else: print( 'Need path to SFR tabular budget output or FloPy SfrFile instance.' ) df = sfrobj.df.copy() df.sort_values(by=['segment', 'reach'], inplace=True) return df
def import_sfr_out(self, path=None, name=None, ext='.sfr.out'): """TODO: Docs :param path: (Default value = None) :param name: (Default value = None) :param ext: (Default value = '.sfr.out') :returns: DataFrame, SFR data """ if path: sfrout = SfrFile(os.path.join(path, name + ext)) self.sfr_df = sfrout.get_dataframe() else: sfrout = SfrFile(os.path.join(self.data_folder, self.name + ext)) self.sfr_df = sfrout.get_dataframe() # End if return self.sfr_df
def test_SfrFile(): common_names = [ 'layer', 'row', 'column', 'segment', 'reach', 'Qin', 'Qaquifer', 'Qout', 'Qovr', 'Qprecip', 'Qet', 'stage', 'depth', 'width', 'Cond' ] sfrout = SfrFile('../examples/data/sfr_examples/sfroutput2.txt') assert sfrout.ncol == 18, sfrout.ncol assert sfrout.names == common_names + ['Qwt', 'delUzstor', 'gw_head'],\ sfrout.names assert sfrout.times == [(0, 0), (49, 1)], sfrout.times # will be None if pandas is not installed if sfrout.pd is not None: df = sfrout.get_dataframe() assert df.layer.values[0] == 1 assert df.column.values[0] == 169 assert df.Cond.values[0] == 74510.0 assert df.gw_head.values[3] == 1.288E+03 sfrout = SfrFile('../examples/data/sfr_examples/test1tr.flw') assert sfrout.ncol == 16, sfrout.ncol assert sfrout.names == common_names + ['gradient'], sfrout.names expected_times = [(0, 0), (4, 0), (9, 0), (12, 0), (14, 0), (19, 0), (24, 0), (29, 0), (32, 0), (34, 0), (39, 0), (44, 0), (49, 0), (0, 1), (4, 1), (9, 1), (12, 1), (14, 1), (19, 1), (24, 1), (29, 1), (32, 1), (34, 1), (39, 1), (44, 1), (45, 1), (46, 1), (47, 1), (48, 1), (49, 1)] assert sfrout.times == expected_times, sfrout.times if sfrout.pd is not None: df = sfrout.get_dataframe() assert df.gradient.values[-1] == 5.502E-02 assert df.shape == (1080, 20) ml = flopy.modflow.Modflow.load('test1tr.nam', model_ws=path, exe_name='mf2005') ml.change_model_ws(outpath) ml.write_input() ml.run_model() sfrout = SfrFile(os.path.join(outpath, 'test1tr.flw')) assert sfrout.ncol == 16, sfrout.ncol assert sfrout.names == common_names + ['gradient'], sfrout.names expected_times = [(0, 0), (4, 0), (9, 0), (12, 0), (14, 0), (19, 0), (24, 0), (29, 0), (32, 0), (34, 0), (39, 0), (44, 0), (49, 0), (0, 1), (4, 1), (9, 1), (12, 1), (14, 1), (19, 1), (24, 1), (29, 1), (32, 1), (34, 1), (39, 1), (44, 1), (45, 1), (46, 1), (47, 1), (48, 1), (49, 1)] assert sfrout.times == expected_times, sfrout.times
def read_sfr_output(mf2005_sfr_outputfile=None, mf2005_SfrFile_instance=None, mf6_sfr_stage_file=None, mf6_sfr_budget_file=None, mf6_package_data=None, model=None, grid_type='structured'): """Read MF-2005 or MF-6 style SFR output; return as DataFrame. """ model_version = None packagedata = None if model is not None: model_version = model.version if model_version == 'mf6': packagedata = pd.DataFrame(model.sfr.packagedata.array.copy()) elif mf6_package_data is not None: model_version = 'mf6' if isinstance(mf6_package_data, str) or isinstance(mf6_package_data, Path): skiprows = 0 names = None with open(mf6_package_data) as src: for line in src: if line.strip().startswith('#'): names = line.strip().split() skiprows += 1 else: ncol = len(line.strip().split()) break if names is None: if grid_type == 'structured': names = ['rno', 'k', 'i', 'j', 'rlen', 'rwid', 'rgrd', 'rtp', 'rbth', 'rhk', 'man', 'ncon', 'ustrf', 'ndv'] else: names = ['rno', 'cellid', 'rlen', 'rwid', 'rgrd', 'rtp', 'rbth', 'rhk', 'man', 'ncon', 'ustrf', 'ndv'] for i, _ in enumerate(range(len(names), ncol)): names.append(f'aux_col{i+1}') else: names[0] = names[0].strip('#') # read the packagedata as a string to handle "none" values with open(mf6_package_data) as src: raw_pd = src.read() raw_pd = raw_pd.lower().replace('none', '0 0 0') packagedata = pd.read_csv(io.StringIO(raw_pd), names=names, skiprows=skiprows, delim_whitespace=True) for col in ['rno', 'k', 'i', 'j']: if col in packagedata: packagedata[col] -= 1 if 'cellid' in packagedata.columns: if not isinstance(packagedata['cellid'][0], int): packagedata['cellid'] = [(c[0]-1, c[1] -1, c[2] -1) for c in packagedata['cellid']] else: packagedata['cellid'] -=1 else: # make the dataframe on the .array attribute for flopy objects # or mf6_package_data is assumed to be array-like packagedata = pd.DataFrame(getattr(mf6_package_data, 'array', mf6_package_data)) if model_version == 'mf6': # get the budget output df = aggregate_mf6_stress_budget(mf6_sfr_budget_file) # get the stage data if mf6_sfr_stage_file is not None: stg = read_mf6_dependent_variable_output(mf6_sfr_stage_file, text='stage') df.sort_values(by=['kstpkper', 'node'], inplace=True) stg.sort_values(by=['kstpkper', 'node'], inplace=True) df.set_index(['kstpkper', 'node'], inplace=True) stg.set_index(['kstpkper', 'node'], inplace=True) na_reaches = np.isnan(df.time.values) #df.loc[~na_reaches].to_csv('df.csv') #stg.loc[~na_reaches].to_csv('stg.csv') #assert np.allclose(df.time.values, stg.time.values) assert np.allclose(df.loc[~na_reaches].time.values, stg.loc[~na_reaches].time.values) assert np.array_equal(df.index, stg.index) df['stage'] = stg['stage'] df.reset_index(inplace=True) # get the row, column location of SFR cells; # compute stream depths if packagedata is not None: rd = packagedata # convert reach number to zero-based if rd.rno.min() == 1: rd['rno'] -= 1 assert rd.rno.min() == 0 assert df.node.min() == 0 rno_strtop = dict(zip(rd.rno, rd.rtp)) df['strtop'] = pd.to_numeric([rno_strtop[rno] for rno in df.node.values], errors='coerce') # fill nan stages with their streambed tops isna = df['stage'].isna() df.loc[isna, 'stage'] = df.loc[isna, 'strtop'] df['depth'] = df['stage'] - df['strtop'] if 'cellid' not in rd.columns: rd['cellid'] = list(zip(rd['k'], rd['i'], rd['j'])) rno_cellid = dict(zip(rd.rno, rd.cellid)) for i, dim in enumerate(['k', 'i', 'j']): df[dim] = pd.to_numeric([rno_cellid[rno][i] for rno in df.node.values], errors='coerce') df.dropna(subset=['k', 'i', 'j'], axis=0, inplace=True) # can't convert to integers if nans are present for dim in ['k', 'i', 'j']: df[dim] = df[dim].astype(int) assert 'int' in df[dim].dtype.name else: # SFR output if mf2005_sfr_outputfile is not None: sfrobj = SfrFile(mf2005_sfr_outputfile) elif mf2005_SfrFile_instance is not None: sfrobj = mf2005_SfrFile_instance else: print('Need path to SFR tabular budget output or FloPy SfrFile instance.') df = sfrobj.df.copy() df.sort_values(by=['segment', 'reach'], inplace=True) return df
def test_SfrFile(): common_names = [ "layer", "row", "column", "segment", "reach", "Qin", "Qaquifer", "Qout", "Qovr", "Qprecip", "Qet", "stage", "depth", "width", "Cond", ] sfrout = SfrFile("../examples/data/sfr_examples/sfroutput2.txt") assert sfrout.ncol == 18, sfrout.ncol assert sfrout.names == common_names + [ "Qwt", "delUzstor", "gw_head", ], sfrout.names assert sfrout.times == [(0, 0), (49, 1)], sfrout.times # will be None if pandas is not installed if sfrout.pd is not None: df = sfrout.get_dataframe() assert df.layer.values[0] == 1 assert df.column.values[0] == 169 assert df.Cond.values[0] == 74510.0 assert df.gw_head.values[3] == 1.288e03 sfrout = SfrFile("../examples/data/sfr_examples/test1tr.flw") assert sfrout.ncol == 16, sfrout.ncol assert sfrout.names == common_names + ["gradient"], sfrout.names expected_times = [ (0, 0), (4, 0), (9, 0), (12, 0), (14, 0), (19, 0), (24, 0), (29, 0), (32, 0), (34, 0), (39, 0), (44, 0), (49, 0), (0, 1), (4, 1), (9, 1), (12, 1), (14, 1), (19, 1), (24, 1), (29, 1), (32, 1), (34, 1), (39, 1), (44, 1), (45, 1), (46, 1), (47, 1), (48, 1), (49, 1), ] assert sfrout.times == expected_times, sfrout.times if sfrout.pd is not None: df = sfrout.get_dataframe() assert df.gradient.values[-1] == 5.502e-02 assert df.shape == (1080, 20) ml = flopy.modflow.Modflow.load("test1tr.nam", model_ws=path, exe_name="mf2005") ml.change_model_ws(outpath) ml.write_input() ml.run_model() sfrout = SfrFile(os.path.join(outpath, "test1tr.flw")) assert sfrout.ncol == 16, sfrout.ncol assert sfrout.names == common_names + ["gradient"], sfrout.names expected_times = [ (0, 0), (4, 0), (9, 0), (12, 0), (14, 0), (19, 0), (24, 0), (29, 0), (32, 0), (34, 0), (39, 0), (44, 0), (49, 0), (0, 1), (4, 1), (9, 1), (12, 1), (14, 1), (19, 1), (24, 1), (29, 1), (32, 1), (34, 1), (39, 1), (44, 1), (45, 1), (46, 1), (47, 1), (48, 1), (49, 1), ] assert sfrout.times == expected_times, sfrout.times