Giter VIP home page Giter VIP logo

pvfactors's People

Contributors

anomam avatar campanelli-sunpower avatar cedricleroy avatar kandersolar avatar tcapelle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pvfactors's Issues

Could not find module

I am using pvlib.bifacial.pvfactors_timeseries, but when i run it i get this error

pvlib.bifacial.pvfactors_timeseries(solar_azimuth=PosSol['azimuth'],
solar_zenith=PosSol['zenith'],
surface_azimuth=surface_azimuth,
surface_tilt=surface_tilt,
axis_azimuth=0.0,
timestamps=data_weatherforecast.index,
dni=data_weatherforecast['dni'],
dhi=data_weatherforecast['dhi'],
gcr=0.716,
pvrow_height=1,
pvrow_width=2,
albedo=albedo,
n_pvrows=3,
index_observed_pvrow=1,
rho_front_pvrow=0.03,
rho_back_pvrow=0.05,
horizon_band_angle=15.0)

But when i run it i get this error:

Could not find module 'C:\anaconda\Library\bin\geos_c.dll' (or one of its dependencies). Try using the full path with constructor syntax.

pvfactors could benefit from a (better) horizon shading model on the back-surface

Currently in pvfactors, the horizon band irradiance incident on the back-surface is exactly equal to the one calculated by the Perez model for the front-surface.
This is not the most logical way of treating the horizon band, especially when we think of cases of multiple rows of fixed tilt systems for instance.
Some improvements should be "easily" implemented just like what was done for the front surface.

`ax` parameter of BasePVArray.plot_at_idx should be optional

It would be a minor convenience if BasePVArray.plot_at_idx could generate its own pyplot Axes object instead of forcing the user to pass one in. I don't mind keeping it as a required parameter in the plot_at_idx methods of other classes, but since BasePVArray is at the top of the tree and likely the one that people will be calling, it makes sense to me for it to be a special case.

It's also convenient that ax is currently the last required parameter, so there's no need to reorder parameters, just tack =None onto the parameter and do a quick check in the method body. However, since the method currently doesn't return anything, the user would have to use plt.gca() or similar to access the plot object, so it might make sense to start returning ax at the end of the method too.

Direct shading geometry split should happen on surface registry

Because right now both the front and back surface of the pvrow are split up (at shading point) even though shading happens only on 1 side.

It didn't matter that much because we end up calculating weighted averages over the full surfaces (results shouldn't stay identical).

The tendency of bifacial SingleAxisTracker and albedo is not reasonable

Hi,

Isssue:
PVlib use pvfacotors to simulate bifacial module.
When I use pvlib to simulate bifacial tracker system, I found that the dc_energy will increase as albedo decrease. However, if I use bifacial fixed rack system to simulate, the trendency is right (dc_energy will increase as albedo increase).

In ordor to simlify the issue, I splited pvfacoter module from pvlib code, only simulate some points for different surface tilt and surface azimuth. However, then found that the problem is still there. My code is as following and as attachment. The results of front and rear irradiance is as following graph.

As previous description, the tendency of fixed-rack system is reasonable, but it is unreasonable for tracker system. Besides, there are some negative value for the results.

pvfactor results comparison for tracker and fixed-rack

