CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-openstudio

Cross-platform collection of software tools to support whole building energy modeling using EnergyPlus and advanced daylight analysis using Radiance

Pending
Overview
Eval results
Files

radiance.mddocs/

Daylight Analysis

Integration with Radiance for advanced daylight and lighting analysis capabilities. The Radiance module provides comprehensive daylight simulation tools including illuminance mapping, glare analysis, and annual daylight metrics, enabling detailed lighting design and energy-efficient daylighting strategies.

Capabilities

Model Translation

Conversion of OpenStudio models to Radiance format for daylight simulation.

/**
 * Converts OpenStudio models to Radiance simulation format
 */
namespace radiance {

class ForwardTranslator {
public:
  // Constructor
  ForwardTranslator();
  
  // Model translation
  std::vector<Path> translateModel(const Path& outPath, const Model& model);
  std::vector<Path> translateModel(const Path& outPath, 
                                   const Model& model, 
                                   const std::vector<Space>& spaces);
  
  // Space-specific translation
  std::vector<Path> translateSpace(const Path& outPath, const Space& space);
  std::vector<Path> translateSpaces(const Path& outPath, 
                                    const std::vector<Space>& spaces);
  
  // Surface translation
  std::vector<Path> translateSurface(const Path& outPath, const Surface& surface);
  std::vector<Path> translateSubSurface(const Path& outPath, const SubSurface& subSurface);
  
  // Material translation
  std::vector<Path> translateMaterials(const Path& outPath, const Model& model);
  Path translateMaterial(const Path& outPath, const Material& material);
  
  // Translation options
  RadianceParameters radianceParameters() const;
  void setRadianceParameters(const RadianceParameters& radianceParameters);
  
  // Error and warning handling
  std::vector<LogMessage> errors() const;
  std::vector<LogMessage> warnings() const;
  
  // Generated files
  std::vector<Path> radianceFiles() const;
  std::vector<Path> octreeFiles() const;
};

/**
 * Radiance simulation parameters and settings
 */
class RadianceParameters {
public:
  // Constructor
  RadianceParameters();
  
  // Ambient bounces
  boost::optional<int> ambientBounces() const;
  bool setAmbientBounces(int ambientBounces);
  void resetAmbientBounces();
  
  // Ambient divisions
  boost::optional<int> ambientDivisions() const;
  bool setAmbientDivisions(int ambientDivisions);
  void resetAmbientDivisions();
  
  // Ambient super-samples
  boost::optional<int> ambientSupersamples() const;
  bool setAmbientSupersamples(int ambientSupersamples);
  void resetAmbientSupersamples();
  
  // Limit reflection
  boost::optional<int> limitReflection() const;
  bool setLimitReflection(int limitReflection);
  void resetLimitReflection();
  
  // Limit weight
  boost::optional<double> limitWeight() const;
  bool setLimitWeight(double limitWeight);
  void resetLimitWeight();
  
  // Grid resolution
  boost::optional<double> gridResolution() const;
  bool setGridResolution(double gridResolution);
  void resetGridResolution();
  
  // Sensor height
  boost::optional<double> sensorHeight() const;
  bool setSensorHeight(double sensorHeight);
  void resetSensorHeight();
};

}

Usage Examples:

#include <openstudio/radiance/ForwardTranslator.hpp>
#include <openstudio/model/Model.hpp>

using namespace openstudio;
using namespace openstudio::model;
using namespace openstudio::radiance;

// Load OpenStudio model
boost::optional<Model> model = Model::load(Path("office_building.osm"));

if (model) {
  // Set up Radiance translator
  ForwardTranslator ft;
  
  // Configure simulation parameters
  RadianceParameters params;
  params.setAmbientBounces(3);
  params.setAmbientDivisions(1000);
  params.setGridResolution(0.5); // 0.5m grid spacing
  ft.setRadianceParameters(params);
  
  // Translate model to Radiance
  Path radianceDir("radiance_simulation");
  std::vector<Path> radianceFiles = ft.translateModel(radianceDir, *model);
  
  // Check translation results
  std::vector<LogMessage> errors = ft.errors();
  if (errors.empty()) {
    std::cout << "Radiance translation successful!" << std::endl;
    std::cout << "Generated " << radianceFiles.size() << " Radiance files" << std::endl;
  } else {
    for (const auto& error : errors) {
      std::cout << "Translation error: " << error.logMessage() << std::endl;
    }
  }
}

