Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add scale_voltage_current_power to ModelChain.pvwatts_dc #1138

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

Merged
merged 10 commits into from
Jan 21, 2021

Conversation

cwhanse
Copy link
Member

@cwhanse cwhanse commented Jan 20, 2021

Adds scaling by modules per string and strings per inverter to the ModelChain.pvwatts_dc method. This behavior parallels ModelChain.sapm and ModelChain.singlediode. User code is not likely to be affected since PVSystem.modules_per_strings and PVSystem.strings_per_inverter both default to 1.

@cwhanse cwhanse added this to the 0.9.0 milestone Jan 20, 2021
@cwhanse
Copy link
Member Author

cwhanse commented Jan 20, 2021

@wholmgren I should have looked at the base level function. pvlib.pvsystem.scale_voltage_current_power expects the input DataFrame to contain voltage, current and power. We could make the existing function more flexible, or add a new function that only scales a Series input of power. Preference?

@wholmgren
Copy link
Member

I had the same oversight despite the fact that "voltage" and "current" are in the name. I'd prefer a new function over changing the existing function. Maybe this is a little lazy and inconsistent, but I'd also be ok with skipping the function layer and only implementing the PVSystem method or just putting it in the ModelChain.pvwatts_dc method.

@cwhanse
Copy link
Member Author

cwhanse commented Jan 20, 2021

I got impatient and tried the first option (make existing function more general). One drawback of the existing function is that it requires all keys including 'i_x' and 'i_xx' which are produced by the singlediode function probably to be consistent with the output of the sapm.

@cwhanse
Copy link
Member Author

cwhanse commented Jan 20, 2021

@wholmgren see what you think before I undo or fix what is broken. I think we can keep the same signature of scale_voltage_current_power.

@wholmgren
Copy link
Member

You've managed to make the name and signature make sense, but using the seldom-used name attribute as a switch feels wrong.

Another option to consider:

  • Within ModelChain.pvwatts_dc we create a temporary DataFrame with p_mp=pdc, v_mp=pdc, and i_mp=1.
  • Within scale_voltage_current_power, use one of the more flexible pandas column selection methods
  • Within ModelChain.pvwatts_dc set the result equal to the appropriate column so just the scaled pdc Series is retained.

@cwhanse
Copy link
Member Author

cwhanse commented Jan 20, 2021

If name is to be avoided for Series I don't see how to use this function to e.g. scale a voltage Series. In that case I think the temporary DataFrame is the way to go.

currents = ['i_mp', 'i_x', 'i_xx', 'i_sc']
voltages = voltage_keys and data.columns
currents = current_keys and data.columns
powers = power_keys and data.columns
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of something like this:

In [28]: voltage = 5

In [29]: current = 10

In [30]: df = pd.DataFrame([[1, 1, 1]], columns=['p_mp', 'v_mp', 'i_mp'])

In [31]: df
Out[31]:
   p_mp  v_mp  i_mp
0     1     1     1

In [32]:     voltage_keys = ['v_mp', 'v_oc']
    ...:     current_keys = ['i_mp', 'i_x', 'i_xx', 'i_sc']
    ...:     power_keys = ['p_mp']

In [33]: df.filter(voltage_keys, axis=1) * voltage
Out[33]:
   v_mp
0     5

In [34]: df.filter(current_keys, axis=1) * current
Out[34]:
   i_mp
0    10

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In [35]: voltage_df = df.filter(voltage_keys, axis=1) * voltage

In [36]: current_df = df.filter(current_keys, axis=1) * current

In [37]: df = pd.concat([voltage_df, current_df], axis=1)

In [38]: df['p_mp'] = df['v_mp'] * df['i_mp']

In [39]: df
Out[39]:
   v_mp  i_mp  p_mp
0     5    10    50

Copy link
Member

@wholmgren wholmgren Jan 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how to scale a power other than p_mp without hugely complicating the code. I also don't know that there's a need for it at this time.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pvwatts methods don't produce voltage or current.

Copy link
Member

@wholmgren wholmgren Jan 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was still in the mindset that we could provide a DataFrame with p_mp=pdc, v_mp=pdc, and i_mp=1 as I suggested above. But yes it is better to just multiply the power keys by the voltage and current scale factors.

In [42]: df = pd.DataFrame([[1, 1, 1]], columns=['p_mp', 'v_mp', 'i_mp'])

In [43]: voltage_df = df.filter(voltage_keys, axis=1) * voltage

In [44]: current_df = df.filter(current_keys, axis=1) * current

In [45]: power_df = df.filter(power_keys, axis=1) * voltage * current

In [49]: concat_df = pd.concat([voltage_df, current_df, power_df], axis=1)

In [50]: concat_df = concat_df[df.columns]

In [51]: concat_df
Out[51]:
   p_mp  v_mp  i_mp
0    50     5    10

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One issue with the temporary DataFrame: when converting back to Series, the column label 'p_mp' is assigned to the Series name, which affects testing but likely no user code. Any concern here?

Copy link
Member

@wholmgren wholmgren Jan 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no concern. pandas assert_series_equal only recently started checking that attribute and it was a fair bit of work to fix all of the newly broken tests in the Arbiter.

@cwhanse
Copy link
Member Author

cwhanse commented Jan 21, 2021

Test failure is unrelated, timeout when fetching SURFRAD data.

cwhanse and others added 2 commits January 21, 2021 13:56
@wholmgren
Copy link
Member

failures are still surfrad io.

Thanks @cwhanse!

@wholmgren wholmgren merged commit 6b92d21 into pvlib:master Jan 21, 2021
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

Successfully merging this pull request may close these issues.

document or support modules_per_string strings_per_inverter with pvwatts in modelchain
2 participants