IswaGroup has own dataProcessor

This commit is contained in:
Sebastian Piwell
2016-05-20 12:48:48 -04:00
parent 672933cd05
commit 57cd44535d
17 changed files with 553 additions and 117 deletions

View File

@@ -35,7 +35,7 @@ public:
CygnetPlane(const ghoul::Dictionary& dictionary);
~CygnetPlane();
private:
protected:
virtual bool createGeometry() override;
virtual bool destroyGeometry() override;
virtual void renderGeometry() override;

View File

@@ -33,6 +33,7 @@
#include <openspace/rendering/renderengine.h>
#include <openspace/util/spicemanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <modules/iswa/rendering/iswagroup.h>
namespace {
const std::string _loggerCat = "DataPlane";
@@ -48,6 +49,7 @@ DataPlane::DataPlane(const ghoul::Dictionary& dictionary)
,_backgroundValues("backgroundValues", "Background Values", glm::vec2(0.0), glm::vec2(0), glm::vec2(1.0))
,_transferFunctionsFile("transferfunctions", "Transfer Functions", "${SCENE}/iswa/tfs/hot.tf")
,_dataOptions("dataOptions", "Data Options")
,_dataProcessor(nullptr)
{
std::string name;
dictionary.getValue("Name", name);
@@ -62,27 +64,35 @@ DataPlane::DataPlane(const ghoul::Dictionary& dictionary)
addProperty(_transferFunctionsFile);
addProperty(_dataOptions);
if(_data->groupName.empty()){
_type = IswaManager::CygnetType::Data;
}
DataPlane::~DataPlane(){}
bool DataPlane::initialize(){
IswaCygnet::initialize();
if(_group){
std::cout << "add to group" << std::endl;
_dataProcessor = _group->dataProcessor();
}else{
OsEng.gui()._iswa.registerProperty(&_useLog);
OsEng.gui()._iswa.registerProperty(&_useHistogram);
OsEng.gui()._iswa.registerProperty(&_normValues);
OsEng.gui()._iswa.registerProperty(&_backgroundValues);
OsEng.gui()._iswa.registerProperty(&_transferFunctionsFile);
OsEng.gui()._iswa.registerProperty(&_dataOptions);
_dataProcessor = std::make_shared<DataProcessor>(
_useLog.value(),
_useHistogram.value(),
_normValues
);
}
setTransferFunctions(_transferFunctionsFile.value());
_dataProcessor = std::make_shared<DataProcessor>(
_useLog.value(),
_useHistogram.value(),
_normValues
);
_normValues.onChange([this](){
// FOR TESTING (should be done on all onChange)
// _avgBenchmarkTime = 0.0;
// _numOfBenchmarks = 0;
_dataProcessor->normValues(_normValues.value());
loadTexture();
});
@@ -103,12 +113,9 @@ DataPlane::DataPlane(const ghoul::Dictionary& dictionary)
setTransferFunctions(_transferFunctionsFile.value());
});
_type = IswaManager::CygnetType::Data;
return true;
}
DataPlane::~DataPlane(){}
void DataPlane::useLog(bool useLog){ _useLog.setValue(useLog); };
void DataPlane::normValues(glm::vec2 normValues){ _normValues.setValue(normValues); };
void DataPlane::useHistogram(bool useHistogram){ _useHistogram.setValue(useHistogram); };
@@ -135,14 +142,15 @@ bool DataPlane::loadTexture() {
if(!_dataOptions.options().size()){ // load options for value selection
fillOptions();
_dataProcessor->addValues(_dataBuffer, _dataOptions);
}
std::vector<float*> data = _dataProcessor->readData(_dataBuffer, _dataOptions);
std::vector<float*> data = _dataProcessor->readData2(_dataBuffer, _dataOptions);
if(data.empty())
return false;
_backgroundValues.setValue(_dataProcessor->filterValues());
// _backgroundValues.setValue(_dataProcessor->filterValues());
bool texturesReady = false;
std::vector<int> selectedOptions = _dataOptions.value();
@@ -297,7 +305,7 @@ void DataPlane::fillOptions(){
_textures.push_back(nullptr);
}
_dataOptions.setValue(std::vector<int>(1,0));
if(!_data->groupName.empty())
if(_group)
IswaManager::ref().registerOptionsToGroup(_data->groupName, _dataOptions.options());
}

View File

@@ -40,6 +40,8 @@ friend class IswaGroup;
DataPlane(const ghoul::Dictionary& dictionary);
~DataPlane();
bool initialize() override;
protected:
virtual void useLog(bool useLog) override;
virtual void normValues(glm::vec2 normValues) override;

View File

