Repository: pvlib/pvlib-python
Pull request #308 (2017-02-07 19:37:59)

Added coefficients for CIGS and a-Si modules types.
Hi PVLib,

I added coefficients for CIGS and a-Si modules types. I also provided references to document with Spectral Reponses (SRs) of the CIGS and a-Si modules. Reference also includes additional testing and field validation of the model.

wholmgren: Thanks Mitch, the tests look great. Still need to remove the tab from the 'asi' line in the documentation, though. It currently reads...

```
(tab)(4 spaces)* 'asi' - anonymous amorphous silicon PV module
```

but needs to read...

```
[12 spaces]* 'asi' - anonymous amorphous silicon PV module
```

If you can make this change in the next day or two then we can include it in the 0.4.4 release.
MLEEFS: Hi Will. I changed the tab to spaces. Sorry about that. I modified the settings in my text editor, so this should no longer be an issue.  

Quick question. For the cdte, monosi, and polysi coefficients fed into test_first_solar_spectral_correction, why don't they perfectly match what I get when running the provided ams and pws inputs?
wholmgren: No worries, I think everyone gets tripped up by tabs vs. spaces in Python at some point. 

I think the discrepancy is due to the fact that I implemented the algorithm with a preliminary set of coefficients in commit 28cc9fb, then you updated the coefficients in 58d77ea2 but did not update the expected output. The changes to the coefficients must have been small enough that they did not change the output by more than the test's tolerance allowed. Do you want to update them or should we go ahead and merge this? Either way is fine with me.
MLEEFS: Thanks for being patient with my tab issues.

I will update the coefficients. I should commit those by the end of the day.
MLEEFS: Updated M values for unit testing of first_solar_spectral_correction. Hopefully things are good to go. Let me know if any more changes need to be made.
wholmgren: Thanks Mitch!

Patch:
diff --git a/pvlib/atmosphere.py b/pvlib/atmosphere.py
index 0b90094..a61774f 100644
--- a/pvlib/atmosphere.py
+++ b/pvlib/atmosphere.py
@@ -374,10 +374,13 @@ def first_solar_spectral_correction(pw, airmass_absolute, module_type=None,
             * 'cdte' - First Solar Series 4-2 CdTe modules.
             * 'monosi', 'xsi' - First Solar TetraSun modules.
             * 'multisi', 'polysi' - multi-crystalline silicon modules.
+            * 'cigs' - anonymous copper indium gallium selenide PV module
+            * 'asi' - anonymous amorphous silicon PV module
 
         The module used to calculate the spectral correction
         coefficients corresponds to the Mult-crystalline silicon
-        Manufacturer 2 Model C from [3]_.
+        Manufacturer 2 Model C from [3]_. Spectral Response (SR) of CIGS
+        and a-Si modules used to derive coefficients can be found in [4]_ 
 
     coefficients : array-like
         allows for entry of user defined spectral correction
@@ -409,6 +412,10 @@ def first_solar_spectral_correction(pw, airmass_absolute, module_type=None,
     .. [3] Marion, William F., et al. User's Manual for Data for Validating
        Models for PV Module Performance. National Renewable Energy
        Laboratory, 2014. http://www.nrel.gov/docs/fy14osti/61610.pdf
+    .. [4] Schweiger, M. and Hermann, W, Influence of Spectral Effects
+        on Energy Yield of Different PV Modules: Comparison of Pwat and
+        MMF Approach, TUV Rheinland Energy GmbH report 21237296.003,
+        January 2017
     """
 
     # --- Screen Input Data ---
@@ -443,13 +450,17 @@ def first_solar_spectral_correction(pw, airmass_absolute, module_type=None,
 
     _coefficients = {}
     _coefficients['cdte'] = (
-       0.86273, -0.038948, -0.012506, 0.098871, 0.084658, -0.0042948)
+        0.86273, -0.038948, -0.012506, 0.098871, 0.084658, -0.0042948)
     _coefficients['monosi'] = (
         0.85914, -0.020880, -0.0058853, 0.12029, 0.026814, -0.0017810)
     _coefficients['xsi'] = _coefficients['monosi']
     _coefficients['polysi'] = (
         0.84090, -0.027539, -0.0079224, 0.13570, 0.038024, -0.0021218)
     _coefficients['multisi'] = _coefficients['polysi']
+    _coefficients['cigs'] = (
+        0.85252, -0.022314, -0.0047216, 0.13666, 0.013342, -0.0008945)
+    _coefficients['asi'] = (
+        1.12094, -0.047620, -0.0083627, -0.10443, 0.098382,-0.0033818)
 
     if module_type is not None and coefficients is None:
         coefficients = _coefficients[module_type.lower()]


Test patch:
diff --git a/pvlib/test/test_atmosphere.py b/pvlib/test/test_atmosphere.py
index 40e58c7..66fec2a 100644
--- a/pvlib/test/test_atmosphere.py
+++ b/pvlib/test/test_atmosphere.py
@@ -79,17 +79,25 @@ def test_gueymard94_pw():
 
 @pytest.mark.parametrize("module_type,expect", [
     ('cdte', np.array(
-        [[ 0.99134828,  0.97701063,  0.93975103],
-         [ 1.02852847,  1.01874908,  0.98604776],
-         [ 1.04722476,  1.03835703,  1.00656735]])),
+        [[ 0.9905102 ,  0.9764032 ,  0.93975028],
+         [ 1.02928735,  1.01881074,  0.98578821],
+         [ 1.04750335,  1.03814456,  1.00623986]])),
     ('monosi', np.array(
-        [[ 0.9782842 ,  1.02092726,  1.03602157],
-         [ 0.9859024 ,  1.0302268 ,  1.04700244],
-         [ 0.98885429,  1.03351495,  1.05062687]])),
+        [[ 0.9776977 ,  1.02043409,  1.03574032],
+         [ 0.98630905,  1.03055092,  1.04736262],
+         [ 0.98828494,  1.03299036,  1.05026561]])),
     ('polysi', np.array(
-        [[ 0.9774921 ,  1.01757872,  1.02649543],
-         [ 0.98947361,  1.0314545 ,  1.04226547],
-         [ 0.99403107,  1.03639082,  1.04758064]]))
+        [[ 0.9770408 ,  1.01705849,  1.02613202],
+         [ 0.98992828,  1.03173953,  1.04260662],
+         [ 0.99352435,  1.03588785,  1.04730718]])),
+    ('cigs', np.array(
+        [[ 0.9745919 ,  1.02821696,  1.05067895],
+         [ 0.97529378,  1.02967497,  1.05289307],
+         [ 0.97269159,  1.02730558,  1.05075651]])),   
+    ('asi', np.array(
+        [[ 1.0555275 ,  0.87707583,  0.72243772],
+         [ 1.11225204,  0.93665901,  0.78487953],
+         [ 1.14555295,  0.97084011,  0.81994083]]))     
 ])
 def test_first_solar_spectral_correction(module_type, expect):
     ams = np.array([1, 3, 5])