Illuminance Analysis

Tools for calculating and analyzing illuminance levels and daylight distribution.

/**
 * Annual illuminance map generation and analysis
 */
class AnnualIlluminanceMap {
public:
  // Constructors
  AnnualIlluminanceMap();
  AnnualIlluminanceMap(const Path& path);
  
  // File I/O
  static boost::optional<AnnualIlluminanceMap> load(const Path& path);
  bool save(const Path& path) const;
  
  // Illuminance data access
  boost::optional<Matrix> illuminanceMap() const;
  std::vector<double> illuminanceValues() const;
  std::vector<DateTime> dateTimes() const;
  
  // Grid properties
  unsigned xPoints() const;
  unsigned yPoints() const;
  double xSpacing() const;
  double ySpacing() const;
  
  // Statistical analysis
  boost::optional<double> minimumIlluminance() const;
  boost::optional<double> maximumIlluminance() const;
  boost::optional<double> averageIlluminance() const;
  boost::optional<double> medianIlluminance() const;
  
  // Daylight metrics
  boost::optional<double> spatialDaylightAutonomy(double threshold = 300.0) const;
  boost::optional<double> continuousDaylightAutonomy(double threshold = 300.0) const;
  boost::optional<double> annualSunlightExposure(double threshold = 1000.0) const;
  
  // Time-based analysis
  std::vector<double> illuminanceAtTime(const DateTime& dateTime) const;
  std::vector<double> illuminanceAtPoint(unsigned x, unsigned y) const;
  
  // Zone-based metrics
  boost::optional<double> zoneAverageIlluminance() const;
  boost::optional<double> uniformityRatio() const;
};

/**
 * Point-in-time illuminance calculations
 */
class IlluminanceMap {
public:
  // Constructor
  IlluminanceMap();
  IlluminanceMap(const Space& space);
  
  // Grid definition
  void setXSpacing(double xSpacing);
  void setYSpacing(double ySpacing);
  void setOriginXCoordinate(double originX);
  void setOriginYCoordinate(double originY);
  void setOriginZCoordinate(double originZ);
  
  double xSpacing() const;
  double ySpacing() const;
  double originXCoordinate() const;
  double originYCoordinate() const;
  double originZCoordinate() const;
  
  // Grid points
  std::vector<Point3d> referencePoints() const;
  unsigned numberofXGridPoints() const;
  unsigned numberofYGridPoints() const;
  
  // Space association
  boost::optional<Space> space() const;
  bool setSpace(const Space& space);
  
  // Illuminance calculation
  std::vector<double> calculateIlluminance(const std::vector<double>& skyValues) const;
  Matrix calculateIlluminanceMatrix(const Matrix& skyMatrix) const;
};

/**
 * Daylighting control and sensor modeling
 */
class DaylightingControl : public SpaceLoadInstance {
public:
  // Constructor
  DaylightingControl(const Model& model);
  
  // Position
  double positionXCoordinate() const;
  bool setPositionXCoordinate(double positionXCoordinate);
  
  double positionYCoordinate() const;
  bool setPositionYCoordinate(double positionYCoordinate);
  
  double positionZCoordinate() const;
  bool setPositionZCoordinate(double positionZCoordinate);
  
  // Sensor orientation
  double psiRotationAroundXAxis() const;
  bool setPsiRotationAroundXAxis(double psiRotation);
  
  double thetaRotationAroundYAxis() const;
  bool setThetaRotationAroundYAxis(double thetaRotation);
  
  double phiRotationAroundZAxis() const;
  bool setPhiRotationAroundZAxis(double phiRotation);
  
  // Control parameters
  double illuminanceSetpoint() const;
  bool setIlluminanceSetpoint(double illuminanceSetpoint);
  
  boost::optional<double> lightingControlSteps() const;
  bool setLightingControlSteps(double lightingControlSteps);
  void resetLightingControlSteps();
  
  double lightingControlProbability() const;
  bool setLightingControlProbability(double lightingControlProbability);
  