Code:
i```
mport pvlib
import pandas as pd
import numpy as np
from pvlib.bifacial import pvfactors_timeseries
from pvfactors.run import run_timeseries_engine
from datetime import datetime
from pandas import DataFrame

Create input data

df_inputs = pd.DataFrame(
{'solar_zenith': [11, 19, 25, 29, 29, 26, 21, 13, 4],
'solar_azimuth': [130, 141, 155, 170, 186, 201, 215, 227, 237],
# 'surface_tilt': [11.5, 43.1, 51.6, 28.8, 0.182, 28.5, 51.4, 44.1, 11.9], # if tracker system, use the group data
# 'surface_azimuth': [90, 90, 90, 90, 90, 270, 270, 270, 270], # if tracker system, use the group data
'surface_tilt': [40, 40, 40, 40, 40, 40, 40, 40, 40],
'surface_azimuth': [180, 180, 180, 180, 180, 180, 180, 180, 180],
'dni': [531, 723, 677, 584, 103, 4.2, 0, 0, 0],
'dhi': [88, 91, 112, 158, 199, 126, 18, 5, 0]},
index=[datetime(1990, 1, 3, 9), datetime(1990, 1, 3, 10), datetime(1990, 1, 3, 11),
datetime(1990, 1, 3, 12), datetime(1990, 1, 3, 13), datetime(1990, 1, 3, 14),
datetime(1990, 1, 3, 15), datetime(1990, 1, 3, 16), datetime(1990, 1, 3, 17)]
)

def pvfactor_build_report(pvarray):
return {
'total_inc_back': pvarray.ts_pvrows[1].back.get_param_weighted('qinc').tolist(),
'total_inc_front': pvarray.ts_pvrows[1].front.get_param_weighted('qinc').tolist()
}

pvarray_parameters = {
'n_pvrows': 3,
'index_observed_pvrow': 1,
'axis_azimuth': 0,
'pvrow_height': 1.5,
'pvrow_width': 4.6,
'gcr': 0.4,
'rho_front_pvrow': 0.01,
'rho_back_pvrow': 0.03,
'horizon_band_angle': 15
}

pvfactor = run_timeseries_engine(pvfactor_build_report,
pvarray_parameters,
df_inputs.index,
df_inputs.dni,
df_inputs.dhi,
df_inputs.solar_zenith,
df_inputs.solar_azimuth,
df_inputs.surface_tilt,
df_inputs.surface_azimuth,
0.2 # albedo, `` you can change the number
)

print(pvfactor)

df_1=DataFrame(pvfactor['total_inc_back'],columns=['total_inc_back'])
df_2=DataFrame(pvfactor['total_inc_front'],columns=['total_inc_front'])
df=df_2.join(df_1)


Negative irradiance values when PV modules go underground

Currently there is nothing stopping a user from specifying an array much wider than it is tall and proceeding to model it at steep tilts that cause the lower module edge to go to negative heights. When that happens, negative irradiance values are returned. For example, for static solar position and irradiance, here's how the returned rearside irradiance varies with surface tilt for an array with pvrow_width/pvrow_height=3 showing how irradiance goes negative when pvrow_width/2 * sin(surface_tilt) > pvrow_height:

image

Code to reproduce above plot (v1.5.2):

Click to expand!
from pvfactors.geometry import OrderedPVArray
from pvfactors.engine import PVEngine
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

ts_inputs = pd.DataFrame({
    "timestamps": 0,
    "DNI": 1000,
    "DHI": 200,
    "solar_zenith": 45,
    "solar_azimuth": 90,
    "surface_tilt": np.linspace(0, 90, num=1000),
    "surface_azimuth": 90,
    "albedo": 0.2,
})

pvarray_parameters = {
    "n_pvrows": 3,
    "pvrow_height": 1,
    "pvrow_width": 3,
    "axis_azimuth": 180,
    "gcr": 0.5,
}

# tilt when part of the module goes underground
boundary_tilt = np.degrees(np.arcsin(
    pvarray_parameters["pvrow_height"] / (pvarray_parameters["pvrow_width"] / 2)
))

pvarray = OrderedPVArray.init_from_dict(pvarray_parameters)
engine = PVEngine(pvarray)
engine.fit(**ts_inputs)

engine.run_full_mode()
grear = pvarray.ts_pvrows[0].back.get_param_weighted("qinc")
plt.plot(ts_inputs["surface_tilt"], grear)
plt.axvline(boundary_tilt, c='k', ls='--')
plt.xlabel("Surface Tilt [degrees]")
plt.ylabel("Rearside Irradiance [W/m2]")

This behavior has tripped people up at least twice:

I think it would be good to raise an error, or at least emit a warning, in this situation. Perhaps a check like this in OrderedPVArray.fit?

        # Check whether the lower module edge ever goes underground
        lower_edge_height = self.height - 0.5 * self.width * np.sin(np.radians(surface_tilt))
        if np.any(lower_edge_height < 0):
            msg = ("Input pvrow_height is not large enough to prevent modules "
                   "from colliding with ground. Check pvrow_width, "
                   "pvrow_height, and surface_tilt.")
            raise ValueError(msg)

PVEngine.skip_step is not used

PVEngine creates a mask indicating values that need not be considered in the calculation:

# Skip timesteps when:
# - solar zenith > 90, ie the sun is down
# - DNI or DHI is negative, which does not make sense
# - DNI and DHI are both zero
self.skip_step = (solar_zenith > 90) | (DNI < 0) | (DHI < 0) \
| ((DNI == 0) & (DHI == 0))

However, that mask is not actually used anywhere today. It used to be, but it looks like it stopped being used in #84 during the switch from iterative to vectorized code.

I think the underlying concept may still be useful even in the current vectorized approach, so I think it's probably worth seeing if we can start using it again somehow, otherwise it should just be deleted IMHO.

Tracker bifacial modules models

Hello everyone,

I'm structuring a monitoring system for a photovoltaic plant with pvlib. As the modules are bifacial and are mounted on a solar tracker (2p), I am using pvfactors. I believe I have already resolved the dependencies: pvfactors 1.5.1, pvlib 0.7.0, and shapely reinstalled via conda.

As the modules do not have parameters for the Sandia model, I intend to use the de Soto model.

I plan to run the code automatically once a day with the weather data collected during the period.

I would like to know if anyone has any code developed with pvfactors and single diode models for the modules.

Sure of your attention, thank you in advance!

Ben Possatto

Simulated irradiance is not continuous at tilt=0

As always I will preface this by saying I'm not a frequent pvfactors user or even someone that has read the pvfactors PVSC paper, so there's a chance this is user error. @spaneja showed this behavior to me and I tried to identify the root cause before opening the issue.

The high-level issue is essentially that the simulated irradiance values for surface_tilt=0 and surface_tilt=0.001 are very different, despite no practical difference in surface_tilt. Here is an example output where the only difference is whether surface_tilt is 0 or 0.001:

   total_inc_back  total_inc_front  total_abs_back  total_abs_front
0      254.512852       702.081332      241.787209       681.018892

   total_inc_back  total_inc_front  total_abs_back  total_abs_front
0       76.187245       541.424948       72.377883         525.1822

I have uploaded a small notebook to reproduce the issue here: https://gist.github.com/kanderso-nrel/4c780640585881b01f82768c5bac5b51

I think I found two issues in the pvfactors code caused by tilt being exactly zero but it's possible that there are more. The first is pretty simple, and mentioned as a warning in that notebook (divide by zero encountered in true_divide). The problem is that finding the cutting points in pvground.py fails when the modules are horizontal. This makes theoretical sense (two parallel lines never intersect), but I'm not sure what to do about it in the code.

dx = (y1s_pvrow - y_ground) / np.tan(rotation_vec)

The second is that when surface_tilt=0, it seems that some values in pvarray.ts_vf_aoi_matrix go negative, which I'm assuming is unexpected. However the view factor calculation code is more than I want to chew on right now so I did not determine what code is to blame for it.

I'm happy to help investigate further but I suspect it would be very inefficient given my lack of familiarity with view factor geometry, so I'm hoping someone more experienced can do it instead 😁

How to recover index of segment

TL;DR: How do I recover the corresponding backface irradiance to compare to my reference cell.

Hello,
I am trying to recover the backface irradiances with the new API.
Probably i am just missing something, but I can't find a way to quickly recover the indexes.
I am doing this:

def individual_report(pvarray:OrderedPVArray, row:int=0): 
    back_surface_list = pvarray.ts_pvrows[row].back.list_segments
    return pd.DataFrame({f'qinc_{s.index}':s.get_param_weighted('qinc') for s in back_surface_list})

but the s.index is always none.
If I index using all_ts_surfaces I get way too much segments. I know that al surfaces are listed, including shaded elements.
Any tips?

qabs per m^2 per hour to high

Hi there,
Thanks a lot for making pvfactors free available!
I am currently using it for my master thesis, calculating the effect of the albedo of red soil on the performance of bifacial modules in Ghana.
I am doing a full year simulation and somehow my qabs values are to high. For example
Simulation with 35 degree tilt angle, fixed axis, albedo: 0,3:
Yearly Energy Output : 1742kWh/m2
Max. qabs front: 1410 kWh/m2 (22. of April, 12:00h)

The radiation on this day is:
Global: 967W/m2
Direct: 747 W/m2
Diffuse: 225W/m2
--> the concluding qabs on front don't make any sense, because its to high.

I am lost in finding the error, have you ever experienced something similar?

Best wishes,
Eva

Opportunities to improve the online documentation

Here's are two things that would be nice to have in the docs, derived largely or entirely from conversation with @spaneja:

Relevant class methods don't have their own docs page

For example: PVEngine has its own page (link), but its fit() method does not, making it hard to know what parameters the method takes (without referring to the tutorials, anyway). I think it should be straightforward to get this working just with sphinx configuration changes.

Irradiance component names and meanings are not documented

It's possible to extract not only total incident and absorbed irradiance but also various sub-components. The docs have an example of this:

"# Get the calculated outputs from the pv array\n",
"center_row_front_incident_irradiance = pvarray.ts_pvrows[1].front.get_param_weighted('qinc')\n",
"left_row_back_reflected_incident_irradiance = pvarray.ts_pvrows[0].back.get_param_weighted('reflection')\n",
"right_row_back_isotropic_incident_irradiance = pvarray.ts_pvrows[2].back.get_param_weighted('isotropic')\n",

It would be nice for the available component names (e.g. reflection) to be listed somewhere, along with specific descriptions of what each name refers to (e.g. does reflection include ground-reflected irradiance, or just row-row reflections?).

Getting odd jumps in incident light from 179 degrees panel azimuth to 180 degrees

Hi all.

I'm getting weird jumps in irradiances when going from a surface azimuth of 179 degrees to 180 degrees. I can see this in two-row arrays, three-row arrays, and four-row arrays (though it's less pronounced with more rows). I can find it in the front and back irradiances.

I found this when looping the same TMY weather file through pvfactors, but using azimuths of 90 to 270 degrees in 1-degree increments (experimenting with using pvfactors to find optimal orientations for solar panels in different parts of Canada). Otherwise, I hold everything else constant.

image

Steps:

  1. I set up a basic pvarray
  2. I use the same TMY file for ghi, dni, and dhi, and time steps
  3. I apply pvlib’s solpos to the TMY’s times and dates to determine solar positions
  4. I pass all these into pvfactors’s engine.fit function while iterating the surface azimuth from 90 degrees to 270 degrees. I use a constant surface tilt.
  5. I sum the irradiance for each column (e.g., qinc_back_0) to get total, annual irradiance
  6. Result: I get weird irradiance bumps (up and down) around 180 degrees (this doesn't happen when I change tilts from 0 to 90 degrees in 1-degree increments).

Thoughts?
Azimuth testing code.txt

468653_59.53_-111.46_tmy.txt
*** Note *** the TMY txt file needs to be converted to CSV (GitHub wouldn't let me upload a CSV for some reason)

incident light by azimuth - 2 rows.xlsx

edited to fix something, though still get those jumps

Problem with timestamps when using engine.fit

So I am following the tutorial about running a full timeseries simulation using pvfactors([https://sunpower.github.io/pvfactors/tutorials/Run_full_timeseries_simulations.html#Run-single-timestep-with-PVEngine-and-inspect-results]). The problem is that the parameter timestamps does not seem to work properly, I already tried to convert my datetime data to a list or a numpy object but it didn't work as well, I get always my data starting at 5am (not sincronized with the other provided parameter for that time, but instead it just follows the sequential order). Well, the timeseries I am is the one provided by #pvlib so idk what is happening. I hope someone can help me with this issue, thank u in advance.

Don't install matplotlib by default

matplotlib is SO HEAVY. Let's make it an optional install.

Also, I'm not convinced that future or six are needed anymore, and it would be nice to move from setup.py to pyproject.toml.

My biggest concern is breaking pvlib-python consumption.

Update Python 3 version support

https://github.com/pvlib/pvlib-python/tree/v0.6.3 lists Python 3.4-7 support (see https://github.com/pvlib/pvlib-python/blob/v0.6.3/setup.py). pvfactors is listed as optional, but is called out in the CI requirements for the Python 3.5-7 runs, but Python 3.4 is not included (e.g., https://github.com/pvlib/pvlib-python/blob/v0.6.3/ci/requirements-py34.yml vs. https://github.com/pvlib/pvlib-python/blob/v0.6.3/ci/requirements-py37.yml).

pvfactors should be more clear about which Python 3 versions are supported in the CLASSIFIERS variable in https://github.com/SunPower/pvfactors/blob/master/setup.py (e.g., more than just 'Programming Language :: Python :: 3.6'). It would also be worth checking that the dependency ranges in https://github.com/SunPower/pvfactors/blob/master/requirements.txt are indeed compatible with those Python 3 versions. (It might be nice to be more specific about Python 2 versions as well.)

Front-side irradiance is not affected by horizon_band_angle

Changing the horizon_band_angle input to HybridPerezOrdered doesn't seem to affect front-side irradiance nearly as much as it does rear-side. Code to reproduce:

from pvfactors.geometry import OrderedPVArray
from pvfactors.engine import PVEngine
from pvfactors.irradiance.models import HybridPerezOrdered
import pandas as pd
import numpy as np

times = pd.to_datetime(['2019-06-01 12:00'])
dni = np.array([600])
dhi = np.array([100])
solar_zenith = np.array([45])
solar_azimuth = np.array([270])
surface_tilt = np.array([45])
surface_azimuth = np.array([270])
albedo = np.array([0.25])

def build_report(pvarray):
    row = pvarray.ts_pvrows[1]
    return {
        'front': row.front.get_param_weighted('qabs')[0],
        'back': row.back.get_param_weighted('qabs')[0],
    }

for band_angle in [5, 15]:
    irradiance_model = HybridPerezOrdered(horizon_band_angle=band_angle)
    pvarray = OrderedPVArray(n_pvrows=3, pvrow_height=1, pvrow_width=1, axis_azimuth=180, gcr=0.5)
    engine = PVEngine(pvarray, irradiance_model=irradiance_model)
    engine.fit(times, dni, dhi, solar_zenith, solar_azimuth, surface_tilt, surface_azimuth, albedo)
    out = engine.run_full_mode(fn_build_report=build_report)
    print(f'band_angle = {band_angle}\t-->', out)
band_angle = 5  --> {'front': 737.1206177322375, 'back': 43.08209190810574}
band_angle = 15 --> {'front': 737.1517229315606, 'back': 50.38605014260793}

Looking at HybridPerezOrdered.transform, I guess the horizon band shading calculation for the front is done differently from the rear. In fact it's not clear to me that horizon band shading is calculated at all for the front side, but maybe I'm missing it. If it is, I would naively expect horizon band shading loss to be more or less the same for front and rear side. @anomam any thoughts? :)

add package to conda

When running our software in production we usually create the conda environment using conda and an environment.yml file so it would be useful to be able to install pvfactors from a conda channel.
I tried using the command "conda skeleton pypi pvfactors" to then build the conda package but was having some trouble pointing to the requirements.txt file.

back irradiance

I am comparing the model with data from our installation and I am always overestimating back irradiance, mostly on winter.
I am comparing qinc from the back of the pvrow to my reference cell data. Should I also consider reflection and iso?
back_irradiance_compare
I took the back irradiance from the surface element equivalent to the reference cell position.

Drop Python 2 support

Python 2 reached its end of life on 2020-01-01. It's been a year now, so it's time to drop support for it in pvfactors to take advantage of all the great new features of Python 3.

Add pvfactor to PyPI

It would be really useful to add pvfactors to PyPI so that we can: pip install pvfactors.

CI is failing in master

Tests started failing after merging PR #110 (probably unrelated though):

  • somehow I missed that CI didn't run for that PR, need to look into that
  • tests failed for python 3.7 & 3.6 with Too long with no output (exceeded 10m0s): context deadline exceeded, first time seeing that
  • installation failed for python 2.7 with pyrsistent requires Python '>=3.5' but the running Python is 2.7.14

Runtime scales poorly with n_pvrows

Oftentimes it is desirable to neglect edge effects to model a row in the interior of a large array. Unfortunately, it seems that the runtime scaling with n_pvrows is quite bad -- I'm having trouble pinning down the degree of the asymptotic polynomial complexity (if it even is polynomial, might be factorial?), but it's certainly not linear or even quadratic:

image

The good news is that going all the way to n_pvrows > 30 is overkill for making edge effects negligible -- n_pvrows=11 seems pretty good, at least for this array geometry:

image

The bad news is that n_pvrows=11 is still an order of magnitude slower than n_pvrows=3, the current default in the pvlib wrapper function. The code for the above plots is available here: https://gist.github.com/kanderso-nrel/e88e3f7389b9d144a546dbe5651dfe1e

I've not looked into how we might go about improving this situation. If I had to guess, it would require a pretty substantial refactor, if it's possible at all. It would be a pleasant surprise if that guess is incorrect :) But even if it can't be fixed, I think it's useful to have an issue documenting this effect.

Implement Backtracking Algorithm

It's possible that the package already incorporates a backtracking algorithm, but I cannot find documentation stating so. If not, could this be a feature that gets implemented?

Discretizing ground surfaces and variable albedos

Hello @renegacitua,

I'm creating a Github issue for the question you asked in #119 so that I can better keep track of things, and so that other people with similar questions may easily find it.

Hi, i'm starting to use pvfactors, is a really great tool, but i had a question. Is the program capable of discretizing the terrain? I mean, I know that it consider the "cut points" and the shadow and not shadow areas, but it can consider a certain zone where I can consider a bigger value of albedo?
In other words, i want to quantify the impact of install a reflective surface on the front or under of the PV row, is this possible with pvfactors? What would you recommend me for this?
I appreciate your help, regards!

Getting irradiance value for a specific segment

Hi @anomam ,

Thanks for developing a great package to model backside irradiance.

I am trying to implement pvfactors in my research on modelling agrivoltaics technology. Essentially, the goal is to install PV panels on top of a farm and observe the effect of shading on crop growth.

For my modelling, I am interested in getting the irradiance values for a specific segment which will be the row of crops. I know how to get the shadow and illuminated elements from ts_ground and calling .coords for coordinates and get_param_weighted('qinc') for the irradiance values.

However, .coords returns segment that is dynamic and moves at every timestep, so I need to add an extra step to check if the shadow or illuminated elements are at the particular coordinates of interest (the row of crops).

I am wondering if there is an easier way to get the irradiance values for specific coordinates in all of the timesteps? Sorry if this is actually explained in the documentation, I am quite new to coding and using python so I am having difficulties in reading the API part and understanding the overall backend process.

maximum recursion depth with perez_diffuse_luminance

When calling perez_diffuse_luminance irradiance model with a panel configuration where the solar vector is almost orthogonal to the surface normal, the computation falls into an infinite recursion loop.

from pvfactors.irradiance.models import perez_diffuse_luminance

timestamps = ['2020-01-02 15:00:00+00:00']
surface_tilt=[86.43564127244697]
surface_azimuth=[312.7]
solar_zenith=[78.53023197697105]
solar_azimuth=[221.9758276910072]
DNI=[100]
DHI=[50]

perez_diffuse_luminance(
timestamps, surface_tilt, surface_azimuth, solar_zenith,
solar_azimuth, DNI, DHI)
RecursionError: maximum recursion depth exceeded while calling a Python object

This is probably because the dot product of the solar vector and both surface normal (front and back) is computed as negative by pvlib.

from pvlib import irradiance
surface_tilt = 86.43564127244697
surface_azimuth = 312.7
solar_azimuth = 221.9758276910072
solar_zenith = 78.53023197697105
            
irradiance.aoi_projection(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth)
-3.642919299551295e-17

irradiance.aoi_projection(180-surface_tilt, surface_azimuth-180, solar_zenith, solar_azimuth)
-3.642919299551295e-17

Importing pvfactors causes ShapelyDeprecationWarnings for shapely >= 1.8

When using pvfactors with shapely 1.8, ShapelyDeperecationWarnings are issued from shapely when pvfactors assigns custom attributes to shapely geometry objects.

Step to reproduce

  1. Install pvfactors 1.5.1 and shapely 1.8.0
    pip install pvfactors==1.5.1 shapely==1.8.0
  2. Import pvfactors.geometry
    python -c "import pvfactors.geometry"

Observed results
The following warnings are printed to the console:

$ python -c 'import pvfactors.geometry'
lib/python3.9/site-packages/pvfactors/geometry/base.py:349: ShapelyDeprecationWarning: Setting custom attributes on geometry objects is deprecated, and will raise an AttributeError in Shapely 2.0
  self.list_surfaces = list_surfaces
lib/python3.9/site-packages/pvfactors/geometry/base.py:350: ShapelyDeprecationWarning: Setting custom attributes on geometry objects is deprecated, and will raise an AttributeError in Shapely 2.0
  self.shaded = self._get_shading(shaded)
lib/python3.9/site-packages/pvfactors/geometry/base.py:351: ShapelyDeprecationWarning: Setting custom attributes on geometry objects is deprecated, and will raise an AttributeError in Shapely 2.0
  self.is_collinear = is_collinear(list_surfaces)
lib/python3.9/site-packages/pvfactors/geometry/base.py:352: ShapelyDeprecationWarning: Setting custom attributes on geometry objects is deprecated, and will raise an AttributeError in Shapely 2.0
  self.param_names = param_names
lib/python3.9/site-packages/pvfactors/geometry/base.py:937: ShapelyDeprecationWarning: Setting custom attributes on geometry objects is deprecated, and will raise an AttributeError in Shapely 2.0
  self.list_segments = tuple(list_segments)
lib/python3.9/site-packages/pvfactors/geometry/base.py:938: ShapelyDeprecationWarning: Setting custom attributes on geometry objects is deprecated, and will raise an AttributeError in Shapely 2.0
  self._all_surfaces = None

Expected results
The geometry module imports successfully without warnings.

Environment
Operating system: Arch Linux (up-to-date)
Python: 3.9.7 (system python using pyenv-virtualenv)
Packages: pvfactors 1.5.1, shapely 1.8.0

PyPI project authorization

@anomam I have tagged pvfactors at v1.5.2. However, I cannot upload to PyPI using twine because the pvfactors project is not associated with my username campanelli-sunpower. Do I need you to add me in PyPI, or perhaps I ask SunPower IT for this? Please advise. Thanks.

Also, would you provide a name for this release? (I do not know Japanese :).) It's currently a pre-release named TBD at https://github.com/SunPower/pvfactors/releases/tag/v1.5.2.

Request svg version of project logo

Hi! We'd like to see if you have an SVG version of your project logo. We are looking to include it in the LF Energy Landscape ( l.lfenergy.org ) and need this to include it. Thanks in advance!

Feature Request: raise a more informative message when geos_c.dll isn't found

Installing shapely from pip instead of conda is a frequent roadblock for users that haven't been exposed to binary python dependencies:

I see in #106 that the shapely dependency is planned to be dropped in the future -- will that be happening in the near future? If it might be a while, what do you think about wrapping shapely imports in a try/except and raising a new error with a helpful hint about installing shapely from conda instead of pip? If that sounds like a good idea, I'm happy to open a PR -- it might be as simple as just adding something like this at the top of __init__.py, or it might need it everywhere shapely is imported, not sure:

try:
    import shapely
except OSError:
    # can't use "raise from" here because py2.7 doesn't support it.  Or drop 2.7 support, see #107
    raise ImportError("Something helpful about conda vs pip for shapely") 

The future of pvfactors

First of all, I would like to say thank you to the people that help keep pvfactors alive (mostly @kanderso-nrel, and more recently @campanelli-sunpower) and for management at SunPower (@srisukhi @pfranz-spwr) for keeping the repository public even after I left the team.

I'm creating this issue because people have been reaching out to me directly asking about the future of pvfactors, and wondering about the fact that it feels abandoned in spite of a sustained interest by people in the industry using it directly, or via pvlib-python.

So I would like to open this discussion with SunPower (@campanelli-sunpower and @srisukhi, but also @pfranz-spwr ) to understand where the company stands on not only maintaining the code, but also building on top of it (there are feature requests like #120, or what I started in #119, and lots of fun and innovative ideas that can be thought of).

I. situation

What is SunPower's plan for pvfactors? Is there any roadmap for it?

  1. My current impression is that pvfactors as-is currently satisfies the modeling needs of SunPower, and that there will understandably not be much more work done on it. Besides, I do not know if SunPower still has interest or simply resources (time, personnel, ...) to maintain its public modeling repositories such as pvfactors (or PVMismatch, but that's a different discussion).

  2. It was also brought to my intention that there doesn't seem to be much overlap between the people who want/can keep SunPower/pvfactors alive, and the people who have admin/management privileges on the repository (including the CI, release process, etc), which creates some inertia in an already slowly moving package.

II. potential next steps

  1. would SunPower be willing to transfer ownership of pvfactors to a different organization like pvlib?

  2. if not, what does SunPower think about the idea of forking pvfactors into a different organization (and of course use a different name)? (not that any permission is needed, just trying to understand what would work best for everyone)

Get front surface irradiances in fastmode

Hey @anomam,
I am trying to compute irradiances using fast mode (pretty cool btw) and want to be able to recover front irradiances as well that back.
I defined a function as shown in the examples:

def fn_report(pvarray, bf_factor=0.7): 
    return {'front': (pvarray.ts_pvrows[fast_mode_pvrow_index].front.get_param_weighted('qinc')),
            'back':  (bf_factor*pvarray.ts_pvrows[fast_mode_pvrow_index].back.get_param_weighted('qinc'))}

As you can see, I am trying to compute a "weighted" irradiance, but I am unable to recover a front surface irradiance. I get KeyError: 'qinc' for front surface.
Any tips on how to inspect this type of elements to see available quantities, params?

Default MAX_X_GROUND is too small for simulations with many rows

By adjusting the gcr, pvrow_width, and n_pvrows inputs it is possible to simulate arrays covering an arbitrarily large distance. For typical inputs (e.g. n_pvrows=3, pvrow_width=4, gcr=0.4), the spanned distance is relatively small, but it's not wholly unreasonable to model a system with, for example, n_pvrows=15, gcr=0.5, pvrow_width=6, in which case the simulated array spans over 100 meters between the first and last rows. The reason this matters is because the default value of MAX_X_GROUND is 100, so the farthest segments in the scene get ignored entirely in the above extreme example. This leads to strange effects like the following, where legend entries indicate pvrow_height and pvrow_width:

image

Because the row width to height ratio is constant across all three variants, I'd expect the returned irradiance values to be identical. However, they are not, and it's due to an increasingly large portion of the array crossing that MAX_X_GROUND boundary as the array scale increases. By setting MAX_X_GROUND to a number large enough to capture the entire array, the difference disappears and the three curves overlap as expected. Here is some code to reproduce:

Click to expand!
from pvfactors import config
# uncomment these lines to make the three lines overlap
#config.MAX_X_GROUND = 1e3
#config.MIN_X_GROUND = -config.MAX_X_GROUND

import pvfactors
from pvfactors import geometry
import pvlib
import pandas as pd
import matplotlib.pyplot as plt

times = pd.date_range('2019-12-21 11:30', '2019-12-21 13:05', freq='5T', tz='Etc/GMT+5')
loc = pvlib.location.Location(40, -80)
sp = loc.get_solarposition(times)
cs = loc.get_clearsky(times)
tr = pvlib.tracking.singleaxis(sp.zenith, sp.azimuth, gcr=0.5)

data = {}
for height, width in [(1.5, 2.0), (3.0, 4.0), (4.5, 6.0)]:
    ret = pvlib.bifacial.pvfactors_timeseries(sp.azimuth, sp.zenith,
                                              tr.surface_azimuth, tr.surface_tilt,
                                              180, times, cs.dni, cs.dhi,
                                              0.5, height, width, 0.2,
                                              n_pvrows=15, index_observed_pvrow=7)
    data[f'({height}, {width})'] = ret[1]
pd.DataFrame(data).plot(figsize=(7, 4))
plt.ylabel('Rear-Side Irradiance [W/m2]')

For reference, the above plot was generated with pvfactors 1.5.1 and pvlib 0.8.1.


The above scenario is certainly unusual, but I don't think it's out of the realm of reasonable usage. Here are some ideas:

  • Increase the MAX_X_GROUND and MIN_X_GROUND values. I'm not sure what consequences this would have, if any, for more typical simulations.
  • Emit a warning if the simulated array is large enough for the default values to be problematic, for example if any of the rows extends beyond the limit, or maybe any of the ground shadows or something.
  • Mention in the documentation somewhere how to increase these limits on the user's end like I've done in the above example. I think pvfactors.config is not mentioned anywhere in the sphinx docs, though maybe I've just missed it.

cc @spaneja

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.