#include <config.h>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include "PHEMCEPHandler.h"
#include "PHEMConstants.h"
#include <utils/options/OptionsCont.h>
#include <utils/common/UtilExceptions.h>
PHEMCEPHandler::PHEMCEPHandler() {
}
PHEMCEPHandler::~PHEMCEPHandler() {
std::map<SUMOEmissionClass, PHEMCEP*>::iterator iter = _ceps.begin();
while (iter != _ceps.end()) {
delete (iter->second);
iter++;
}
_ceps.clear();
}
PHEMCEPHandler&
PHEMCEPHandler::getHandlerInstance() {
static PHEMCEPHandler instance;
return instance;
}
bool
PHEMCEPHandler::Load(SUMOEmissionClass emissionClass, const std::string& emissionClassIdentifier) {
std::vector< std::vector<double> > matrixSpeedInertiaTable;
std::vector< std::vector<double> > normedDragTable;
std::vector< std::vector<double> > matrixFC;
std::vector< std::vector<double> > matrixPollutants;
std::vector<std::string> headerFC;
std::vector<std::string> headerPollutants;
std::vector<double> idlingValues;
std::vector<double> idlingValuesFC;
double vehicleMass;
double vehicleLoading;
double vehicleMassRot;
double crosssectionalArea;
double cwValue;
double f0;
double f1;
double f2;
double f3;
double f4;
double axleRatio;
double ratedPower;
double engineIdlingSpeed;
double engineRatedSpeed;
double effectiveWheelDiameter;
std::string vehicleMassType;
std::string vehicleFuelType;
double pNormV0;
double pNormP0;
double pNormV1;
double pNormP1;
OptionsCont& oc = OptionsCont::getOptions();
std::vector<std::string> phemPath;
phemPath.push_back(oc.getString("phemlight-path") + "/");
if (getenv("PHEMLIGHT_PATH") != nullptr) {
phemPath.push_back(std::string(getenv("PHEMLIGHT_PATH")) + "/");
}
if (getenv("SUMO_HOME") != nullptr) {
phemPath.push_back(std::string(getenv("SUMO_HOME")) + "/data/emissions/PHEMlight/");
}
if (!ReadVehicleFile(phemPath, emissionClassIdentifier,
vehicleMass,
vehicleLoading,
vehicleMassRot,
crosssectionalArea,
cwValue,
f0,
f1,
f2,
f3,
f4,
axleRatio,
ratedPower,
engineIdlingSpeed,
engineRatedSpeed,
effectiveWheelDiameter,
vehicleMassType,
vehicleFuelType,
pNormV0,
pNormP0,
pNormV1,
pNormP1,
matrixSpeedInertiaTable,
normedDragTable)) {
return false;
}
if (!ReadEmissionData(true, phemPath, emissionClassIdentifier, headerFC, matrixFC, idlingValuesFC)) {
return false;
}
if (!ReadEmissionData(false, phemPath, emissionClassIdentifier, headerPollutants, matrixPollutants, idlingValues)) {
return false;
}
_ceps[emissionClass] = new PHEMCEP(vehicleMassType == "HV",
emissionClass, emissionClassIdentifier,
vehicleMass,
vehicleLoading,
vehicleMassRot,
crosssectionalArea,
cwValue,
f0,
f1,
f2,
f3,
f4,
ratedPower,
pNormV0,
pNormP0,
pNormV1,
pNormP1,
axleRatio,
engineIdlingSpeed,
engineRatedSpeed,
effectiveWheelDiameter,
idlingValuesFC.front(),
vehicleFuelType,
matrixFC,
headerPollutants,
matrixPollutants,
matrixSpeedInertiaTable,
normedDragTable,
idlingValues);
return true;
}
PHEMCEP*
PHEMCEPHandler::GetCep(SUMOEmissionClass emissionClass) {
if (_ceps.find(emissionClass) == _ceps.end()) {
return nullptr;
}
return _ceps[emissionClass];
}
bool
PHEMCEPHandler::ReadVehicleFile(const std::vector<std::string>& path, const std::string& emissionClass,
double& vehicleMass,
double& vehicleLoading,
double& vehicleMassRot,
double& crossArea,
double& cWValue,
double& f0,
double& f1,
double& f2,
double& f3,
double& f4,
double& axleRatio,
double& ratedPower,
double& engineIdlingSpeed,
double& engineRatedSpeed,
double& effectiveWheelDiameter,
std::string& vehicleMassType,
std::string& vehicleFuelType,
double& pNormV0,
double& pNormP0,
double& pNormV1,
double& pNormP1,
std::vector< std::vector<double> >& matrixSpeedInertiaTable,
std::vector< std::vector<double> >& normedDragTable)
{
std::ifstream fileVehicle;
for (std::vector<std::string>::const_iterator i = path.begin(); i != path.end(); i++) {
fileVehicle.open(((*i) + emissionClass + ".PHEMLight.veh").c_str());
if (fileVehicle.good()) {
break;
}
}
if (!fileVehicle.good()) {
return false;
}
std::string line;
std::string cell;
std::string commentPrefix = "c";
int dataCount = 0;
std::getline(fileVehicle, line);
while (std::getline(fileVehicle, line) && dataCount <= 49) {
if (line.size() > 0 && line.substr(line.size() - 1) == "\r") {
line = line.substr(0, line.size() - 1);
}
std::stringstream lineStream(line);
if (line.substr(0, 1) == commentPrefix) {
continue;
} else {
dataCount++;
}
std::getline(lineStream, cell, ',');
if (dataCount == 1) {
std::istringstream(cell) >> vehicleMass;
}
if (dataCount == 2) {
std::istringstream(cell) >> vehicleLoading;
}
if (dataCount == 3) {
std::istringstream(cell) >> cWValue;
}
if (dataCount == 4) {
std::istringstream(cell) >> crossArea;
}
if (dataCount == 7) {
std::istringstream(cell) >> vehicleMassRot;
}
if (dataCount == 10) {
std::istringstream(cell) >> ratedPower;
}
if (dataCount == 11) {
std::istringstream(cell) >> engineRatedSpeed;
}
if (dataCount == 12) {
std::istringstream(cell) >> engineIdlingSpeed;
}
if (dataCount == 14) {
std::istringstream(cell) >> f0;
}
if (dataCount == 15) {
std::istringstream(cell) >> f1;
}
if (dataCount == 16) {
std::istringstream(cell) >> f2;
}
if (dataCount == 17) {
std::istringstream(cell) >> f3;
}
if (dataCount == 18) {
std::istringstream(cell) >> f4;
}
if (dataCount == 21) {
std::istringstream(cell) >> axleRatio;
}
if (dataCount == 22) {
std::istringstream(cell) >> effectiveWheelDiameter;
}
if (dataCount == 45) {
vehicleMassType = cell;
}
if (dataCount == 46) {
vehicleFuelType = cell;
}
if (dataCount == 47) {
std::istringstream(cell) >> pNormV0;
}
if (dataCount == 48) {
std::istringstream(cell) >> pNormP0;
}
if (dataCount == 49) {
std::istringstream(cell) >> pNormV1;
}
if (dataCount == 50) {
std::istringstream(cell) >> pNormP1;
}
}
while (std::getline(fileVehicle, line) && line.substr(0, 1) != commentPrefix) {
std::stringstream lineStream(line);
std::vector<double> vi;
while (std::getline(lineStream, cell, ',')) {
double entry;
std::istringstream(cell) >> entry;
vi.push_back(entry);
}
matrixSpeedInertiaTable.push_back(vi);
}
while (std::getline(fileVehicle, line)) {
if (line.substr(0, 1) == commentPrefix) {
continue;
}
std::stringstream lineStream(line);
std::vector<double> vi;
while (std::getline(lineStream, cell, ',')) {
double entry;
std::istringstream(cell) >> entry;
vi.push_back(entry);
}
normedDragTable.push_back(vi);
}
fileVehicle.close();
return true;
}
bool PHEMCEPHandler::ReadEmissionData(bool readFC, const std::vector<std::string>& path, const std::string& emissionClass,
std::vector<std::string>& header, std::vector<std::vector<double> >& matrix, std::vector<double>& idlingValues) {
std::string pollutantExtension = "";
if (readFC) {
pollutantExtension += "_FC";
}
std::ifstream fileEmission;
for (std::vector<std::string>::const_iterator i = path.begin(); i != path.end(); i++) {
fileEmission.open(((*i) + emissionClass + pollutantExtension + ".csv").c_str());
if (fileEmission.good()) {
break;
}
}
if (!fileEmission.good()) {
return false;
}
std::string line;
std::string cell;
if (std::getline(fileEmission, line)) {
std::stringstream lineStream(line);
std::getline(lineStream, cell, ',');
while (std::getline(lineStream, cell, ',')) {
header.push_back(cell);
}
}
std::getline(fileEmission, line);
std::getline(fileEmission, line);
std::getline(fileEmission, line);
std::stringstream idlingStream(line);
std::string idlingCell;
std::getline(idlingStream, idlingCell, ',');
while (std::getline(idlingStream, idlingCell, ',')) {
double entry;
std::istringstream(idlingCell) >> entry;
idlingValues.push_back(entry);
}
while (std::getline(fileEmission, line)) {
std::stringstream lineStream(line);
std::vector <double> vi;
while (std::getline(lineStream, cell, ',')) {
double entry;
std::istringstream(cell) >> entry;
vi.push_back(entry);
}
matrix.push_back(vi);
}
fileEmission.close();
return true;
}