  // Glare control
  boost::optional<double> glareCalculationAzimuthAngleofViewDirectionClockwisefromZoneyAxis() const;
  bool setGlareCalculationAzimuthAngleofViewDirectionClockwisefromZoneyAxis(double angle);
  
  boost::optional<double> maximumAllowableDiscomfortGlareIndex() const;
  bool setMaximumAllowableDiscomfortGlareIndex(double index);
};

Window Groups and Daylighting

Advanced window modeling and daylight analysis for complex fenestration systems.

/**
 * Window group for coordinated daylighting analysis
 */
class WindowGroup {
public:
  // Constructor
  WindowGroup();
  WindowGroup(const std::vector<SubSurface>& subSurfaces);
  
  // Window management
  std::vector<SubSurface> subSurfaces() const;
  bool addSubSurface(const SubSurface& subSurface);
  bool removeSubSurface(const SubSurface& subSurface);
  void clearSubSurfaces();
  
  // Group properties
  boost::optional<std::string> name() const;
  void setName(const std::string& name);
  
  boost::optional<double> windowGroupRendering() const;
  void setWindowGroupRendering(double windowGroupRendering);
  
  // Window group control
  boost::optional<Construction> windowGroupConstruction() const;
  void setWindowGroupConstruction(const Construction& construction);
  
  boost::optional<ShadingControl> windowGroupShadingControl() const;
  void setWindowGroupShadingControl(const ShadingControl& shadingControl);
  
  // Daylight matrix generation
  std::vector<Path> generateDaylightMatrix(const Path& outputDir,
                                          const RadianceParameters& parameters) const;
  
  // View matrix calculation
  Matrix calculateViewMatrix(const std::vector<Point3d>& sensorPoints,
                            const RadianceParameters& parameters) const;
};

/**
 * Three-phase method daylight calculation
 */
class ThreePhaseMethod {
public:
  // Constructor
  ThreePhaseMethod();
  
  // Matrix components
  void setViewMatrix(const Matrix& viewMatrix);
  void setDaylightMatrix(const Matrix& daylightMatrix);
  void setSkyMatrix(const Matrix& skyMatrix);
  
  Matrix viewMatrix() const;
  Matrix daylightMatrix() const;
  Matrix skyMatrix() const;
  
  // Calculation
  Matrix calculateIlluminance() const;
  std::vector<double> calculateAnnualIlluminance(const std::vector<DateTime>& dateTimes) const;
  
  // Sky conditions
  void setClearSky();
  void setOvercastSky();
  void setIntermediateSky();
  void setCustomSky(const Matrix& skyRadiance);
  
  // Window state management
  void setWindowState(const WindowGroup& windowGroup, const std::string& state);
  std::map<WindowGroup, std::string> windowStates() const;
};

Radiance Utilities and Support

Helper classes for Radiance file management and simulation control.

/**
 * Radiance file header information
 */
class HeaderInfo {
public:
  // Constructor
  HeaderInfo();
  
  // Header fields
  std::string creator() const;
  void setCreator(const std::string& creator);
  
  DateTime creationDate() const;
  void setCreationDate(const DateTime& date);
  
  std::string description() const;
  void setDescription(const std::string& description);
  
  std::string format() const;
  void setFormat(const std::string& format);
  
  // View information
  boost::optional<std::string> view() const;
  void setView(const std::string& view);
  void resetView();
  
  // Resolution
  boost::optional<int> xResolution() const;
  boost::optional<int> yResolution() const;
  void setResolution(int x, int y);
  
  // File generation
  std::string generateHeader() const;
};

/**
 * Radiance utility functions
 */
namespace Utils {
  
  // File path utilities
  Path radianceDirectory();
  Path radianceBinDirectory();
  Path radianceLibDirectory();
  
  // Executable paths
  Path rpictPath();
  Path rtracePath();
  Path rviewPath();
  Path oconvPath();
  Path genDayMtxPath();
  
  // Sky generation
  Path generateClearSky(const Path& outputDir,
                       const DateTime& dateTime,
                       double latitude,
                       double longitude,
                       double timeZone);
  
  Path generateOvercastSky(const Path& outputDir);
  
  Path generateIntermediateSky(const Path& outputDir,
                              const DateTime& dateTime, 
                              double latitude,
                              double longitude,
                              double timeZone,
                              double cloudCover);
  
