Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PstFrom.add_parameters() par_style = direct #533

Open
wzell-usgs opened this issue Aug 30, 2024 · 3 comments
Open

PstFrom.add_parameters() par_style = direct #533

wzell-usgs opened this issue Aug 30, 2024 · 3 comments

Comments

@wzell-usgs
Copy link

wzell-usgs commented Aug 30, 2024

I'm trying to understand and implement a few features of the 'direct' parameter style using PstFrom.add_parameters().

For this sequence

pf = pyemu.utils.PstFrom(...)
pf.add_parameters(...)  # If I specify par_style direct and pass the initial_value argument here ...
pf.add_observations(...)
pst = pf.build_pst()  # ... I get an error here that parameter_data includes NaNs

Those NaNs are the parval1 column that I thought I was specifying with the initial_value argument that I passed to pf.add_parameters.

I think the problem is here (and my code runs as expected if I remove this conditional and set parval1) :

pyemu/pyemu/utils/pst_from.py

Lines 2774 to 2775 in b301698

if par_style != "d":
df.loc[:, "parval1"] = initial_value

Is there a reason that parval1 should not be set here for direct parameters? Should I be doing something differently to specify initial values for direct parameters?

Thx

@jtwhite79
Copy link
Collaborator

For direct parameters, we want to read the existing input file and use those values for parval1 quantities, thats why the initial_value arg is ignored for direct parameters. Can you post a min working example that causes these nans?

@wzell-usgs
Copy link
Author

So the error that I'm experiencing is related to the presence of NaN values in the model input file. Which, in retrospect, does seem like an obvious place to look for the error ... But for a little more context and perhaps of interest to others who find this:

  • My model input file originally had 0s in inactive cells (because I'd created it by multiplying parval1 onto the ones and zeros of the idomain array).
  • That model input file, however, failed the
    def _check_diff(org_arr, input_filename, zval=None):
    because the 0s were included in the variability assessment. Because that check uses np.nanmin and np.nanmax I circumvented it by replacing my 0s with np.nan.
  • Which then put NaNs into the parameter data and caused the subsequent error.

There is, however, a curious little postscript. Here's my minimum reproducible example:

original_d = 'original_d'
new_d = 'new_d'
nrow, ncol = 10, 10

parnme = 'myparam'
parval1, lower_bound, upper_bound = 15, 5, 50
input_file = f'{parnme}.dat'
input_vals = np.ones((nrow, ncol)) * parval1

# Write the model input file for this parameter;
np.savetxt(os.path.join(original_d, input_file),
           input_vals,
           fmt='%0.8e')

pf = pyemu.utils.PstFrom(original_d, new_d, remove_existing=True)
pf.add_parameters(par_name_base=parnme,
                  initial_value=parval1,
                  filenames=input_file,
                  par_type='constant',
                  par_style='direct',
                  transform='log',
                  lower_bound=lower_bound,
                  upper_bound=upper_bound,
                  dist_type='uniform')

pst = pf.build_pst()

So that works. I did actually consider the potential effect of NaNs in the model input so I put a stripe of NaNs across the top of the model input file like this:

input_vals[0:1, :] = np.nan  # Create an 'inactive' area flagged by NaNs

That still works! That is, parval1 gets written correctly into the pst.parameter_data.

However, if I move the stripe of NaNs to the BOTTOM of the model input array ...

input_vals[-1:, :] = np.nan  # Create an 'inactive' area flagged by NaNs

parval1 does not get written correctly into the pst.parameter_data.
I suppose the moral of the story is to write a full (nrow, ncol) array of parval1s to the model input file and not mask any inactive cells.

@jtwhite79
Copy link
Collaborator

Yeah nans are trouble. If you want to have inactive areas for the parameterization, best to use a zone array...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants