std::pair<std::string,std::string> decomposeScaledUnitString(const std::string& s) { if (!isScaledUnit(s)) { LOG_FREE_AND_THROW("openstudio.QuantityRegex","Cannot decompose " << s << " into a scale and a compound unit because it is not a scaled unit."); } std::pair<std::string,std::string> result; boost::match_results<std::string::const_iterator> match; boost::regex scaleRegex("(\\\\?[\\l\\u]{1,5})\\("); // pull out scale if (!boost::regex_search(s,match,scaleRegex,boost::match_continuous)) { LOG_FREE_AND_THROW("openstudio.QuantityRegex","Could not extract a scale from the scaled unit " << s << "."); } result.first = std::string(match[1].first,match[1].second); // pull out compound unit if (!boost::regex_search(s,match,regexEmbeddedCompoundUnit())) { LOG_FREE_AND_THROW("openstudio.QuantityRegex","Could not extract a compound unit from " << s << "."); } int i = 1; while (!match[i].matched) {++i;} result.second = std::string(match[1].first,match[1].second); return result; }
QVariant loadJSON(const openstudio::path& p) { QFile file(toQString(p)); if (file.open(QFile::ReadOnly)) { QJsonParseError err; QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &err); file.close(); if (err.error) { LOG_FREE_AND_THROW("openstudio.Json","Error parsing JSON: " + toString(err.errorString())); } return doc.toVariant(); } LOG_FREE_AND_THROW("openstudio.Json","Could not open file " << toString(p) << " for reading."); return QVariant(); }
QVariant loadJSON(const openstudio::path& p) { openstudio::filesystem::ifstream file(p, std::ios_base::binary); if (file.is_open()) { QJsonParseError err; QJsonDocument doc = QJsonDocument::fromJson(openstudio::filesystem::read_as_QByteArray(file), &err); file.close(); if (err.error) { LOG_FREE_AND_THROW("openstudio.Json","Error parsing JSON: " + toString(err.errorString())); } return doc.toVariant(); } LOG_FREE_AND_THROW("openstudio.Json","Could not open file " << toString(p) << " for reading."); return QVariant(); }
std::pair<unsigned,unsigned> numFractionalDigits(const std::vector<double>& values, unsigned numSigFigs) { if (numSigFigs == 0u) { LOG_FREE_AND_THROW("openstudio.core.StringHelpers","Number of significant figures must be > 0."); } std::pair<unsigned,unsigned> result(0u,0u); for (unsigned i = 0, n = values.size(); i < n; ++i) { double value = values[i]; unsigned numDigits = numFractionalDigits(value,numSigFigs); if (i == 0) { result = std::pair<unsigned,unsigned>(numDigits,numDigits); } else { if (numDigits < result.first) { result.first = numDigits; } else if (numDigits > result.second) { result.second = numDigits; } } } return result; }
VersionString::VersionString(const std::string& version) : m_str(version) { boost::regex versionRegex("(\\d+)\\.(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?"); boost::smatch m; if (boost::regex_match(version,m,versionRegex)) { m_major = boost::lexical_cast<int>(std::string(m[1].first,m[1].second)); m_minor = boost::lexical_cast<int>(std::string(m[2].first,m[2].second)); int n = m.size(); if (3 < n) { std::string temp(m[3].first,m[3].second); if (!temp.empty()) { m_patch = boost::lexical_cast<int>(temp); } } if (4 < n) { std::string temp(m[4].first,m[4].second); if (!temp.empty()) { m_build = boost::lexical_cast<int>(temp); } } } else { LOG_FREE_AND_THROW("openstudio.utilities.VersionString", "Could not parse '" << version << "' as a version string."); } }
double toNumSigFigs(double value, unsigned numSigFigs) { if (numSigFigs == 0u) { LOG_FREE_AND_THROW("openstudio.core.StringHelpers","Number of significant figures must be > 0."); } if (equal<double>(value,0.0)) { return value; } double absValue = fabs(value); bool negative = (value != absValue); double orderOfMagnitude = floor(log10(absValue)); // 1683 => 3 // 0.001683892 => -3 // X.XXXXX add more sig-figs double positioningPowerOfTen = -orderOfMagnitude + double(int(numSigFigs) - 1); // 1683, 2 sig-figs => 1683 * 10**-2 => 16.83 // 0.001683892, 2 sig-figs => 0.001683892 * 10**4 => 16.83892 double temp = absValue * pow(10.0,positioningPowerOfTen); temp = floor(temp + 0.5); // round doesn't exist in VS2008 at least double result = temp * pow(10.0,-positioningPowerOfTen); if (negative) { return -result; } return result; }
VersionString extractOpenStudioVersion(const QVariant& variant) { QJsonObject topLevel = QJsonDocument::fromVariant(variant).object(); if (topLevel.contains("metadata")) { topLevel = topLevel["metadata"].toObject(); } OptionalVersionString version; if (topLevel.contains("openstudio_version")) { version = VersionString(topLevel["openstudio_version"].toString().toStdString()); } else if (topLevel.contains("version")) { version = VersionString(topLevel["version"].toString().toStdString()); } else { LOG_FREE_AND_THROW("openstudio.core.Json","No version identifier found in QJSON variant."); } OS_ASSERT(version); if (version.get() > VersionString(openStudioVersion())) { LOG_FREE(Warn,"openstudio.Json","Loading json file from version " << version << " with OpenStudio version " << VersionString(openStudioVersion()) << ". OpenStudio json files are not designed to be forwards-compatible. " << "Unexpected behavior may result.") } return version.get(); }
QVariant loadJSON(const std::string& json) { QJsonDocument doc = QJsonDocument::fromJson(toQString(json).toUtf8()); if (doc.isNull()) { LOG_FREE_AND_THROW("openstudio.Json","Error parsing JSON"); } return doc.toVariant(); }
void DefaultConstructionSetsController::onAddObject(const openstudio::IddObjectType& iddObjectType) { switch(iddObjectType.value()){ case IddObjectType::OS_DefaultConstructionSet: openstudio::model::DefaultConstructionSet(this->model()); break; default: LOG_FREE_AND_THROW("DefaultConstructionSetsController", "Unknown IddObjectType '" << iddObjectType.valueName() << "'"); } }
void MaterialsController::onAddObject(const openstudio::IddObjectType& iddObjectType) { model::Model model = this->model(); boost::optional<model::Material> mat; switch(iddObjectType.value()){ case IddObjectType::OS_Material: mat = openstudio::model::StandardOpaqueMaterial(model); break; case IddObjectType::OS_Material_NoMass: mat = openstudio::model::MasslessOpaqueMaterial(model); break; case IddObjectType::OS_Material_AirGap: mat = openstudio::model::AirGap(model); break; case IddObjectType::OS_Material_AirWall: mat = openstudio::model::AirWallMaterial(model); break; case IddObjectType::OS_Material_InfraredTransparent: mat = openstudio::model::InfraredTransparentMaterial(model); break; case IddObjectType::OS_Material_RoofVegetation: mat = openstudio::model::RoofVegetation(model); break; case IddObjectType::OS_WindowMaterial_SimpleGlazingSystem: mat = openstudio::model::SimpleGlazing(model); break; case IddObjectType::OS_WindowMaterial_Glazing: mat = openstudio::model::StandardGlazing(model); break; case IddObjectType::OS_WindowMaterial_Gas: mat = openstudio::model::Gas(model); break; case IddObjectType::OS_WindowMaterial_GasMixture: mat = openstudio::model::GasMixture(model); break; case IddObjectType::OS_WindowMaterial_Blind: mat = openstudio::model::Blind(model); break; case IddObjectType::OS_WindowMaterial_Screen: mat = openstudio::model::Screen(model); break; case IddObjectType::OS_WindowMaterial_Shade: mat = openstudio::model::Shade(model); break; case IddObjectType::OS_WindowMaterial_Glazing_RefractionExtinctionMethod: mat = openstudio::model::RefractionExtinctionGlazing(model); break; case IddObjectType::OS_WindowMaterial_GlazingGroup_Thermochromic: mat = openstudio::model::ThermochromicGlazing(model); break; default: LOG_FREE_AND_THROW("MaterialsController", "Unknown IddObjectType '" << iddObjectType.valueName() << "'"); } }
AnalysisJSONLoadResult loadJSON(const openstudio::path& p) { OptionalAnalysisObject result; StringStreamLogSink logger; logger.setLogLevel(Error); try { QVariant variant = openstudio::loadJSON(p); VersionString version = extractOpenStudioVersion(variant); QVariantMap map = variant.toMap(); QVariantMap objectMap; if (map.contains("data_point")) { // leave objectMap blank, because it cannot contain project_dir result = detail::DataPoint_Impl::factoryFromVariant(map["data_point"],version,boost::none); } else if (map.contains("analysis")) { objectMap = map["analysis"].toMap(); result = detail::Analysis_Impl::fromVariant(objectMap,version); } else { LOG_FREE_AND_THROW("openstudio.analysis.AnalysisObject", "The file at " << toString(p) << " does not contain a data_point or " << "an analysis."); } OS_ASSERT(result); openstudio::path projectDir; if (version < VersionString("1.1.2")) { OS_ASSERT(map.contains("metadata")); if (map["metadata"].toMap().contains("project_dir")) { projectDir = toPath(map["metadata"].toMap()["project_dir"].toString()); } } else { if (objectMap.contains("project_dir")) { projectDir = toPath(objectMap["project_dir"].toString()); } } return AnalysisJSONLoadResult(*result,projectDir,version); } catch (std::exception& e) { LOG_FREE(Error,"openstudio.analysis.AnalysisObject", "The file at " << toString(p) << " cannot be parsed as an OpenStudio " << "analysis framework json file, because " << e.what()); } catch (...) { LOG_FREE(Error,"openstudio.analysis.AnalysisObject", "The file at " << toString(p) << " cannot be parsed as an OpenStudio " << "analysis framework json file."); } return AnalysisJSONLoadResult(logger.logMessages()); }
std::pair<std::string,int> decomposeAtomicUnitString(const std::string& s) { if (!isAtomicUnit(s)) { LOG_FREE_AND_THROW("openstudio.QuantityRegex","Cannot decompose " << s << " into a base unit and exponent because it is not an atomic unit."); } std::pair<std::string,int> result; boost::smatch match; boost::regex_search(s,match,regexBaseUnit()); result.first = std::string(match[0].first,match[0].second); if (boost::regex_search(s,match,regexExponent())) { std::istringstream iss(std::string(match[0].first,match[0].second)); iss >> result.second; } else {
std::pair< std::vector<std::string>,std::vector<std::string> > decomposeCompoundUnitString( const std::string& s) { if (!isCompoundUnit(s)) { LOG_FREE_AND_THROW("openstudio.QuantityRegex","Cannot decompose " << s << " into AtomicUnits in the numerator and denominator because it is not a compound unit."); } std::pair< std::vector<std::string>,std::vector<std::string> > result; boost::match_results<std::string::const_iterator> match; std::string ws(s); // remove leading 1, if applicable std::string::iterator firstCharEnd = ws.begin(); ++firstCharEnd; std::string::const_iterator tempStrConstIter; // for gcc std::string firstChar(ws.begin(),firstCharEnd); if (firstChar == "1") { ws = std::string(firstCharEnd,ws.end()); firstCharEnd = ws.begin(); ++firstCharEnd; firstChar = std::string(ws.begin(),firstCharEnd); } while (!ws.empty() && (firstChar != "/")) { // populate numerator boost::regex_search(ws,match,regexAtomicUnit()); result.first.push_back(std::string(match[0].first,match[0].second)); tempStrConstIter = ws.end(); // for gcc ws = std::string(match[0].second,tempStrConstIter); if (!ws.empty()) { firstCharEnd = ws.begin(); ++firstCharEnd; firstChar = std::string(ws.begin(),firstCharEnd); } } if (firstChar == "/") { ws = std::string(firstCharEnd,ws.end()); while (!ws.empty()) { // populate denominator boost::regex_search(ws,match,regexAtomicUnit()); result.second.push_back(std::string(match[0].first,match[0].second)); tempStrConstIter = ws.end(); // for gcc ws = std::string(match[0].second,tempStrConstIter); } } return result; }
std::pair<std::string,std::pair<unsigned,std::string> > decomposeDirectScaledUnit(const std::string& s) { if (!isDirectScaledUnit(s)) { LOG_FREE_AND_THROW("openstudio.QuantityRegex","Cannot decompose " << s << " into a numerator and scaled denominator because it is not an direct scaled unit."); } std::pair<std::string,std::pair<unsigned,std::string> > result; boost::match_results<std::string::const_iterator> match; boost::regex_search(s,match,regexDirectScaledUnit()); result.first = std::string(match[1].first,match[1].second); std::string powerOfTen(match[2].first,match[2].second); result.second.first = powerOfTen.size() - 1; result.second.second = std::string(match[3].first,match[3].second); return result; }
unsigned numFractionalDigits(double value,unsigned numSigFigs) { if (numSigFigs == 0u) { LOG_FREE_AND_THROW("openstudio.core.StringHelpers","Number of significant figures must be > 0."); } if (equal<double>(value,0.0)) { return numSigFigs - 1u; } value = fabs(value); int orderOfMagnitude = int(floor(log10(value))); // 1683 => 3 // 0.001683892 => -3 int figsBeforeDecimal = std::min(std::max(orderOfMagnitude + 1,0),int(numSigFigs)); OS_ASSERT(figsBeforeDecimal >= 0); OS_ASSERT(figsBeforeDecimal <= int(numSigFigs)); int numZerosAfterDecimal = std::max(-1 - orderOfMagnitude,0); OS_ASSERT(numZerosAfterDecimal >= 0); return numSigFigs - figsBeforeDecimal + numZerosAfterDecimal; }
std::pair<std::string,std::string> decomposeQuantityString(const std::string& s) { std::pair<std::string,std::string> result; boost::match_results<std::string::const_iterator> match; if (!boost::regex_match(s,match,regexQuantity())) { LOG_FREE_AND_THROW("openstudio.QuantityRegex","Cannot decompose " << s << " into (value,unit) because it is not a quantity."); } // pull out number result.first = std::string(match[1].first,match[1].second); // see if there is / between number and unit std::string temp(match[2].first,match[2].second); if (temp == "/") { result.second = "1/"; } // pull out unit result.second += std::string(match[3].first,match[3].second); return result; }
void ConstructionsController::onAddObject(const openstudio::IddObjectType& iddObjectType) { switch(iddObjectType.value()){ case IddObjectType::OS_Construction: openstudio::model::Construction(this->model()); break; case IddObjectType::OS_Construction_InternalSource: openstudio::model::ConstructionWithInternalSource(this->model()); break; case IddObjectType::OS_Construction_CfactorUndergroundWall: openstudio::model::CFactorUndergroundWallConstruction(this->model()); break; case IddObjectType::OS_Construction_FfactorGroundFloor: openstudio::model::FFactorGroundFloorConstruction(this->model()); break; case IddObjectType::OS_Construction_WindowDataFile: openstudio::model::WindowDataFile(this->model()); break; default: LOG_FREE_AND_THROW("ConstructionsController", "Unknown IddObjectType '" << iddObjectType.valueName() << "'"); } }