Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
A Python library for calculating thermal and optical properties of glazing systems
Berkeley Lab WINDOW Calc Engine (CalcEngine) Copyright (c) 2016 - 2023, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved.
If you have questions about your rights to use or distribute this software, please contact Berkeley Lab's Innovation & Partnerships Office at IPO@lbl.gov.
NOTICE. This Software was developed under funding from the U.S. Department of Energy and the U.S. Government consequently retains certain rights. As such, the U.S. Government has been granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable, worldwide license in the Software to reproduce, distribute copies to the public, prepare derivative works, and perform publicly and display publicly, and to permit other to do so.
This module provides a simplified method for calculating various thermal and optical properties of glazing systems.
Version 2 has substantially more features but the interface has also changed as a result. For help updating existing code see Migrating from version 1
Version 3 has additional features but should maintain compatability with code written for version 2 with the exception of cases creating user-defined shades. Some methods of creating gases and gaps have been deprecated. If you experience any problems updating code that creates user-defined shades to match the updated examples or problems with gaps or gases please let us know.
Windows requires a version of the Microsoft C++ redistributable >= the version of Visual Studio used to build the library. Currently the wheels on pypi are generated using Visual Studio 16 2019. However in general installing the latest version of the C++ runtime for your architecture should always be sufficient. Installation packages are available from Microsoft here: https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist
The pre-built wheels provided at pypi should work on any x86/x64 version of Linux or Mac that supports at least C++17.
For M2 Macs pre-built wheels are not currently available. From our limited testing building from source (see below) should work. If you have experience problems building from source on a Mac using the M2 architecture please let us know.
CMake - Not required for installing from wheel files on Windows.
Once any needed requirements have been installed:
pip install pywincalc
Once the requirements have been installed this project can be built from source directly from the repository by
pip install git+https://github.com/LBNL-ETA/pyWinCalc.git
Building Python packages from source on Windows is more complicated than Mac/Linux. First the correct C++ compiler first needs to be installed as well as CMake. See https://wiki.python.org/moin/WindowsCompilers for more information about C++ compilers for Python packages on Windows. Once that has been installed pyWinCalc can be built following the build from source steps.
We recognize that there is a fair amount of complexity in the functionality provided by this library. To attempt to mitigate this somewhat we have provided a selection of examples that we hope cover all potential use cases between them. It may be beneficial to begin by looking at whichever example(s) seem to cover your particular use case and then consulting the rest of this and other documentation.
For example, if you are interested in exploring the effect various gas fills have on glazing systems made from combinations of existing commercial glass products contained in the IGSDB you could look at the gaps_and_gases example.
Or if you are interested in seeing all of the possible optical results that can be calculated from the NFRC standard you can find them in the optical_results_NFRC.py example.
Most of the functionality provided by pywincalc is based around a glazing system. That is the solid and gap layers that make up a window not including frames or dividers. One exception is CMA calculations using frames are also provided, see the CMA section for more information about the CMA process and calculations.
For glazing systems calculations can be grouped into two broad categories: optical and thermal calculations.
In the context of this program optical
and thermal
refer to the algorithms used to perform the calculations and not the part of the spectrum used in the calculations. E.g. the calculation for the transmittance in the infrared spectrum is considered an optical calculation here not a thermal calculation.
Optical calculations are based on optical standards which are defined by .std
files and are not affected by environmental conditions. The optical standards define various methods that can be used to generate optical results.
Since optical standards are free to define which methods are provided as well as the names of the methods pywincalc
provides a general way of calculating optical results via a optical_method_results
method in the GlazingSystem class.
There are a few important exceptions to this. See the section on optical calculation details for more details.
Currently only ISO 15099 thermal calculations are supported.
Thermal calculations depend on the environmental conditions and, in some cases, optical results calculated using specific methods. E.g. the SHGC calculations can depend on optical results calculated using the SOLAR
method from the optical standard.
It is important to note that it is possible to calculate thermal results using an optical standard that does not necessarily conform to the ISO 15099 standard so care should be used when selecting which optical standard is used for thermal calculations.
With the exception of wavelength values which are in microns all units are values are in SI base units. However for documentation some units are expressed as more common derived SI units when the values are equivalent. For example:
Calculations can be performed using predefined optical standards in the form that is expected by WINDOW. The path to the base standard files is all that needs to be passed. Any other files referenced by the standard file must be in the same directory (or specified as a relative directory from within the standard file).
Custom standards can be created by creating a new set of files following the same format.
As of version 3.0.0 the standards files are now bundled with the python package so there should be no longer be a need to clone the repository just to get the standards files.
As of version 3.0.0 optical_standard is no longer a required parameter for GlazingSystem. By default a glazing system created without an optical standard will use the NFRC standard as implemented in the W5_NFRC_2003.std file.
The path to the directory the bundled standards files are in is in the pywincalc.standard_path
variable.
Optical standards used by pywincalc are defined using a standards file and usually several related files referenced by the standards file.
For an example standards file see W5_NFRC_2003.std
Each standards file contains sections that define the optical methods provided by the standard. In the W5 NFRC 2003 standard file the first method defined looks like this:
Name : SOLAR
Description : NFRC 300-2003 Solar
Source Spectrum : ASTM E891 Table 1 Direct AM1_5.ssp
Detector Spectrum : None
Wavelength Set : Source
Integration Rule : Trapezoidal
Minimum Wavelength : 0.3
Maximum Wavelength : 2.5
The most important part for using pywincalc is the name of the method. Since optical standard files can set anything for a name pywincalc has one generic method for calculating optical results and two other methods to handle exceptions to the generic rule: THERMAL IR and color calculations. See the section on optical calculation details for more on those two cases.
The choice of standards file affects what can be calculated because not all files implement all methods. For example the prEN_410.std file does not contain a definition of the THERMAL IR method.
Calculations that rely on specific methods will not work if the standard does not provide them. Since the prEN_410.std files does not contain a definition for the thermal IR method the pywincalc.calc_thermal_ir
function will not work.
Solid layers define the glazing or shading products that make up a glazing system. There are several methods for creating solid layers currently supported which use two broad categories of data sources:
In the examples files with "igsdb" in the name use data downloaded from the IGSDB. Files with "user_defined" in the name show how to create objects using data supplied by the user.
It is possible to use data IGSDB in conjunction with user-defined data. E.g. the example file perforated_screen_user_defined_geometry_igsdb_material uses data downloaded from the IGSDB for a shade material and combines that with a user-defined geometry to create a perforated screen.
Here are some examples of each method of creating a solid layer
The following types of solid layers are currently supported:
For systems with more than one solid layer each solid layer must be separated by a gap. The methods for creating gaps currently supported are:
As of version 3.0.0 vacuum gaps are supported.
For examples of each see gaps_and_gases.py in the examples directory.
Shading products require BSDF calculations while glazings do not. If any layer passed to a glazing system is a shading layer the glazing system will also require a BSDF hemisphere. For examples see any of the shade examples e.g. venetian_blind_local_file.py
However it is possible to use BSDF calculations for a system with no shading products. To do so pass a BSDF hemisphere as in the examples with shading systems. For an example that also shows results that are only available for BSDF calculations see optical_results_NFRC.py
If a glazing system is given a BSDF hemisphere as a parameter it will always use that for optical calculations.
Since there are several ways of creating and combining layers plus different calculation options example scripts are provided in the /example directory.
These scripts use optical standards that are included with pywincalc. Some scripts use measured data for example products provided in the /examples/products directory.
A minimum example might look like this
import pywincalc
clear_3_path = "products/CLEAR_3.DAT"
clear_3 = pywincalc.parse_optics_file(clear_3_path)
solid_layers = [clear_3]
glazing_system = pywincalc.GlazingSystem(solid_layers=solid_layers)
print("Single Layer U-value: {u}".format(u=glazing_system.u()))
Please see the following examples which contain more information.
The examples names have the following meanings:
igsdb
means the example downloads data from the IGSDBuser-defined
means the example does not use a completely defined existing product. This could be anything from using a pre-defined material to make a shade to using user-defined measured spectral data.NOTE: The igsdb examples require the python requests library and an API token for igsdb.lbl.gov. An API token can be obtained by creating an account there. See https://igsdb.lbl.gov/about/ for more information on creating an account.
These are files in the example folder that provide some functionality but are not calculation examples.
If there is something you are trying to calculate that does not exist as an example yet please contact us.
As of version 3.0.0 if you create a GlazingSystem without an optical standard it will default to using the NFRC optical standard and optical_standard is not required.
method_name
at theta and phi incidence angle. Returns an OpticalResults
object containing all of the results. See Optical Results section below.Most optical results can be calculated by passing the name of the optical method to the optical_method_results
method of the GlazingSystem
. However there are two exceptions:
COLOR_TRISTIMX
, COLOR_TRISTIMY
, and COLOR_TRISTIMZ
. While it is possible to calculate results for each of these methods individually the results will not give accurate color information.THERMAL IR
method. Thermal IR optical results are only available for a single layer and cannot be calculated for a system. These results should be calculated using the calc_thermal_ir
function.There are two types of optical results available: those calculated from any method that is not a color method and color results. Color calculations are a special case and therefore have their own method used to calculate them and their own results structure. The differences between color results and other optical results is discussed in the section below.
An OpticalResults
object has two parts: system_results
and layer_results
.
system_results
apply to the system as a whole and are objects nested as follows: system_results.side.transmission_type.flux_type
With the following options available for each
front
, back
transmittance
, reflectance
direct_direct
, direct_diffuse
, direct_hemispherical
, diffuse_diffuse
, matrix
direct_hemisperical
= direct_direct
+ direct_diffuse
E.g. the direct-diffuse front reflectance is system_results.front.reflectance.direct_diffuse
layer_results
contain a list of results corresponding to each solid layer. Results for both sides are provided for each layer. Currently the only supported result per side is absorptance. Absorptance is available for both direct and diffuse cases.
As of version 2.4.0 absorptance results are available as heat and electricity. Electricity absoprtance is only non-zero for layers with PV data. The following results are available for each side of each layer:
total_direct, total_diffuse, heat_direct, heat_diffuse, electricity_direct, electricity_diffuse, direct, diffuse
NOTE: direct and diffuse are deprecated and equal to total_direct and total_diffuse.
As of version 3.0.0 angular absorptance results are also available. These results are only available for systems that have a BSDF hemisphere.
E.g the diffuse back absorptance for the first solid layer is layer_results[0].back.absorptance.diffuse
Matrix results are only available for systems that have a BSDF basis. See the section on BSDF Calculations for information on how to create and use a BSDF basis. For systems with a BSDF basis the matrix result is a square matrix of the same size as the number of patches in the basis.
The structure of color results is similar to, but different from, the structure of other optical results. There are two main differences. First individual layer results are not yet supported for colors. And second instead of one value at each flux type (direct-direct, direct-diffuse, etc...) color results have RGB, Lab, and Trichromatic values. Those represent the same result mapped into three common color spaces for convenience.
So while for other results results.front.transmittance.direct_direct
would return a single value for colors that returns an object that contains RGB, Lab, and Trichromatic objects. E.g. to get the RGB blue value from a color result this is required: results.front.transmittance.direct_direct.rgb.B
Thermal IR results are only available for a single layer and only have four results available. They are:
transmittance_front_diffuse_diffuse
transmittance_back_diffuse_diffuse
emissivity_front_hemispheric
emissivity_back_hemispheric
Environmental conditions consists of two parts: the inside and outside environment. The exterior environment will be used as the environment before the first solid layer in the system and the interior environment will be used after the last solid layer in the system. Each contains the same fields. To use custom values for thermal calculations create an Environments object from inside and outside Environment objects. See environmental_conditions_user_defined.py
Environment fields:
Pre-constructed NFRC U and SHGC environments are available by calling pywincalc.nfrc_u_environments()
and pywincalc.nfrc_shgc_environments()
There are several options for gases. Gases can be created either from pre-defined gases (e.g. Air, Argon, etc...), by supplying physical parameters to create arbitrary custom gases, or by mixtures containing either predefined or custom gases.
Gases can be created from a PredefinedGasType
. Current supported predefined gas types are: AIR, ARGON, KRYPTON, and XENON.
As of version 3.0.0 the below is deprecated. See See gaps_and_gases.py for the new method of creating gases.
A gap layer can be created from a predefined gas type like so:
gap_1 = pywincalc.Gap(pywincalc.PredefinedGasType.AIR, .0127) # .0127 is gap thickness in meters
A CustomGasData
object can be created by providing the following information:
See gaps_and_gases.py for more on creating custom gases.
Gas mixtures can be created from custom and predefined gases by specifying the percentage of each in the mixtures.
As of version 3.0.0 the below is deprecated. See gaps_and_gases.py for the new method of creating gases.
# The following creates a gas that is 80% sulfur hexafluoride, 15% Argonm and 5% Air
gap_4_component_1 = pywincalc.CustomGasMixtureComponent(sulfur_hexafluoride, 0.8)
gap_4_component_2 = pywincalc.PredefinedGasMixtureComponent(pywincalc.PredefinedGasType.ARGON, .15)
gap_4_component_3 = pywincalc.PredefinedGasMixtureComponent(pywincalc.PredefinedGasType.AIR, .05)
gap_4 = pywincalc.Gap([gap_4_component_1, gap_4_component_2, gap_4_component_3], .025) # 2.5mm thick gap
Complete class documentation generated by pydoc can be found here: https://github.com/LBNL-ETA/pyWinCalc/blob/main/pywincalc_class_documentation.html
See this paper for context and background about the CMA modeling process: Component Modeling Methodology for Predicting Thermal Performance of Non-Residential Fenestration Systems
In THERM, when inserting a glazing system, on the first Glazing Systems dialog box, instead of clicking the "Import" button, click the "NFRC CMA..." button. This will take you to a special "Insert Glazing System" dialog box specifically for the CMA calculation. The THMX file created when this THERM file is saved has the required CMA information in it for use with the pyWinCalc code.
The CMA calculation process can be summarized with the following steps:
The examples folder has the following examples:
Most of the interface in version 2 should work in version 3 with the exception of user-defined shades. Creating shades with user-defined data should hopefully be easier and clearer. There are now factory methods for each non-BSDF shade type: create_perforated_screen
, create_venetian_blind
and create_woven_shade
. See perforated_screen_user_defined_geometry_and_user_defined_nband_material.py, perforated_screen_user_defined_geometry_igsdb_material.py, venetian_blind_user_defined_geometry_igsdb_material.py, venetian_blind_user_defined_geometry_user_defined_dual_band_material.py, vertical_venetian_user_defined_geometry_igsdb_material.py, or woven_shade_user_defined_geometry_igsdb_material.py
Creating gases and gaps has changed but the prior interface has been retained and flagged as deprecated. If you run into any problems with existing code and cannot easily convert it following the examples in gaps_and_gases.py contact us and hopefully we will be able to help.
There were several interface changes that resulted from the new functionality. These changes are mostly contained in two places: The GlazingSystem constructor and the results structures. Each section will start with a guide on how to convert existing code and will follow with some rational and explination. This conversion will convert the code in the v1 example.py file to code that will work in v2.
# Code prior to line 16 in the v1 example.py does not need to be changed
# v1 code
glazing_system_single_layer = pywincalc.Glazing_System(solid_layers, gaps, standard, width, height)
u_results = glazing_system_single_layer.u() # calculate U-value according to ISO15099
print("Single Layer U-value: {u}".format(u=u_results.result))
# v2 code
glazing_system_single_layer = pywincalc.GlazingSystem(optical_standard=optical_standard, solid_layers=solid_layers, width=width, height=height, environment=pywincalc.nfrc_u_environments())
u_result = glazing_system_single_layer.u() # calculate U-value according to ISO15099
print("Single Layer U-value: {u}".format(u=u_result))
# These results are not available in the thermal results but are available in optical results
# See the section on available optical results for how to obtain them
print("Single Layer u t_sol: {t}".format(t=u_results.t_sol))
print("Single Layer u solar absorptances per layer: {a}".format(a=u_results.layer_solar_absorptances))
#v1 code
shgc_results = glazing_system_single_layer.shgc() # calculate SHGC according to ISO15099
print("Single Layer SHGC: {shgc}".format(shgc=shgc_results.result))
# v2 code
# Important Note: While it is still possible to calculate the SHGC value for the
# glazing_system_single_layer system created above it will do so using the NFRC U
# environments. This will not result in the same SHGC as before. To achieve the
# same SHGC as before a glazing system with the correct environment needs to be created
glazing_system_single_layer_nfrc_shgc_env = pywincalc.GlazingSystem(optical_standard=optical_standard, solid_layers=solid_layers, width=width, height=height, environment=pywincalc.nfrc_shgc_environments())
shgc_result = glazing_system_single_layer_nfrc_shgc_env.shgc() # calculate SHGC according to ISO15099
print("Single Layer SHGC: {shgc}".format(shgc=shgc_result))
# v1 code
# These results are not available in the thermal results but are available in optical results
# See the section on available optical results for how to obtain them
print("Single Layer SHGC t_sol: {t}".format(t=shgc_results.t_sol))
print("Single Layer SHGC solar absorptances per layer: {a}".format(a=shgc_results.layer_solar_absorptances))
#v1 code
solar_optical_results_single_layer = glazing_system_single_layer.all_method_values(pywincalc.Method_Type.SOLAR)
# v2 code
solar_optical_results_single_layer = glazing_system_single_layer.optical_method_results("SOLAR")
# v1 code
print("Single Layer Solar optical transmittance front direct-direct: {r}".format(r=solar_optical_results_single_layer.direct_direct.tf))
# v2 code
print("Single Layer Solar optical transmittance front direct-direct: {r}".format(r=solar_optical_results_single_layer.system_results.front.transmittance.direct_direct))
# v1 code
gap_1 = pywincalc.Gap_Data(pywincalc.Gas_Type.AIR, .0127) # .0127 is gap thickness in meters
gap_2 = pywincalc.Gap_Data(pywincalc.Gas_Type.ARGON, .02) # .02 is gap thickness in meters
# v2 code
gap_1 = pywincalc.Gap(pywincalc.PredefinedGasType.AIR, .0127) # .0127 is gap thickness in meters
gap_2 = pywincalc.Gap_Data(pywincalc.PredefinedGasType.ARGON, .02) # .02 is gap thickness in meters
# v1 code
tf_rgb_results_triple_layer = color_results_triple_layer.direct_direct.tf.rgb
print("Triple Layer color results transmittance front direct-direct RGB: ({r}, {g}, {b})".format(r=tf_rgb_results_triple_layer.R, g=tf_rgb_results_triple_layer.G, b=tf_rgb_results_triple_layer.B))
# v2 code
tf_rgb_results_triple_layer = color_results_triple_layer.system_results.front.transmittance.direct_direct.rgb
print("Triple Layer color results transmittance front direct-direct RGB: ({r}, {g}, {b})".format(r=tf_rgb_results_triple_layer.R, g=tf_rgb_results_triple_layer.G, b=tf_rgb_results_triple_layer.B))
First Glazing_System was changed to GlazingSystem to be more in line with python's naming conventions.
Second the GlazingSystem constructor parameter order changed and there are additional paramters that can be passed in. All parameters are now able to be passed using keywords. e.g.
glazing_system = pywincalc.GlazingSystem(optical_standard=optical_standard, solid_layers=solid_layers)
Finally there is a change to how environmental conditions are handled. In v1 GlazingSystem had two built-in environments -- NFRC U and NFRC SHGC. In v2 a GlazingSystem has one environment passed in as a parameter. This allows for any environmental conditions to be used in thermal calculations.
For convenience there are methods to get the NFRC envionmnents, pywincalc.nfrc_u_environments()
and pywincalc.nfrc_shgc_environments()
To create custom environments see the Environments section above.
However this means that some care should be taken when constructing glazing systems for thermal results. The NFRC U and SHGC environments are simply standardized environmental conditions used by NFRC to generate their respective thermal result. But any environmental conditions can be used to calculate both U and SHGC values.
For example, in the example.py file in v1 there is code to get U and SHGC values that looks like this
u_results = glazing_system_single_layer.u() # calculate U-value according to ISO15099
shgc_results = glazing_system_single_layer.shgc() # calculate SHGC according to ISO15099
That behavior used to calculate U and SHGC from the respective built-in environments. Now in order to do the equivalent two glazing systems need to be created:
glazing_system_nfrc_u_env = pywincalc.GlazingSystem(optical_standard=optical_standard, solid_layers=solid_layers, environment=pywincalc.nfrc_u_environments())
glazing_system_nfrc_shgc_env = pywincalc.GlazingSystem(optical_standard=optical_standard, solid_layers=solid_layers, environment=pywincalc.nfrc_shgc_environments())
nfrc_u_value = glazing_system_nfrc_u_env.u()
nfrc_shgc_value = glazing_system_nfrc_shgc_env.shgc()
Or one glazing system can be created with one set of environmental conditions, run calculations, and then change the environmental conditions and run different calculations:
glazing_system = pywincalc.GlazingSystem(optical_standard=optical_standard, solid_layers=solid_layers, environment=pywincalc.nfrc_u_environments())
nfrc_u_value = glazing_system.u()
glazing_system.environments(pywincalc.nfrc_shgc_environments())
nfrc_shgc_value = glazing_system.shgc()
The all_method_results
function has been renamed to optical_method_results
. It still requires an optical method but now also accepts optional theta and phi values for angular calculations.
The top level object returned by the optical_method_results
now has two components: system_results and layer_results. As the names imply system_results contains results that apply to the system as a whole while layer_results have results on a per-solid-layer basis.
Under system_results
then it goes side (front
or back
), then transmittance
or reflectance
, then flux type (direct-direct
, direct-diffuse
, direct-hemispherical
, diffuse-diffuse
, or matrix
)
GlazingSystem.u()
and GlazingSystem.shgc()
now return single values
Both u()
and shgc()
take optional theta
and phi
values for angular calculations. Both theta
and phi
default to zero so if neither are provided the result will be for normal incidence angle.
Note: This should only be used for creating glazing layers with PV properties. This format is not yet supported for any other solid layer types.
Please refer to the generic_pv.json file provided for a working example.
FAQs
A Python library for calculating thermal and optical properties of glazing systems
We found that pywincalc demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.