@@ -27,6 +27,7 @@
#include <ghoul/filesystem/filesystem.h>
#include <modules/base/rendering/planetgeometry.h>
#include <fstream>
#include <modules/iswa/rendering/iswagroup.h>
namespace {
@@ -57,30 +58,37 @@ DataSphere::DataSphere(const ghoul::Dictionary& dictionary)
addProperty(_transferFunctionsFile);
addProperty(_dataOptions);
if(_data->groupName.empty()){
_type = IswaManager::CygnetType::Data;
}
DataSphere::~DataSphere(){}
bool DataSphere::initialize(){
IswaCygnet::initialize();
if(_group){
_dataProcessor = _group->dataProcessor();
}else{
OsEng.gui()._iswa.registerProperty(&_useLog);
OsEng.gui()._iswa.registerProperty(&_useHistogram);
OsEng.gui()._iswa.registerProperty(&_normValues);
OsEng.gui()._iswa.registerProperty(&_backgroundValues);
OsEng.gui()._iswa.registerProperty(&_transferFunctionsFile);
OsEng.gui()._iswa.registerProperty(&_dataOptions);
_dataProcessor = std::make_shared<DataProcessor>(
_useLog.value(),
_useHistogram.value(),
_normValues
);
}
setTransferFunctions(_transferFunctionsFile.value());
_dataProcessor = std::make_shared<DataProcessor>(
_useLog.value(),
_useHistogram.value(),
_normValues
);
_normValues.onChange([this](){
// FOR TESTING (should be done on all onChange)
// _avgBenchmarkTime = 0.0;
// _numOfBenchmarks = 0;
_dataProcessor->normValues(_normValues.value());
loadTexture();
});
_useLog.onChange([this](){
_dataProcessor->useLog(_useLog.value());
loadTexture();
@@ -97,14 +105,9 @@ DataSphere::DataSphere(const ghoul::Dictionary& dictionary)
setTransferFunctions(_transferFunctionsFile.value());
});
_type = IswaManager::CygnetType::Data;
_dataBuffer = "";
//_data->frame = "SM";
return true;
}
DataSphere::~DataSphere(){}
void DataSphere::useLog(bool useLog){ _useLog.setValue(useLog); };
void DataSphere::normValues(glm::vec2 normValues){ _normValues.setValue(normValues); };
void DataSphere::useHistogram(bool useHistogram){ _useHistogram.setValue(useHistogram); };
@@ -131,9 +134,10 @@ bool DataSphere::loadTexture(){
if(!_dataOptions.options().size()){ // load options for value selection
fillOptions();
_dataProcessor->addValuesFromJSON(_dataBuffer, _dataOptions);
}
std::vector<float*> data = _dataProcessor->readJSONData(_dataBuffer, _dataOptions);
std::vector<float*> data = _dataProcessor->readJSONData2(_dataBuffer, _dataOptions);
if(data.empty())
return false;

View File

@@ -39,6 +39,8 @@ public:
DataSphere(const ghoul::Dictionary& dictionary);
~DataSphere();
bool initialize() override;
protected:
virtual void useLog(bool useLog) override;
virtual void normValues(glm::vec2 normValues) override;

View File

@@ -37,6 +37,7 @@ IswaCygnet::IswaCygnet(const ghoul::Dictionary& dictionary)
, _delete("delete", "Delete")
, _shader(nullptr)
,_type(IswaManager::CygnetType::NoType)
,_group(nullptr)
{
_data = std::make_shared<Metadata>();
@@ -101,19 +102,23 @@ IswaCygnet::IswaCygnet(const ghoul::Dictionary& dictionary)
_delete.onChange([this](){
OsEng.scriptEngine().queueScript("openspace.removeSceneGraphNode('" + name() + "')");
});
}
IswaCygnet::~IswaCygnet(){}
bool IswaCygnet::initialize(){
_textures.push_back(nullptr);
if(!_data->groupName.empty()){
_group = IswaManager::ref().registerToGroup(_data->groupName, _type, this);
std::cout << "Register group " << (_group != nullptr) << std::endl;
}
initializeTime();
createGeometry();
createShader();
updateTexture();
if(!_data->groupName.empty())
IswaManager::ref().registerToGroup(_data->groupName, _type, this);
return true;
}

View File

@@ -125,6 +125,8 @@ protected:
std::vector<std::shared_ptr<TransferFunction>> _transferFunctions;
std::future<DownloadManager::MemoryFile> _futureObject;
std::shared_ptr<IswaGroup> _group;
IswaManager::CygnetType _type;
};

View File

@@ -41,6 +41,7 @@ IswaGroup::IswaGroup(std::string name)
,_dataOptions("dataOptions", "Data Options")
// ,_id(id)
,_type(IswaManager::CygnetType::NoType)
// ,_dataProcessor(nullptr)
{
setName(name);
@@ -54,6 +55,12 @@ IswaGroup::IswaGroup(std::string name)
addProperty(_dataOptions);
addProperty(_delete);
_dataProcessor = std::make_shared<DataProcessor>(
_useLog.value(),
_useHistogram.value(),
_normValues
);
}
IswaGroup::~IswaGroup(){
@@ -103,7 +110,13 @@ void IswaGroup::registerOptions(const std::vector<properties::SelectionProperty:
if(_type == IswaManager::CygnetType::Data){
if(_dataOptions.options().empty()){
for(auto option : options){
_dataOptions.addOption(option);
std::stringstream memorystream(option.description);
std::string optionName;
getline(memorystream, optionName, '/');
getline(memorystream, optionName, '/');
_dataOptions.addOption({option.value, name()+"/"+optionName});
}
_dataOptions.setValue(std::vector<int>(1,0));
}
@@ -187,4 +200,8 @@ void IswaGroup::clearGroup(){
unregisterProperties();
}
std::shared_ptr<DataProcessor> IswaGroup::dataProcessor(){
return _dataProcessor;
}
} //namespace openspace

View File

@@ -33,6 +33,7 @@
// #include <modules/iswa/rendering/iswacygnet.h>
#include <openspace/properties/triggerproperty.h>
#include <modules/iswa/util/iswamanager.h>
#include <modules/iswa/util/dataprocessor.h>
namespace openspace{
@@ -47,6 +48,15 @@ public:
void registerOptions(const std::vector<properties::SelectionProperty::Option>& options);
bool checkType(IswaManager::CygnetType type);
void clearGroup();
std::shared_ptr<DataProcessor> dataProcessor();
// bool useLog(){return _useLog.value();};
// glm::vec2 normValues(){return _normValues.value();};
// bool useHistogram(){return _useHistogram.value();};
// std::vector<int> dataOptions(){return _dataOptions.value();};
// std::string transferFunctionsFile(){return _transferFunctionsFile.value();};
// glm::vec2 backgroundValues(){return _backgroundValues.value();};
private:
void registerProperties();
void unregisterProperties();
@@ -69,6 +79,8 @@ private:
// int groupId;
// IswaCygnet cygnet;
int _id;
std::shared_ptr<DataProcessor> _dataProcessor;
std::vector<IswaCygnet* > _cygnets;
IswaManager::CygnetType _type;
};

View File

@@ -37,6 +37,7 @@
#include <ghoul/filesystem/filesystem.h>
#include <fstream>
#include <modules/iswa/ext/json/json.hpp>
#include <modules/iswa/rendering/iswagroup.h>
namespace {
@@ -55,7 +56,7 @@ KameleonPlane::KameleonPlane(const ghoul::Dictionary& dictionary)
,_transferFunctionsFile("transferfunctions", "Transfer Functions", "${SCENE}/iswa/tfs/hot.tf")
,_dataOptions("dataOptions", "Data Options")
,_fieldlines("fieldlineSeedsIndexFile", "Fieldline Seedpoints")
,_resolution("resolution", "Resolutionx100", 2, 1, 5)
,_resolution("resolution", "Resolutionx100", 1, 1, 5)
,_slice("slice", "Slice", 0.0, 0.0, 1.0)
{
std::string name;
@@ -74,26 +75,80 @@ KameleonPlane::KameleonPlane(const ghoul::Dictionary& dictionary)
addProperty(_dataOptions);
addProperty(_fieldlines);
if(_data->groupName.empty()){
_type = IswaManager::CygnetType::Data;
dictionary.getValue("kwPath", _kwPath);
std::string fieldlineIndexFile;
dictionary.getValue("fieldlineSeedsIndexFile", fieldlineIndexFile);
readFieldlinePaths(absPath(fieldlineIndexFile));
_fieldlines.onChange([this](){ updateFieldlineSeeds();} );
std::string axis;
dictionary.getValue("axisCut", axis);
OsEng.gui()._iswa.registerProperty(&_slice);
if(axis == "x"){
_scale = _data->scale.x;
_data->scale.x = 0;
_data->offset.x = 0;
_slice.setValue((_data->offset.x - _data->gridMin.x)/_scale);
}else if(axis == "y"){
_scale = _data->scale.y;
_data->scale.y = 0;
_data->offset.y = 0;
_slice.setValue((_data->offset.y -_data->gridMin.y)/_scale);
}else{
_scale = _data->scale.z;
_data->scale.z = 0;
_data->offset.z = 0;
_slice.setValue((_data->offset.z - _data->gridMin.z)/_scale);
}
}
KameleonPlane::~KameleonPlane(){
_kw = nullptr;
}
bool KameleonPlane::initialize(){
_textures.push_back(nullptr);
if(!_data->groupName.empty()){
_group = IswaManager::ref().registerToGroup(_data->groupName, _type, this);
std::cout << "Register group " << (_group != nullptr) << std::endl;
}
initializeTime();
createGeometry();
createShader();
if(_group){
_dataProcessor = _group->dataProcessor();
}else{
OsEng.gui()._iswa.registerProperty(&_useLog);
OsEng.gui()._iswa.registerProperty(&_useHistogram);
OsEng.gui()._iswa.registerProperty(&_normValues);
OsEng.gui()._iswa.registerProperty(&_backgroundValues);
OsEng.gui()._iswa.registerProperty(&_resolution);
OsEng.gui()._iswa.registerProperty(&_slice);
OsEng.gui()._iswa.registerProperty(&_transferFunctionsFile);
OsEng.gui()._iswa.registerProperty(&_dataOptions);
OsEng.gui()._iswa.registerProperty(&_fieldlines);
_dataProcessor = std::make_shared<DataProcessor>(
_useLog.value(),
_useHistogram.value(),
_normValues
);
}
setTransferFunctions(_transferFunctionsFile.value());
_dataProcessor = std::make_shared<DataProcessor>(
_useLog.value(),
_useHistogram.value(),
_normValues
);
_normValues.onChange([this](){
_dataProcessor->normValues(_normValues.value());
loadTexture();
@@ -114,52 +169,27 @@ KameleonPlane::KameleonPlane(const ghoul::Dictionary& dictionary)
});
_resolution.onChange([this](){
_dataProcessor->clear();
updateTexture();
});
_type = IswaManager::CygnetType::Data;
dictionary.getValue("kwPath", _kwPath);
std::string fieldlineIndexFile;
dictionary.getValue("fieldlineSeedsIndexFile", fieldlineIndexFile);
readFieldlinePaths(absPath(fieldlineIndexFile));
_fieldlines.onChange([this](){ updateFieldlineSeeds();} );
std::string axis;
dictionary.getValue("axisCut", axis);
if(axis == "x"){
_scale = _data->scale.x;
_data->scale.x = 0;
_data->offset.x = 0;
_slice.setValue((_data->offset.x - _data->gridMin.x)/_scale);
}else if(axis == "y"){
_scale = _data->scale.y;
_data->scale.y = 0;
_data->offset.y = 0;
_slice.setValue((_data->offset.y -_data->gridMin.y)/_scale);
}else{
_scale = _data->scale.z;
_data->scale.z = 0;
_data->offset.z = 0;
_slice.setValue((_data->offset.z - _data->gridMin.z)/_scale);
}
_slice.onChange([this](){
updateTexture();
});
updateTexture();
}
KameleonPlane::~KameleonPlane(){
_kw = nullptr;
}
void KameleonPlane::useLog(bool useLog){ _useLog.setValue(useLog); };
void KameleonPlane::normValues(glm::vec2 normValues){ _normValues.setValue(normValues); };
void KameleonPlane::useHistogram(bool useHistogram){ _useHistogram.setValue(useHistogram); };
void KameleonPlane::dataOptions(std::vector<int> options){ _dataOptions.setValue(options); };
void KameleonPlane::transferFunctionsFile(std::string tfPath){ _transferFunctionsFile.setValue(tfPath); };
void KameleonPlane::backgroundValues(glm::vec2 backgroundValues){ _backgroundValues.setValue(backgroundValues); };
bool KameleonPlane::loadTexture() {
std::cout << "loadTexture()" << std::endl;
ghoul::opengl::Texture::FilterMode filtermode = ghoul::opengl::Texture::FilterMode::Linear;
ghoul::opengl::Texture::WrappingMode wrappingmode = ghoul::opengl::Texture::WrappingMode::ClampToEdge;
@@ -169,13 +199,18 @@ bool KameleonPlane::loadTexture() {
for(int option : selectedOptions){
if(!_dataSlices[option]){
std::cout << options[option].description << std::endl;
_dataSlices[option] = _kw->getUniformSliceValues(options[option].description, _dimensions, _slice.value());
std::stringstream memorystream(options[option].description);
std::string optionName;
getline(memorystream, optionName, '/');
getline(memorystream, optionName, '/');
// std::cout << options[option].description << std::endl;
_dataSlices[option] = _kw->getUniformSliceValues(optionName, _dimensions, _slice.value());
_dataProcessor->addValuesFromKameleonData(_dataSlices[option], _dimensions, options.size(), option);
}
}
std::vector<float*> data = _dataProcessor->processKameleonData(_dataSlices, _dimensions, _dataOptions);
std::vector<float*> data = _dataProcessor->processKameleonData2(_dataSlices, _dimensions, _dataOptions);
if(data.empty())
return false;
@@ -261,8 +296,6 @@ bool KameleonPlane::updateTexture(){
_textures[i] = std::move(nullptr);
}
loadTexture();
return true;
@@ -366,16 +399,16 @@ void KameleonPlane::fillOptions(){
for(std::string option : options){
if(option.size() < 4 && option != "x" && option != "y" && option != "z"){
_dataOptions.addOption({numOptions, option});
_dataOptions.addOption({numOptions, name()+"/"+option});
_dataSlices.push_back(nullptr);
_textures.push_back(nullptr);
numOptions++;
}
}
_dataOptions.setValue(std::vector<int>(1,0));
_dataOptions.onChange([this](){loadTexture();});
if(!_data->groupName.empty())
if(_group)
IswaManager::ref().registerOptionsToGroup(_data->groupName, _dataOptions.options());
_dataOptions.onChange([this](){loadTexture();});
}
void KameleonPlane::updateFieldlineSeeds(){

View File

@@ -38,6 +38,16 @@
KameleonPlane(const ghoul::Dictionary& dictionary);
~KameleonPlane();
bool initialize() override;
protected:
virtual void useLog(bool useLog) override;
virtual void normValues(glm::vec2 normValues) override;
virtual void useHistogram(bool useHistogram) override;
virtual void dataOptions(std::vector<int> options) override;
virtual void transferFunctionsFile(std::string tfPath) override;
virtual void backgroundValues(glm::vec2 backgroundValues) override;
private:
virtual bool loadTexture() override;
virtual bool updateTexture() override;

View File

@@ -48,6 +48,7 @@ DataProcessor::DataProcessor(bool useLog, bool useHistogram, glm::vec2 normValue
,_useHistogram(useHistogram)
,_normValues(normValues)
,_filterValues(glm::vec2(0))
,_numValues(0)
{
_coordinateVariables = {"x", "y", "z", "phi", "theta"};
};
@@ -115,11 +116,67 @@ std::vector<std::string> DataProcessor::readJSONHeader(std::string& dataBuffer){
return options;
}
void DataProcessor::addValues(std::string& dataBuffer, properties::SelectionProperty dataOptions){
int numOptions = dataOptions.options().size();
if(_min.empty()) _min = std::vector<float>(numOptions, std::numeric_limits<float>::max());
if(_max.empty()) _max = std::vector<float>(numOptions, std::numeric_limits<float>::min());
if(_sum.empty()) _sum = std::vector<float>(numOptions, 0.0f);
if(_sd.empty()) _sd = std::vector<float>(numOptions, 0.0f);
if(_numValues.empty()) _numValues= std::vector<float>(numOptions, 0.0f);
if(_histograms.empty())_histograms = std::vector<std::shared_ptr<Histogram>>(numOptions, nullptr);
if(!dataBuffer.empty()){
std::stringstream memorystream(dataBuffer);
std::string line;
std::vector<float> sum(numOptions, 0.0f);
std::vector<std::vector<float>> values(numOptions, std::vector<float>());
int numValues = 0;
while(getline(memorystream, line)){
if(line.find("#") == 0) continue;
std::stringstream ss(line);
std::vector<float> value;
float v;
while(ss >> v){
value.push_back(v);
}
if(value.size()){
for(int i=0; i<numOptions; i++){
float v = value[i+3];
values[i].push_back(v);
_min[i] = std::min(_min[i], v);
_max[i] = std::max(_max[i], v);
sum[i] += v;
}
numValues++;
}
}
for(int i=0; i<numOptions; i++){
float mean = (1.0/numValues)*sum[i];
float var = 0;
for(int j=0; j<numValues; j++){
var += pow(values[i][j] - mean, 2);
}
float sd = sqrt(var / numValues);
_sum[i] += sum[i];
_sd[i] = sqrt(pow(_sd[i],2) + pow(sd, 2));
_numValues[i] += numValues;
std::cout << i << " " << _numValues[i] << " " << _sum[i] << " " << _sd[i] << std::endl;
}
}
}
std::vector<float*> DataProcessor::readData(std::string& dataBuffer, properties::SelectionProperty dataOptions){
if(!dataBuffer.empty()){
// if(!_dataOptions.options().size()) // load options for value selection
// readHeader(dataBuffer);
std::stringstream memorystream(dataBuffer);
std::string line;
@@ -207,18 +264,61 @@ std::vector<float*> DataProcessor::readData(std::string& dataBuffer, properties:
}
}
std::vector<float*> DataProcessor::readData2(std::string& dataBuffer, properties::SelectionProperty dataOptions){
if(!dataBuffer.empty()){
std::stringstream memorystream(dataBuffer);
std::string line;
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
std::vector<std::vector<float>> values(selectedOptions.size(), std::vector<float>());
std::vector<float*> data(dataOptions.options().size(), nullptr);
for(int option : selectedOptions){
data[option] = new float[_dimensions.x*_dimensions.y]{0.0f};
}
int numValues = 0;
while(getline(memorystream, line)){
if(line.find("#") == 0){ //part of the header
continue;
}
std::stringstream ss(line);
std::vector<float> value;
float v;
while(ss >> v){
value.push_back(v);
}
if(value.size()){
for(int option : selectedOptions){
float v = value[option+3]; //+3 because "options" x, y and z.
data[option][numValues] = processDataPoint(v, option);
}
}
numValues++;
}
if(numValues != _dimensions.x*_dimensions.y){
LWARNING("Number of values read and expected are not the same");
return std::vector<float*>();
}
return data;
}else{
return std::vector<float*>();
}
}
std::vector<float*> DataProcessor::readJSONData(std::string& dataBuffer, properties::SelectionProperty dataOptions){
if(!dataBuffer.empty()){
json j = json::parse(dataBuffer);
json var = j["variables"];
// if(!_dataOptions.options().size()) // load options for value selection
// readHeader(dataBuffer);
// std::stringstream memorystream(dataBuffer);
// std::string line;
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
@@ -262,7 +362,6 @@ std::vector<float*> DataProcessor::readJSONData(std::string& dataBuffer, propert
sum[i] += v;
}
// break;
}
i++;
}
@@ -279,23 +378,210 @@ std::vector<float*> DataProcessor::readJSONData(std::string& dataBuffer, propert
}
}
std::vector<float*> DataProcessor::processKameleonData(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions){
void DataProcessor::addValuesFromJSON(std::string& dataBuffer, properties::SelectionProperty dataOptions){
int numOptions = dataOptions.options().size();
if(_min.empty()) _min = std::vector<float>(numOptions, std::numeric_limits<float>::max());
if(_max.empty()) _max = std::vector<float>(numOptions, std::numeric_limits<float>::min());
if(_sum.empty()) _sum = std::vector<float>(numOptions, 0.0f);
if(_sd.empty()) _sd = std::vector<float>(numOptions, 0.0f);
if(_numValues.empty()) _numValues= std::vector<float>(numOptions, 0.0f);
if(_histograms.empty())_histograms = std::vector<std::shared_ptr<Histogram>>(numOptions, nullptr);
if(!dataBuffer.empty()){
json j = json::parse(dataBuffer);
json var = j["variables"];
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
std::vector<float> sum(numOptions, 0.0f);
std::vector<std::vector<float>> values(numOptions, std::vector<float>());
auto options = dataOptions.options();
std::vector<float*> data(options.size(), nullptr);
int i = 0;
for(int i=0; i<numOptions; i++){
std::stringstream memorystream(options[i].description);
std::string optionName;
getline(memorystream, optionName, '/');
getline(memorystream, optionName, '/');
json valueArray = var[optionName];
int ySize = valueArray.size();
for(int y=0; y<valueArray.size(); y++){
json value = valueArray.at(y);
for(int x=0; x<value.size(); x++){
float v = value.at(x);
values[i].push_back(v);
_min[i] = std::min(_min[i],v);
_max[i] = std::min(_max[i],v);
sum[i] += v;
}
}
}
for(int i=0; i<numOptions; i++){
int numValues = values[i].size();
float mean = (1.0/numValues)*sum[i];
float var = 0;
for(int j=0; j<numValues; j++){
var += pow(values[i][j] - mean, 2);
}
float sd = sqrt(var / numValues);
_sum[i] += sum[i];
_sd[i] = sqrt(pow(_sd[i],2) + pow(sd, 2));
_numValues[i] += numValues;
}
}
}
std::vector<float*> DataProcessor::readJSONData2(std::string& dataBuffer, properties::SelectionProperty dataOptions){
if(!dataBuffer.empty()){
json j = json::parse(dataBuffer);
json var = j["variables"];
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
std::vector<float> sum(numSelected, 0.0f);
std::vector<std::vector<float>> values(numSelected, std::vector<float>());
auto options = dataOptions.options();
std::vector<float*> data(options.size(), nullptr);
for(int option : selectedOptions){
data[option] = new float[_dimensions.x*_dimensions.y]{0.0f};
std::stringstream memorystream(options[option].description);
std::string optionName;
getline(memorystream, optionName, '/');
getline(memorystream, optionName, '/');
json yArray = var[optionName];
for(int y=0; y<yArray.size(); y++){
json xArray = yArray.at(y);
for(int x=0; x<xArray.size(); x++){
int i = x + y*xArray.size();
// std::cout << _dimensions.x*_dimensions.y << " " << i << std::endl;
float v = xArray.at(x);
data[option][i] = processDataPoint(v, option);
}
}
}
return data;
}
else {
// LWARNING("Nothing in memory buffer, are you connected to the information super highway?");
return std::vector<float*>();
}
}
void DataProcessor::addValuesFromKameleonData(float* kdata, glm::size3_t dimensions, int numOptions, int option){
if(_min.empty()) _min = std::vector<float>(numOptions, std::numeric_limits<float>::max());
if(_max.empty()) _max = std::vector<float>(numOptions, std::numeric_limits<float>::min());
if(_sum.empty()) _sum= std::vector<float>(numOptions, 0.0f);
if(_sd.empty()) _sd= std::vector<float>(numOptions, 0.0f);
if(_numValues.empty()) _numValues= std::vector<float>(numOptions, 0.0f);
if(_histograms.empty())_histograms = std::vector<std::shared_ptr<Histogram>>(numOptions, nullptr);
int numValues = dimensions.x*dimensions.y*dimensions.z;
float sum = 0;
for(int i=0; i<numValues; i++){
float v = kdata[i];
_min[option] = std::min(_min[option],v);
_max[option] = std::max(_max[option],v);
sum += v;
}
float mean = (1.0 / numValues) * sum;
float var = 0;
for(int i=0; i<numValues; i++){
var += pow(kdata[i] - mean, 2);
}
float sd = sqrt ( var / numValues );
_sum[option] += sum;
_sd[option] = sqrt(pow(_sd[option],2)+ pow(sd,2));
_numValues[option] += numValues;
}
std::vector<float*> DataProcessor::processKameleonData2(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions){
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
std::vector<float> min(numSelected, std::numeric_limits<float>::max());
std::vector<std::vector<float>> values(selectedOptions.size(), std::vector<float>());
std::vector<float*> data(dataOptions.options().size(), nullptr);
int numValues = dimensions.x*dimensions.y*dimensions.z;
for(int option : selectedOptions){
data[option] = new float[numValues]{0.0f};
for(int i=0; i<numValues; i++){
float v = kdata[option][i];
data[option][i] = processDataPoint(v, option);
}
}
return data;
}
std::vector<float*> DataProcessor::processKameleonData(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions){
std::vector<int> selectedOptions = dataOptions.value();
int numSelected = selectedOptions.size();
auto options = dataOptions.options();
int numOptions = options.size();
if(_min.empty()){
_min = std::vector<float>(numOptions, std::numeric_limits<float>::max());
}
if(_max.empty()){
_max = std::vector<float>(numOptions, std::numeric_limits<float>::min());
}
if(_sum.empty()){
_sum= std::vector<float>(numOptions, 0.0f);
}
if(_sd.empty()){
_sd= std::vector<float>(numOptions, 0.0f);
}
if(_histograms.empty()){
_histograms = std::vector<std::shared_ptr<Histogram>>(numOptions, nullptr);
}
std::vector<float> min(numSelected, std::numeric_limits<float>::max());
std::vector<float> max(numSelected, std::numeric_limits<float>::min());
std::vector<float> sum(numSelected, 0.0f);
std::vector<std::vector<float>> optionValues(numSelected, std::vector<float>());
auto options = dataOptions.options();
std::vector<float*> data(options.size(), nullptr);
int numValues = dimensions.x*dimensions.y*dimensions.z;
int i = 0;
for(int option : selectedOptions){
bool calculateMin = (_min[option] == std::numeric_limits<float>::max());
bool calculateMax = (_max[option] == std::numeric_limits<float>::min());
bool claculateSum = (_sum[option] == 0.0f);
data[option] = new float[numValues]{0.0f};
for(int j=0; j<numValues; j++){
@@ -314,18 +600,28 @@ std::vector<float*> DataProcessor::processKameleonData(std::vector<float*> kdata
max[i] = std::max(max[i], v);
sum[i] += v;
if(calculateMin)
_min[option] = std::min(_min[option],v);
if(calculateMax)
_max[option] = std::max(_max[option],v);
if(claculateSum)
_sum[option] += v;
}
i++;
// if(calculateMin)
// std::cout << _min[option] << std::endl;
}
for(int i=0; i<numSelected; i++){
processData(data[ selectedOptions[i] ], optionValues[i], min[i], max[i], sum[i]);
int selected = selectedOptions[i];
processData(data[ selected ], optionValues[i], _min[selected], _max[selected], _sum[selected], selected);
}
return data;
}
void DataProcessor::processData(float* outputData, std::vector<float>& inputData, float min, float max,float sum){
void DataProcessor::processData(float* outputData, std::vector<float>& inputData, float min, float max,float sum, int selected){
const int numValues = inputData.size();
Histogram histogram(min, max, 512);
@@ -371,6 +667,14 @@ void DataProcessor::processData(float* outputData, std::vector<float>& inputData
// equalized.print();
}
float DataProcessor::processDataPoint(float value, int option){
if(_numValues.empty()) return 0.0f;
float mean = (1.0 / _numValues[option]) * _sum[option];
float v = normalizeWithStandardScore(value, mean, _sd[option]);
return v;
}
float DataProcessor::normalizeWithStandardScore(float value, float mean, float sd){
float zScoreMin = _normValues.x;
@@ -386,4 +690,12 @@ glm::vec2 DataProcessor::filterValues(){
return _filterValues;
}
void DataProcessor::clear(){
_min.clear();
_max.clear();
_sum.clear();
_sd.clear();
_histograms.clear();
}
}

View File

@@ -31,6 +31,7 @@
#include <ghoul/glm.h>
#include <ghoul/opengl/texture.h>
#include <set>
#include <openspace/util/histogram.h>
namespace openspace{
class DataProcessor{
@@ -57,23 +58,33 @@ public:
std::vector<std::string> readHeader(std::string& dataBuffer);
std::vector<float*> readData(std::string& dataBuffer, properties::SelectionProperty dataOptions);
std::vector<float*> readData2(std::string& dataBuffer, properties::SelectionProperty dataOptions);
void addValues(std::string& dataBuffer, properties::SelectionProperty dataOptions);
std::vector<std::string> readJSONHeader(std::string& dataBuffer);
std::vector<float*> readJSONData(std::string& dataBuffer, properties::SelectionProperty dataOptions);
std::vector<float*> readJSONData2(std::string& dataBuffer, properties::SelectionProperty dataOptions);
void addValuesFromJSON(std::string& dataBuffer, properties::SelectionProperty dataOptions);
std::vector<float*> processKameleonData(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions);
std::vector<float*> processKameleonData2(std::vector<float*> kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions);
void addValuesFromKameleonData(float* kdata, glm::size3_t dimensions, int numOptions, int option);
void clear();
glm::vec2 filterValues();
private:
void processData(
float* outputData, // Where you want your processed data to go
std::vector<float>& inputData, //data that needs processing
float min, // min value of the input data
float max, // max valye of the input data
float sum // sum of the input data
float sum, // sum of the input data
int selected = 0
);
float processDataPoint(float value, int option);
float normalizeWithStandardScore(float value, float mean, float sd);
glm::size3_t _dimensions;
@@ -82,6 +93,13 @@ private:
glm::vec2 _normValues;
glm::vec2 _filterValues;
std::vector<float> _min;
std::vector<float> _max;
std::vector<float> _sum;
std::vector<float> _sd;
std::vector<float> _numValues;
std::vector<std::shared_ptr<Histogram>> _histograms;
// int _numValues;
std::set<std::string> _coordinateVariables;
};

View File

@@ -201,12 +201,13 @@ std::string IswaManager::iswaUrl(int id, std::string type){
return url;
}
void IswaManager::registerToGroup(std::string name, CygnetType type, IswaCygnet* cygnet){
std::shared_ptr<IswaGroup> IswaManager::registerToGroup(std::string name, CygnetType type, IswaCygnet* cygnet){
if(_groups.find(name) == _groups.end()){
_groups.insert(std::pair<std::string, std::shared_ptr<IswaGroup>>(name, std::make_shared<IswaGroup>(name)));
}
_groups[name]->registerCygnet(cygnet, type);
return _groups[name];
}
void IswaManager::unregisterFromGroup(std::string name, IswaCygnet* cygnet){
@@ -343,7 +344,7 @@ std::string IswaManager::parseKWToLuaTable(std::string kwPath, std::string cut,
}
std::string table = "{"
"Name = 'KameleonPlane_"+cut+"',"
"Name = 'KameleonPlane-"+cut+"',"
"Parent = '" + parent + "', "
"Renderable = {"
"Type = 'KameleonPlane', "

View File

@@ -83,7 +83,7 @@ public:
std::future<DownloadManager::MemoryFile> fetchDataCygnet(int id);
std::string iswaUrl(int id, std::string type = "image");
void registerToGroup(std::string name, CygnetType type, IswaCygnet* cygnet);
std::shared_ptr<IswaGroup> registerToGroup(std::string name, CygnetType type, IswaCygnet* cygnet);
void unregisterFromGroup(std::string name, IswaCygnet* cygnet);
void registerOptionsToGroup(std::string name, const std::vector<properties::SelectionProperty::Option>& options);
std::shared_ptr<IswaGroup> iswaGroup(std::string name);

View File

@@ -75,7 +75,7 @@ void renderOptionProperty(Property* prop) {
void renderSelectionProperty(Property* prop) {
SelectionProperty* p = static_cast<SelectionProperty*>(prop);
std::string name = p->guiName();
if (ImGui::CollapsingHeader((name).c_str())) {
const std::vector<SelectionProperty::Option>& options = p->options();
std::vector<int> newSelectedIndices;