-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Gold I-V dataset with benchmarking #426
Conversation
Here is some code for others to reproduce computations. To run this do the following: $ pip install pyinterval # first time only
$ python gold_dataset.py # Will rewrite test.json file with gold dataset
|
current | ||
|
||
|
||
def bootstrap_si_device_bishop(cell_area_cm2=4., N_s=1, ideality_factor=1.5): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer create_si_device_bishop
|
||
def bootstrap_si_device_bishop(cell_area_cm2=4., N_s=1, ideality_factor=1.5): | ||
""" | ||
Create c-Si device based on cell parameters in Bishop's 1988 paper Fig. 6. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a De Soto model for a c-Si device...
|
||
|
||
def bootstrap_si_cell_large(): | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer create_si_cell_large
def bootstrap_si_cell_large(): | ||
""" | ||
Create a single-large-area-cell c-Si device based on a SunPower module. | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add note that we are creating a De Soto model for the cell
device.V_mp_ref = device.V_mp_ref / Ns_module | ||
device.a_ref = device.a_ref / Ns_module | ||
device.R_s = device.R_s / Ns_module | ||
device.R_sh_ref = Ns_module * device.R_sh_ref |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be Ns_module / device.R_sh_ref
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, you need to multiply that one.
def make_gold_dataset(): | ||
""" | ||
Make a gold dataset of I-V curves that accurately solve single-diode model. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that accurately solve the single diode equation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...that are accurate solutions to...
Returns | ||
------- | ||
gold_dataset : dict | ||
The gold data are returned in a dict with metadata (e.g., timestamp, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it practical to outline the gold_dataset
dict here (i.e., list and describe each key), the device dict, and a list member dict for a device?
returned in a python dict that is in a lossless, machine-interoperable | ||
format, which is the expected input to most of the other functions in this | ||
python module. (Other functions can convert this dict to a human-readable | ||
format.) An explict method of Bishop [1] is used to compute (V, I) pairs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would help to name the 'other functions'
return gold_dataset | ||
|
||
|
||
def convert_gold_dataset(gold_dataset): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe add _to_pvlib
to function name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, gold_dataset_to_pvlib
return gold_dataset_converted | ||
|
||
|
||
def pretty_print_gold_dataset(gold_dataset): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gold_dataset_to_csv
# Load G, T, and 5 single-diode model parameters for each I-V curve | ||
# Floats converted from lossless, machine-interoperable hex format | ||
|
||
iv_curve["G"] = float.fromhex(iv_curve["G"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we use the pvlib keys? effective_irradiance
instead of G
, temp_cell
instead of T
, etc.
pvlib/data/gold/sdm.py
Outdated
See ``make_gold_dataset()``. | ||
|
||
test_func : dict | ||
A dictionary of functions to guage. Supported keys to functions are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'gauge'
Sorry, I'm not too clear on the question here. There's been too much going on!
|
@adriesse Will is inviting you to review the pull request. OK if you don't have time, since both Will and I have done so. The PR consists of two basic components: a function to precisely calculate sets of IV curves (a number of example devices are included), and a function to compare between two IV curve calculators (think of a function that runs and compares two functions). I think Will's major interest is, do you think this capability is appropriate for and useful to pvlib? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall impressions:
There are some really long functions here, and it would be nice to chop them up. I think one way to do this might be to not treat the whole gold set as a single entity but process (and store/read) them one device or even one curve at a time.
The storage format was discussed a while back. Given the size of your tolerance I think the lossy csv format is more than adequate. You can also flatten the data into a 2d table and read/write that with pandas and even put a few header lines with extra info pretty easily. I think multiple files would be appropriate--there won't be hundreds.
Anyway, even if neither of those two ideas is appealing, there are some other ideas for improvements already. It is a big contribution overall, and I think it would be fine to take some extra time to hone it further.
device.PTC = None | ||
|
||
return device | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This leaves me searching whether you kept attribute of the device you copied. Wouldn't it be cleaner to just create a new device from scratch?
device.V_mp_ref = device.V_mp_ref / Ns_module | ||
device.a_ref = device.a_ref / Ns_module | ||
device.R_s = device.R_s / Ns_module | ||
device.R_sh_ref = Ns_module * device.R_sh_ref |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, you need to multiply that one.
def make_gold_dataset(): | ||
""" | ||
Make a gold dataset of I-V curves that accurately solve single-diode model. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...that are accurate solutions to...
|
||
From a gold dataset in the lossless, machine-interoperable format, create | ||
and return the dataset as a human-readale, comma-separated-value (csv) | ||
string. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
readable
# Don't include entire curve in exception message | ||
del device_dict["iv_curves"][-1]["v_gold"] | ||
del device_dict["iv_curves"][-1]["i_gold"] | ||
raise ValueError("Residual interval {} not in {}, \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this ever happen??
interval(nNsVth)) - interval(g_sh) * | ||
(interval(v) + interval(i)*interval(r_s)) - | ||
interval(i) for v, i in zip(v_gold, i_gold)] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the advantage of using intervals here, where all the intervals are single numbers?
for v, i, current_sum_residual_interval in zip( | ||
v_gold, i_gold, | ||
current_sum_residual_interval_list): | ||
if current_sum_residual_interval not in tol_interval: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the advantage of this over np.isclose()?
device_dict["i_from_v"]["performance"]["time_s"]["std"] = \ | ||
numpy.std(device_dict["i_from_v"] | ||
["performance"]["time_s"]["data"], ddof=1) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block is quite hard for me to parse.
pvlib.pvsystem.retrieve_sam('cecmod').SunPower_SPR_E20_327, | ||
pvlib.pvsystem.retrieve_sam('cecmod').First_Solar_FS_495 | ||
] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about copying the parameters for all 5 devices into golden_devices.csv or something similar? Then you just need a single read.
ci/requirements-py34.yml
Outdated
@@ -17,5 +17,7 @@ dependencies: | |||
- nose | |||
- pip: | |||
- coveralls | |||
- pvfactors==1.0.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@anomam Do you know if I'm fixing or breaking something here? (Is pvfactors 1.0.1 really not supported in Python 3.4?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point @markcampanelli , starting with version 1.0.0 pvfactors should work with earlier versions of pandas, and therefore be compatible with Python 3.4.
Could you post an issue in pvfactors by any chance? A PR would be very much welcome as well :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Python 3.4 hit "end of life" a few months ago. I don't plan to support it going forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like scipy/scipy#8028 may have fixed the significant issue with a |
Closing this in favor of #1573. |
pvlib python pull request guidelines
Thank you for your contribution to pvlib python!
You may submit a pull request with your code at any stage of completion, however, before the code can be merged the following items must be addressed:
git diff upstream/master -u -- "*.py" | flake8 --diff
and/or landscape.io linting service.docs/sphinx/source/api.rst
for API changes.docs/sphinx/source/whatsnew
file for all changes.Please don't hesitate to ask for help if you're unsure of how to accomplish any of the above. You may delete all of these instructions except for the list above.
Brief description of the problem and proposed solution (if not already fully described in the issue linked to above):