Cross-platform collection of software tools to support whole building energy modeling using EnergyPlus and advanced daylight analysis using Radiance
—
Comprehensive utility classes for geometry, units, file I/O, and data structures that form the foundation of the OpenStudio SDK. These utilities provide cross-platform infrastructure for handling physical units, 3D geometry, file operations, and data management.
Cross-platform file and path handling with comprehensive path manipulation capabilities.
/**
* Cross-platform path handling and file system operations
*/
class Path {
public:
// Constructors
Path();
Path(const std::string& p);
Path(const char* p);
// Path conversion
std::string string() const;
std::wstring wstring() const;
std::string generic_string() const;
// Path components
std::string filename() const;
std::string stem() const;
std::string extension() const;
Path parent_path() const;
Path root_path() const;
// Path operations
Path operator/(const Path& p) const;
Path& operator/=(const Path& p);
// File system queries
bool exists() const;
bool is_complete() const;
bool is_directory() const;
bool is_regular_file() const;
bool empty() const;
// Path manipulation
Path replace_extension(const std::string& new_extension = std::string()) const;
Path make_preferred() const;
};
namespace filesystem {
// File system operations
bool exists(const Path& p);
bool is_directory(const Path& p);
bool is_regular_file(const Path& p);
bool create_directories(const Path& p);
bool remove(const Path& p);
bool copy_file(const Path& from, const Path& to);
uintmax_t file_size(const Path& p);
std::time_t last_write_time(const Path& p);
// Directory iteration
std::vector<Path> directory_iterator(const Path& p);
std::vector<Path> recursive_directory_iterator(const Path& p);
}Usage Examples:
#include <openstudio/utilities/core/Path.hpp>
using namespace openstudio;
// Path construction and manipulation
Path modelDir("/home/user/models");
Path modelFile = modelDir / "building.osm";
// Path queries
if (modelFile.exists() && modelFile.is_regular_file()) {
std::string filename = modelFile.filename(); // "building.osm"
std::string stem = modelFile.stem(); // "building"
std::string ext = modelFile.extension(); // ".osm"
}
// Create output path with different extension
Path idfFile = modelFile.replace_extension(".idf");
// File operations
if (!filesystem::exists(modelDir)) {
filesystem::create_directories(modelDir);
}Comprehensive 3D geometric operations for building modeling and analysis.
/**
* 3D point representation
*/
class Point3d {
public:
// Constructors
Point3d();
Point3d(double x, double y, double z);
// Coordinate access
double x() const;
double y() const;
double z() const;
void setX(double x);
void setY(double y);
void setZ(double z);
// Vector operations
Vector3d operator-(const Point3d& other) const;
Point3d operator+(const Vector3d& vec) const;
Point3d operator-(const Vector3d& vec) const;
// Distance calculations
double distanceTo(const Point3d& other) const;
};
/**
* 3D vector representation
*/
class Vector3d {
public:
// Constructors
Vector3d();
Vector3d(double x, double y, double z);
// Component access
double x() const;
double y() const;
double z() const;
void setX(double x);
void setY(double y);
void setZ(double z);
// Vector operations
double length() const;
double lengthSquared() const;
bool normalize();
Vector3d normalized() const;
Vector3d operator+(const Vector3d& other) const;
Vector3d operator-(const Vector3d& other) const;
Vector3d operator*(double scalar) const;
Vector3d operator/(double scalar) const;
// Vector products
double dot(const Vector3d& other) const;
Vector3d cross(const Vector3d& other) const;
};
/**
* 3D transformation matrix
*/
class Transformation {
public:
// Constructors
Transformation();
Transformation(const Vector3d& translation);
Transformation(const Vector3d& rotationAxis, double rotationAngle);
// Static factory methods
static Transformation translation(const Vector3d& translation);
static Transformation rotation(const Vector3d& axis, double angle);
static Transformation rotation(const Point3d& origin, const Vector3d& axis, double angle);
// Matrix operations
Transformation operator*(const Transformation& other) const;
Transformation inverse() const;
// Transform points and vectors
Point3d operator*(const Point3d& point) const;
Vector3d operator*(const Vector3d& vector) const;
std::vector<Point3d> operator*(const std::vector<Point3d>& points) const;
// Matrix access
boost::optional<Vector3d> translation() const;
boost::optional<Vector3d> rotationAxis() const;
boost::optional<double> rotationAngle() const;
};
/**
* 3D polygon operations
*/
class Polygon3d {
public:
// Constructors
Polygon3d(const std::vector<Point3d>& vertices);
// Vertex access
std::vector<Point3d> vertices() const;
unsigned numVertices() const;
// Geometric properties
boost::optional<Vector3d> outwardNormal() const;
boost::optional<double> area() const;
boost::optional<Point3d> centroid() const;
boost::optional<Plane> plane() const;
// Geometric operations
bool isPlanar() const;
bool isConvex() const;
std::vector<Polygon3d> triangulate() const;
// Point-in-polygon tests
bool pointInside(const Point3d& point) const;
};
/**
* Bounding box operations
*/
class BoundingBox {
public:
// Constructors
BoundingBox();
BoundingBox(const Point3d& minCorner, const Point3d& maxCorner);
// Corner access
Point3d minCorner() const;
Point3d maxCorner() const;
// Dimension queries
double minX() const;
double maxX() const;
double minY() const;
double maxY() const;
double minZ() const;
double maxZ() const;
// Volume and area
double volume() const;
double surfaceArea() const;
// Operations
void addPoint(const Point3d& point);
void addPoints(const std::vector<Point3d>& points);
bool intersects(const BoundingBox& other) const;
bool contains(const Point3d& point) const;
};Comprehensive unit system with automatic conversions and quantity management.
/**
* Physical unit representation with conversion capabilities
*/
class Unit {
public:
// Constructors
Unit();
Unit(UnitSystem system = UnitSystem::Mixed);
// Unit system queries
UnitSystem system() const;
// Base unit operations
void setBaseUnitExponent(const std::string& baseUnit, int exponent);
int baseUnitExponent(const std::string& baseUnit) const;
// Unit operations
Unit operator*(const Unit& rUnit) const;
Unit operator/(const Unit& rUnit) const;
Unit pow(int expNum, int expDen = 1) const;
// String representation
std::string standardString() const;
std::string prettyString() const;
};
/**
* Quantity - value with associated units
*/
class Quantity {
public:
// Constructors
Quantity();
Quantity(double value);
Quantity(double value, const Unit& units);
// Value and unit access
double value() const;
Unit units() const;
UnitSystem system() const;
// Value modification
void setValue(double value);
bool setUnits(const Unit& units);
// Unit conversion
boost::optional<Quantity> convert(const Unit& targetUnits) const;
boost::optional<Quantity> convert(UnitSystem targetSystem) const;
// Arithmetic operations
Quantity operator+(const Quantity& rQuantity) const;
Quantity operator-(const Quantity& rQuantity) const;
Quantity operator*(const Quantity& rQuantity) const;
Quantity operator/(const Quantity& rQuantity) const;
Quantity pow(int expNum, int expDen = 1) const;
};
/**
* Collection of quantities with consistent units
*/
class OSQuantityVector {
public:
// Constructors
OSQuantityVector();
OSQuantityVector(const Unit& units);
OSQuantityVector(const std::vector<Quantity>& values);
// Vector operations
unsigned size() const;
bool empty() const;
void push_back(const Quantity& q);
void clear();
// Unit operations
Unit units() const;
bool setUnits(const Unit& units);
boost::optional<OSQuantityVector> convert(const Unit& targetUnits) const;
// Value access
std::vector<double> values() const;
std::vector<Quantity> quantities() const;
Quantity getQuantity(unsigned index) const;
};
// Common unit factory functions
namespace createUnits {
// Length units
Unit createSILength(); // m
Unit createIPLength(); // ft
Unit createFeet();
Unit createInches();
Unit createMeters();
Unit createCentimeters();
// Area units
Unit createSIArea(); // m^2
Unit createIPArea(); // ft^2
// Volume units
Unit createSIVolume(); // m^3
Unit createIPVolume(); // ft^3
// Temperature units
Unit createSITemperature(); // K
Unit createIPTemperature(); // R
Unit createCelsiusTemperature(); // C
Unit createFahrenheitTemperature(); // F
// Energy units
Unit createSIEnergy(); // J
Unit createIPEnergy(); // Btu
Unit createKWh();
// Power units
Unit createSIPower(); // W
Unit createIPPower(); // Btu/h
}Comprehensive time management for simulation and scheduling operations.
/**
* Time duration representation
*/
class Time {
public:
// Constructors
Time();
Time(double totalDays);
Time(int days, int hours = 0, int minutes = 0, int seconds = 0);
// Component access
int days() const;
int hours() const;
int minutes() const;
int seconds() const;
// Total time access
double totalDays() const;
double totalHours() const;
double totalMinutes() const;
double totalSeconds() const;
// Arithmetic operations
Time operator+(const Time& time) const;
Time operator-(const Time& time) const;
Time operator*(double mult) const;
Time operator/(double div) const;
// String representation
std::string toString() const;
};
/**
* Calendar date representation
*/
class Date {
public:
// Constructors
Date();
Date(MonthOfYear monthOfYear, unsigned dayOfMonth);
Date(MonthOfYear monthOfYear, unsigned dayOfMonth, int year);
Date(unsigned dayOfYear, int year);
// Component access
int year() const;
MonthOfYear monthOfYear() const;
unsigned dayOfMonth() const;
unsigned dayOfYear() const;
DayOfWeek dayOfWeek() const;
// Date operations
Date operator+(const Time& time) const;
Date operator-(const Time& time) const;
Time operator-(const Date& date) const;
// Leap year handling
bool isLeapYear() const;
static bool isLeapYear(int year);
// String representation
std::string toString() const;
};
/**
* Combined date and time
*/
class DateTime {
public:
// Constructors
DateTime();
DateTime(const Date& date);
DateTime(const Date& date, const Time& time);
// Component access
Date date() const;
Time time() const;
// Arithmetic operations
DateTime operator+(const Time& time) const;
DateTime operator-(const Time& time) const;
Time operator-(const DateTime& dateTime) const;
// String representation
std::string toString() const;
};
// Enumeration types
enum class MonthOfYear {
Jan = 1, Feb, Mar, Apr, May, Jun,
Jul, Aug, Sep, Oct, Nov, Dec
};
enum class DayOfWeek {
Sunday = 0, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday
};Comprehensive logging system with multiple output targets and severity levels.
/**
* Logging framework with multiple severity levels
*/
class Logger {
public:
// Static access to loggers
static Logger& instance();
static LoggerType& standardOut();
// Logging methods
void logMessage(LogLevel level, const LogChannel& channel, const std::string& message);
// Log level control
void setLogLevel(LogLevel level);
LogLevel logLevel() const;
// Log sinks
void addLogSink(boost::shared_ptr<LogSink> logSink);
void removeLogSink(boost::shared_ptr<LogSink> logSink);
};
/**
* Base class for log output destinations
*/
class LogSink {
public:
virtual ~LogSink() = default;
// Core logging method
virtual void logMessage(const LogMessage& logMessage) = 0;
// Level filtering
void setLogLevel(LogLevel logLevel);
LogLevel logLevel() const;
// Channel filtering
void setChannelRegex(const std::string& channelRegex);
std::string channelRegex() const;
// Threading
void setThreadId(boost::thread::id threadId);
boost::thread::id threadId() const;
};
/**
* File-based log output
*/
class FileLogSink : public LogSink {
public:
FileLogSink(const Path& path);
Path path() const;
virtual void logMessage(const LogMessage& logMessage) override;
};
/**
* String stream log output for testing
*/
class StringStreamLogSink : public LogSink {
public:
StringStreamLogSink();
std::string logMessages() const;
std::vector<LogMessage> logMessagesVec() const;
virtual void logMessage(const LogMessage& logMessage) override;
};
// Log level enumeration
enum class LogLevel {
Trace = -3,
Debug = -2,
Info = -1,
Warn = 0,
Error = 1,
Fatal = 2
};
// Logging macros
#define LOG(level, channel) \
if (openstudio::Logger::instance().logLevel() <= level) \
openstudio::Logger::instance().logMessage(level, channel, "")
#define LOG_FREE(level, channel, message) \
openstudio::Logger::instance().logMessage(level, channel, message)Mathematical data structures for numerical analysis and data management.
/**
* Mathematical matrix operations
*/
class Matrix {
public:
// Constructors
Matrix();
Matrix(unsigned m, unsigned n, double value = 0.0);
Matrix(const std::vector<std::vector<double>>& vector);
// Dimension access
unsigned size1() const; // rows
unsigned size2() const; // columns
// Element access
double operator()(unsigned i, unsigned j) const;
double& operator()(unsigned i, unsigned j);
// Matrix operations
Matrix operator+(const Matrix& other) const;
Matrix operator-(const Matrix& other) const;
Matrix operator*(const Matrix& other) const;
Matrix operator*(double scalar) const;
// Matrix properties
Matrix transpose() const;
boost::optional<Matrix> inverse() const;
double determinant() const;
// Row and column operations
Vector getRow(unsigned i) const;
Vector getColumn(unsigned j) const;
void setRow(unsigned i, const Vector& row);
void setColumn(unsigned j, const Vector& column);
};
/**
* Mathematical vector operations
*/
class Vector {
public:
// Constructors
Vector();
Vector(unsigned size, double value = 0.0);
Vector(const std::vector<double>& vector);
// Size operations
unsigned size() const;
void resize(unsigned size);
// Element access
double operator()(unsigned i) const;
double& operator()(unsigned i);
double operator[](unsigned i) const;
double& operator[](unsigned i);
// Vector operations
Vector operator+(const Vector& other) const;
Vector operator-(const Vector& other) const;
Vector operator*(double scalar) const;
double dot(const Vector& other) const;
// Vector properties
double length() const;
double sum() const;
double mean() const;
double minimum() const;
double maximum() const;
};
/**
* Time series data management
*/
class TimeSeries {
public:
// Constructors
TimeSeries();
TimeSeries(const Date& startDate,
const Time& intervalLength,
const Vector& values,
const std::string& units);
// Data access
Date startDate() const;
Time intervalLength() const;
std::vector<DateTime> dateTimes() const;
Vector values() const;
std::string units() const;
// Value access by time
double value(const DateTime& dateTime) const;
std::vector<double> values(const DateTime& startDateTime,
const DateTime& endDateTime) const;
// Statistical operations
double minimum() const;
double maximum() const;
double mean() const;
double sum() const;
// Time series operations
TimeSeries operator+(const TimeSeries& other) const;
TimeSeries operator-(const TimeSeries& other) const;
TimeSeries operator*(double scalar) const;
};#include <openstudio/utilities/core/Path.hpp>
using namespace openstudio;
// Working with model files
Path modelDir = Path("/home/user/models");
Path osmFile = modelDir / "office_building.osm";
Path idfFile = osmFile.replace_extension(".idf");
// Check file existence and create directories
if (!filesystem::exists(modelDir)) {
filesystem::create_directories(modelDir);
}
// File operations with error handling
if (filesystem::exists(osmFile)) {
// Backup existing file
Path backupFile = osmFile.replace_extension(".osm.bak");
filesystem::copy_file(osmFile, backupFile);
std::cout << "File size: " << filesystem::file_size(osmFile) << " bytes" << std::endl;
}#include <openstudio/utilities/geometry/Point3d.hpp>
#include <openstudio/utilities/geometry/Vector3d.hpp>
#include <openstudio/utilities/geometry/Transformation.hpp>
using namespace openstudio;
// Create building geometry
std::vector<Point3d> floorVertices;
floorVertices.push_back(Point3d(0, 0, 0));
floorVertices.push_back(Point3d(20, 0, 0));
floorVertices.push_back(Point3d(20, 15, 0));
floorVertices.push_back(Point3d(0, 15, 0));
// Calculate floor area
Polygon3d floor(floorVertices);
boost::optional<double> area = floor.area();
if (area) {
std::cout << "Floor area: " << *area << " m²" << std::endl;
}
// Transform geometry (rotate building 45 degrees)
Vector3d zAxis(0, 0, 1);
Transformation rotation = Transformation::rotation(zAxis, 45 * 3.14159 / 180);
std::vector<Point3d> rotatedVertices = rotation * floorVertices;#include <openstudio/utilities/units/Quantity.hpp>
#include <openstudio/utilities/units/QuantityFactory.hpp>
using namespace openstudio;
// Create quantities with units
Quantity areaIP(1000, createUnits::createIPArea()); // 1000 ft²
Quantity areaSI(100, createUnits::createSIArea()); // 100 m²
// Convert between unit systems
boost::optional<Quantity> areaSIConverted = areaIP.convert(createUnits::createSIArea());
if (areaSIConverted) {
std::cout << areaIP.value() << " ft² = "
<< areaSIConverted->value() << " m²" << std::endl;
}
// Energy calculations
Quantity powerSI(5000, createUnits::createSIPower()); // 5000 W
Quantity timeHours(8, createUnits::createTime()); // 8 hours
Quantity energy = powerSI * timeHours; // Energy in W⋅h
boost::optional<Quantity> energyKWh = energy.convert(createUnits::createKWh());
// Temperature conversions
Quantity tempF(75, createUnits::createFahrenheitTemperature());
boost::optional<Quantity> tempC = tempF.convert(createUnits::createCelsiusTemperature());#include <openstudio/utilities/core/Logger.hpp>
using namespace openstudio;
// Set up file logging
boost::shared_ptr<FileLogSink> fileSink(new FileLogSink(Path("simulation.log")));
fileSink->setLogLevel(LogLevel::Info);
Logger::instance().addLogSink(fileSink);
// Log messages at different levels
LOG_FREE(LogLevel::Info, "OpenStudio.Model", "Creating building model");
LOG_FREE(LogLevel::Warn, "OpenStudio.Model", "Missing construction assignment");
LOG_FREE(LogLevel::Error, "OpenStudio.Simulation", "EnergyPlus simulation failed");
// Log with channel filtering
boost::shared_ptr<StringStreamLogSink> testSink(new StringStreamLogSink());
testSink->setChannelRegex("OpenStudio\\.Model.*");
Logger::instance().addLogSink(testSink);Install with Tessl CLI
npx tessl i tessl/pypi-openstudio