  // Weather file processing
  std::vector<Matrix> generateAnnualSkyMatrix(const Path& weatherFile,
                                             const Path& outputDir);
  
  Matrix generateSkyMatrix(const std::vector<DateTime>& dateTimes,
                          const std::vector<double>& directNormalIrradiance,
                          const std::vector<double>& diffuseHorizontalIrradiance);
  
  // Simulation execution
  bool runRadianceSimulation(const Path& octreeFile,
                           const Path& viewFile,
                           const Path& outputFile,
                           const RadianceParameters& parameters);
  
  bool runRtrace(const Path& octreeFile,
                const std::vector<Point3d>& points,
                const std::vector<Vector3d>& directions,
                const Path& outputFile);
  
  // Result processing
  std::vector<double> parseIlluminanceResults(const Path& resultsFile);
  Matrix parseMatrixResults(const Path& matrixFile);
  
  // File validation
  bool validateRadianceFile(const Path& radianceFile);
  bool validateOctreeFile(const Path& octreeFile);
}

Annual Daylight Metrics

Comprehensive daylight performance metrics and analysis tools.

/**
 * Annual daylight performance metrics calculation
 */
class AnnualDaylightMetrics {
public:
  // Constructor from illuminance map
  AnnualDaylightMetrics(const AnnualIlluminanceMap& illuminanceMap);
  
  // Daylight Autonomy (DA)
  double daylightAutonomy(double threshold = 300.0) const;
  Matrix daylightAutonomyMap(double threshold = 300.0) const;
  
  // Continuous Daylight Autonomy (cDA)
  double continuousDaylightAutonomy(double threshold = 300.0) const;
  Matrix continuousDaylightAutonomyMap(double threshold = 300.0) const;
  
  // Spatial Daylight Autonomy (sDA)
  double spatialDaylightAutonomy(double threshold = 300.0, double areaThreshold = 0.50) const;
  
  // Annual Sunlight Exposure (ASE)
  double annualSunlightExposure(double threshold = 1000.0, double areaThreshold = 0.10) const;
  Matrix annualSunlightExposureMap(double threshold = 1000.0) const;
  
  // Useful Daylight Illuminance (UDI)
  struct UDIBins {
    double fell_short;    // < 100 lux
    double supplementary; // 100-300 lux
    double autonomous;    // 300-3000 lux
    double exceeded;      // > 3000 lux
  };
  
  UDIBins usefulDaylightIlluminance() const;
  std::map<std::string, Matrix> usefulDaylightIlluminanceMaps() const;
  
  // Daylight Glare Probability (DGP) - requires view analysis
  boost::optional<double> daylightGlareProbability() const;
  void setDaylightGlareProbability(double dgp);
  
  // Climate-based daylight modeling
  double climaticAvailability() const;
  std::vector<double> monthlyDaylightAvailability() const;
  
  // Summary statistics
  struct DaylightSummary {
    double mean_illuminance;
    double median_illuminance;
    double min_illuminance;
    double max_illuminance;
    double uniformity_ratio;
    double daylight_autonomy;
    double spatial_daylight_autonomy;
    double annual_sunlight_exposure;
  };
  
  DaylightSummary generateSummary() const;
};

Common Usage Patterns

Basic Radiance Translation and Simulation

#include <openstudio/radiance/ForwardTranslator.hpp>
#include <openstudio/radiance/Utils.hpp>

using namespace openstudio;
using namespace openstudio::model;
using namespace openstudio::radiance;

// Load model and set up translation
boost::optional<Model> model = Model::load(Path("daylit_office.osm"));

if (model) {
  // Configure Radiance parameters for high accuracy
  RadianceParameters params;
  params.setAmbientBounces(5);
  params.setAmbientDivisions(1500);
  params.setAmbientSupersamples(100);
  params.setLimitWeight(0.0002);
  
  // Set up translator
  ForwardTranslator ft;
  ft.setRadianceParameters(params);
  
  // Translate specific spaces (e.g., only occupied spaces)
  std::vector<Space> spaces;
  for (const auto& space : model->getConcreteModelObjects<Space>()) {
    // Only translate spaces with people
    if (!space.people().empty()) {
      spaces.push_back(space);
    }
  }
  
  // Translate to Radiance
  Path radianceDir("daylight_analysis");
  std::vector<Path> radianceFiles = ft.translateModel(radianceDir, *model, spaces);
  
  // Generate octree for simulation
  Path octreeFile = radianceDir / "scene.oct";
  // Note: In practice, you would call oconv to generate the octree
  
  // Set up illuminance mapping
  for (const auto& space : spaces) {
    IlluminanceMap illumMap(space);
    illumMap.setXSpacing(0.5); // 0.5m grid
    illumMap.setYSpacing(0.5);
    illumMap.setOriginZCoordinate(0.8); // Desktop height
    
    // Calculate reference points
    std::vector<Point3d> points = illumMap.referencePoints();
    std::cout << "Space '" << space.name().get_value_or("Unnamed") 
              << "' has " << points.size() << " analysis points" << std::endl;
  }
}

Annual Daylight Analysis

#include <openstudio/radiance/AnnualIlluminanceMap.hpp>
#include <openstudio/radiance/AnnualDaylightMetrics.hpp>

using namespace openstudio;
using namespace openstudio::radiance;

// Load annual illuminance results (typically generated by external Radiance tools)
boost::optional<AnnualIlluminanceMap> annualMap = 
  AnnualIlluminanceMap::load(Path("annual_illuminance.ill"));

if (annualMap) {
  // Calculate comprehensive daylight metrics
  AnnualDaylightMetrics metrics(*annualMap);
  
  // Generate summary report
  AnnualDaylightMetrics::DaylightSummary summary = metrics.generateSummary();
  
  std::cout << "Daylight Performance Summary:" << std::endl;
  std::cout << "  Mean Illuminance: " << summary.mean_illuminance << " lux" << std::endl;
  std::cout << "  Daylight Autonomy (300 lux): " << summary.daylight_autonomy * 100 << "%" << std::endl;
  std::cout << "  Spatial DA (sDA300/50%): " << summary.spatial_daylight_autonomy * 100 << "%" << std::endl;
  std::cout << "  Annual Sunlight Exposure (ASE1000/10%): " << summary.annual_sunlight_exposure * 100 << "%" << std::endl;
  
  // Check LEED v4 compliance
  bool leedCompliant = (summary.spatial_daylight_autonomy >= 0.50) && 
                       (summary.annual_sunlight_exposure <= 0.10);
  
  if (leedCompliant) {
    std::cout << "✓ LEED v4 daylight requirements met" << std::endl;
  } else {
    std::cout << "✗ LEED v4 daylight requirements not met" << std::endl;
  }
  
  // Useful Daylight Illuminance analysis
  AnnualDaylightMetrics::UDIBins udi = metrics.usefulDaylightIlluminance();
  
  std::cout << "\nUseful Daylight Illuminance:" << std::endl;
  std::cout << "  Fell Short (<100 lux): " << udi.fell_short * 100 << "%" << std::endl;
  std::cout << "  Supplementary (100-300 lux): " << udi.supplementary * 100 << "%" << std::endl;
  std::cout << "  Autonomous (300-3000 lux): " << udi.autonomous * 100 << "%" << std::endl;
  std::cout << "  Exceeded (>3000 lux): " << udi.exceeded * 100 << "%" << std::endl;
}

Three-Phase Daylight Method

#include <openstudio/radiance/ThreePhaseMethod.hpp>
#include <openstudio/radiance/WindowGroup.hpp>

using namespace openstudio;
using namespace openstudio::radiance;

// Set up three-phase daylight calculation for dynamic shading analysis
Model model;
// ... create model with windows and shading systems ...

// Create window groups for coordinated analysis
std::vector<SubSurface> southWindows;
for (const auto& surface : model.getConcreteModelObjects<Surface>()) {
  if (surface.azimuth() && std::abs(*surface.azimuth() - 180.0) < 45.0) { // South-facing
    for (const auto& subSurface : surface.subSurfaces()) {
      if (subSurface.subSurfaceType() == "FixedWindow" || 
          subSurface.subSurfaceType() == "OperableWindow") {
        southWindows.push_back(subSurface);
      }
    }
  }
}

WindowGroup southWindowGroup(southWindows);
southWindowGroup.setName("South Windows");

// Set up three-phase calculation
ThreePhaseMethod threePhase;

// Generate daylight matrices for different shading states
RadianceParameters params;
params.setAmbientBounces(3);
params.setAmbientDivisions(1000);

// Calculate for clear glazing state
southWindowGroup.setWindowGroupConstruction(/* clear glazing construction */);
std::vector<Path> clearMatrixFiles = southWindowGroup.generateDaylightMatrix(
  Path("matrices/clear"), params);

// Calculate for shaded state  
southWindowGroup.setWindowGroupConstruction(/* shaded glazing construction */);
std::vector<Path> shadedMatrixFiles = southWindowGroup.generateDaylightMatrix(
  Path("matrices/shaded"), params);

// Load matrices (in practice, these would be read from generated files)
Matrix viewMatrix; // View matrix from sensors to window
Matrix daylightMatrixClear; // Daylight matrix for clear state
Matrix daylightMatrixShaded; // Daylight matrix for shaded state
Matrix skyMatrix; // Annual sky matrix

// Calculate annual illuminance for both states
threePhase.setViewMatrix(viewMatrix);
threePhase.setSkyMatrix(skyMatrix);

// Clear state analysis
threePhase.setDaylightMatrix(daylightMatrixClear);
Matrix clearIlluminance = threePhase.calculateIlluminance();

// Shaded state analysis  
threePhase.setDaylightMatrix(daylightMatrixShaded);
Matrix shadedIlluminance = threePhase.calculateIlluminance();

// Compare results and optimize shading control
std::cout << "Clear state annual illuminance calculated" << std::endl;
std::cout << "Shaded state annual illuminance calculated" << std::endl;

Daylighting Controls Integration

#include <openstudio/model/DaylightingControl.hpp>
#include <openstudio/model/Space.hpp>

using namespace openstudio;
using namespace openstudio::model;

Model model;
// ... create model with spaces ...

// Add daylighting controls to each space
for (auto& space : model.getConcreteModelObjects<Space>()) {
  
  // Only add controls to spaces with significant window area
  double windowArea = 0.0;
  for (const auto& surface : space.surfaces()) {
    for (const auto& subSurface : surface.subSurfaces()) {
      windowArea += subSurface.grossArea();
    }
  }
  
  if (windowArea > 5.0) { // More than 5 m² of windows
    
    // Create daylighting control
    DaylightingControl daylightingControl(model);
    daylightingControl.setSpace(space);
    
    // Position at space centroid
    boost::optional<Point3d> centroid = space.transformation() * space.floorPrint().centroid();
    if (centroid) {
      daylightingControl.setPositionXCoordinate(centroid->x());
      daylightingControl.setPositionYCoordinate(centroid->y());
      daylightingControl.setPositionZCoordinate(centroid->z() + 0.8); // Desktop height
    }
    
    // Configure control parameters
    daylightingControl.setIlluminanceSetpoint(500.0); // 500 lux target
    daylightingControl.setLightingControlSteps(3.0);   // 3-step dimming
    daylightingControl.setLightingControlProbability(1.0); // Always respond
    
    // Set up glare control if space has view to exterior
    bool hasExteriorView = false;
    for (const auto& surface : space.surfaces()) {
      if (surface.outsideBoundaryCondition() == "Outdoors") {
        for (const auto& subSurface : surface.subSurfaces()) {
          hasExteriorView = true;
          break;
        }
      }
    }
    
    if (hasExteriorView) {
      daylightingControl.setMaximumAllowableDiscomfortGlareIndex(0.4); // Imperceptible glare
      daylightingControl.setGlareCalculationAzimuthAngleofViewDirectionClockwisefromZoneyAxis(0.0);
    }
    
    std::cout << "Added daylighting control to space: " 
              << space.name().get_value_or("Unnamed") << std::endl;
  }
}

// Verify all daylighting controls
std::vector<DaylightingControl> controls = model.getConcreteModelObjects<DaylightingControl>();
std::cout << "Total daylighting controls: " << controls.size() << std::endl;

Install with Tessl CLI

npx tessl i tessl/pypi-openstudio

docs

energyplus.md

index.md

measure.md

model.md

radiance.md

utilities.md

workflow.md

tile.json