diff --git a/data/scene/default.scene b/data/scene/default.scene index bfaabb6c9e..176c4600d1 100644 --- a/data/scene/default.scene +++ b/data/scene/default.scene @@ -30,11 +30,21 @@ function postInitialization() openspace.printInfo("Done setting default values") - openspace.iswa.addCygnet(0,"z"); + openspace.iswa.addCygnet(0,"x", "Kameleon"); + openspace.iswa.addCygnet(0,"y", "Kameleon"); + openspace.iswa.addCygnet(0,"z", "Kameleon"); + --openspace.iswa.addCygnet(-4,"Data"); - --openspace.iswa.addCygnet(-1,"Data","GM"); + + --penspace.iswa.addCygnet(-1,"Data"); + --openspace.iswa.addCygnet(-2,"Data"); + --openspace.iswa.addCygnet(-3,"Data"); + --openspace.iswa.addCygnet(-2,"Data","GM"); + --openspace.iswa.addCygnet(-1,"Data","GM"); --openspace.iswa.addCygnet(-3,"Data","GM"); + + --[[ openspace.iswa.addScreenSpaceCygnet( diff --git a/modules/iswa/rendering/cygnetplane.h b/modules/iswa/rendering/cygnetplane.h index 2bcad6d011..6703bd11dd 100644 --- a/modules/iswa/rendering/cygnetplane.h +++ b/modules/iswa/rendering/cygnetplane.h @@ -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; diff --git a/modules/iswa/rendering/dataplane.cpp b/modules/iswa/rendering/dataplane.cpp index a7894e2016..1594f67c8d 100644 --- a/modules/iswa/rendering/dataplane.cpp +++ b/modules/iswa/rendering/dataplane.cpp @@ -33,6 +33,7 @@ #include #include #include +#include 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( + _useLog.value(), + _useHistogram.value(), + _normValues + ); } setTransferFunctions(_transferFunctionsFile.value()); - _dataProcessor = std::make_shared( - _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 data = _dataProcessor->readData(_dataBuffer, _dataOptions); + std::vector data = _dataProcessor->readData2(_dataBuffer, _dataOptions); if(data.empty()) return false; - _backgroundValues.setValue(_dataProcessor->filterValues()); + // _backgroundValues.setValue(_dataProcessor->filterValues()); bool texturesReady = false; std::vector selectedOptions = _dataOptions.value(); @@ -297,7 +305,7 @@ void DataPlane::fillOptions(){ _textures.push_back(nullptr); } _dataOptions.setValue(std::vector(1,0)); - if(!_data->groupName.empty()) + if(_group) IswaManager::ref().registerOptionsToGroup(_data->groupName, _dataOptions.options()); } diff --git a/modules/iswa/rendering/dataplane.h b/modules/iswa/rendering/dataplane.h index 784d1abfa3..b9548d35e9 100644 --- a/modules/iswa/rendering/dataplane.h +++ b/modules/iswa/rendering/dataplane.h @@ -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; diff --git a/modules/iswa/rendering/datasphere.cpp b/modules/iswa/rendering/datasphere.cpp index be46c01cdc..f77c0dec1e 100644 --- a/modules/iswa/rendering/datasphere.cpp +++ b/modules/iswa/rendering/datasphere.cpp @@ -27,6 +27,7 @@ #include #include #include +#include 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( + _useLog.value(), + _useHistogram.value(), + _normValues + ); } setTransferFunctions(_transferFunctionsFile.value()); - _dataProcessor = std::make_shared( - _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 data = _dataProcessor->readJSONData(_dataBuffer, _dataOptions); + std::vector data = _dataProcessor->readJSONData2(_dataBuffer, _dataOptions); if(data.empty()) return false; diff --git a/modules/iswa/rendering/datasphere.h b/modules/iswa/rendering/datasphere.h index c576f38dd9..629194cd83 100644 --- a/modules/iswa/rendering/datasphere.h +++ b/modules/iswa/rendering/datasphere.h @@ -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; diff --git a/modules/iswa/rendering/iswacygnet.cpp b/modules/iswa/rendering/iswacygnet.cpp index cac55c0001..2703482d10 100644 --- a/modules/iswa/rendering/iswacygnet.cpp +++ b/modules/iswa/rendering/iswacygnet.cpp @@ -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(); @@ -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; } diff --git a/modules/iswa/rendering/iswacygnet.h b/modules/iswa/rendering/iswacygnet.h index 8a05cbebcb..bcb027df6b 100644 --- a/modules/iswa/rendering/iswacygnet.h +++ b/modules/iswa/rendering/iswacygnet.h @@ -125,6 +125,8 @@ protected: std::vector> _transferFunctions; std::future _futureObject; + std::shared_ptr _group; + IswaManager::CygnetType _type; }; diff --git a/modules/iswa/rendering/iswagroup.cpp b/modules/iswa/rendering/iswagroup.cpp index 88483884ee..2958a53bc0 100644 --- a/modules/iswa/rendering/iswagroup.cpp +++ b/modules/iswa/rendering/iswagroup.cpp @@ -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( + _useLog.value(), + _useHistogram.value(), + _normValues + ); } IswaGroup::~IswaGroup(){ @@ -103,7 +110,13 @@ void IswaGroup::registerOptions(const std::vector(1,0)); } @@ -187,4 +200,8 @@ void IswaGroup::clearGroup(){ unregisterProperties(); } +std::shared_ptr IswaGroup::dataProcessor(){ + return _dataProcessor; +} + } //namespace openspace \ No newline at end of file diff --git a/modules/iswa/rendering/iswagroup.h b/modules/iswa/rendering/iswagroup.h index 5293f4c782..424ceda866 100644 --- a/modules/iswa/rendering/iswagroup.h +++ b/modules/iswa/rendering/iswagroup.h @@ -33,6 +33,7 @@ // #include #include #include +#include namespace openspace{ @@ -47,6 +48,15 @@ public: void registerOptions(const std::vector& options); bool checkType(IswaManager::CygnetType type); void clearGroup(); + + std::shared_ptr dataProcessor(); + + // bool useLog(){return _useLog.value();}; + // glm::vec2 normValues(){return _normValues.value();}; + // bool useHistogram(){return _useHistogram.value();}; + // std::vector 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; std::vector _cygnets; IswaManager::CygnetType _type; }; diff --git a/modules/iswa/rendering/kameleonplane.cpp b/modules/iswa/rendering/kameleonplane.cpp index be3833abe8..08d91594ac 100644 --- a/modules/iswa/rendering/kameleonplane.cpp +++ b/modules/iswa/rendering/kameleonplane.cpp @@ -37,6 +37,7 @@ #include #include #include +#include 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( + _useLog.value(), + _useHistogram.value(), + _normValues + ); } - + setTransferFunctions(_transferFunctionsFile.value()); - _dataProcessor = std::make_shared( - _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 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 data = _dataProcessor->processKameleonData(_dataSlices, _dimensions, _dataOptions); + std::vector 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(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(){ diff --git a/modules/iswa/rendering/kameleonplane.h b/modules/iswa/rendering/kameleonplane.h index 3cef01515c..f04a1833a9 100644 --- a/modules/iswa/rendering/kameleonplane.h +++ b/modules/iswa/rendering/kameleonplane.h @@ -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 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; diff --git a/modules/iswa/util/dataprocessor.cpp b/modules/iswa/util/dataprocessor.cpp index 8b36032884..a78b13b8c0 100644 --- a/modules/iswa/util/dataprocessor.cpp +++ b/modules/iswa/util/dataprocessor.cpp @@ -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 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(numOptions, std::numeric_limits::max()); + if(_max.empty()) _max = std::vector(numOptions, std::numeric_limits::min()); + if(_sum.empty()) _sum = std::vector(numOptions, 0.0f); + if(_sd.empty()) _sd = std::vector(numOptions, 0.0f); + if(_numValues.empty()) _numValues= std::vector(numOptions, 0.0f); + if(_histograms.empty())_histograms = std::vector>(numOptions, nullptr); + + if(!dataBuffer.empty()){ + + std::stringstream memorystream(dataBuffer); + std::string line; + std::vector sum(numOptions, 0.0f); + std::vector> values(numOptions, std::vector()); + + int numValues = 0; + while(getline(memorystream, line)){ + if(line.find("#") == 0) continue; + + std::stringstream ss(line); + std::vector value; + float v; + while(ss >> v){ + value.push_back(v); + } + + if(value.size()){ + for(int i=0; i 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 DataProcessor::readData(std::string& dataBuffer, properties: } } + +std::vector DataProcessor::readData2(std::string& dataBuffer, properties::SelectionProperty dataOptions){ + if(!dataBuffer.empty()){ + std::stringstream memorystream(dataBuffer); + std::string line; + + std::vector selectedOptions = dataOptions.value(); + int numSelected = selectedOptions.size(); + + std::vector> values(selectedOptions.size(), std::vector()); + std::vector 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 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(); + } + + return data; + + }else{ + return std::vector(); + } +} + std::vector 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 selectedOptions = dataOptions.value(); int numSelected = selectedOptions.size(); @@ -262,7 +362,6 @@ std::vector DataProcessor::readJSONData(std::string& dataBuffer, propert sum[i] += v; } - // break; } i++; } @@ -279,23 +378,210 @@ std::vector DataProcessor::readJSONData(std::string& dataBuffer, propert } } -std::vector DataProcessor::processKameleonData(std::vector 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(numOptions, std::numeric_limits::max()); + if(_max.empty()) _max = std::vector(numOptions, std::numeric_limits::min()); + if(_sum.empty()) _sum = std::vector(numOptions, 0.0f); + if(_sd.empty()) _sd = std::vector(numOptions, 0.0f); + if(_numValues.empty()) _numValues= std::vector(numOptions, 0.0f); + if(_histograms.empty())_histograms = std::vector>(numOptions, nullptr); + + + if(!dataBuffer.empty()){ + json j = json::parse(dataBuffer); + json var = j["variables"]; + + std::vector selectedOptions = dataOptions.value(); + int numSelected = selectedOptions.size(); + std::vector sum(numOptions, 0.0f); + + std::vector> values(numOptions, std::vector()); + auto options = dataOptions.options(); + std::vector data(options.size(), nullptr); + int i = 0; + + for(int i=0; i DataProcessor::readJSONData2(std::string& dataBuffer, properties::SelectionProperty dataOptions){ + if(!dataBuffer.empty()){ + json j = json::parse(dataBuffer); + json var = j["variables"]; + + std::vector selectedOptions = dataOptions.value(); + int numSelected = selectedOptions.size(); + + std::vector sum(numSelected, 0.0f); + std::vector> values(numSelected, std::vector()); + auto options = dataOptions.options(); + + std::vector 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(); + } +} + + +void DataProcessor::addValuesFromKameleonData(float* kdata, glm::size3_t dimensions, int numOptions, int option){ + if(_min.empty()) _min = std::vector(numOptions, std::numeric_limits::max()); + if(_max.empty()) _max = std::vector(numOptions, std::numeric_limits::min()); + if(_sum.empty()) _sum= std::vector(numOptions, 0.0f); + if(_sd.empty()) _sd= std::vector(numOptions, 0.0f); + if(_numValues.empty()) _numValues= std::vector(numOptions, 0.0f); + if(_histograms.empty())_histograms = std::vector>(numOptions, nullptr); + + + int numValues = dimensions.x*dimensions.y*dimensions.z; + float sum = 0; + + for(int i=0; i DataProcessor::processKameleonData2(std::vector kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions){ std::vector selectedOptions = dataOptions.value(); int numSelected = selectedOptions.size(); - std::vector min(numSelected, std::numeric_limits::max()); + std::vector> values(selectedOptions.size(), std::vector()); + std::vector 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 DataProcessor::processKameleonData(std::vector kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions){ + std::vector selectedOptions = dataOptions.value(); + int numSelected = selectedOptions.size(); + auto options = dataOptions.options(); + int numOptions = options.size(); + + if(_min.empty()){ + _min = std::vector(numOptions, std::numeric_limits::max()); + } + + if(_max.empty()){ + _max = std::vector(numOptions, std::numeric_limits::min()); + } + + if(_sum.empty()){ + _sum= std::vector(numOptions, 0.0f); + } + + if(_sd.empty()){ + _sd= std::vector(numOptions, 0.0f); + } + + if(_histograms.empty()){ + _histograms = std::vector>(numOptions, nullptr); + } + + + std::vector min(numSelected, std::numeric_limits::max()); std::vector max(numSelected, std::numeric_limits::min()); std::vector sum(numSelected, 0.0f); std::vector> optionValues(numSelected, std::vector()); - auto options = dataOptions.options(); std::vector 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::max()); + bool calculateMax = (_max[option] == std::numeric_limits::min()); + bool claculateSum = (_sum[option] == 0.0f); + data[option] = new float[numValues]{0.0f}; for(int j=0; j DataProcessor::processKameleonData(std::vector 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& inputData, float min, float max,float sum){ +void DataProcessor::processData(float* outputData, std::vector& 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& 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(); +} + } \ No newline at end of file diff --git a/modules/iswa/util/dataprocessor.h b/modules/iswa/util/dataprocessor.h index 1134ee2b1c..b6517af0d0 100644 --- a/modules/iswa/util/dataprocessor.h +++ b/modules/iswa/util/dataprocessor.h @@ -31,6 +31,7 @@ #include #include #include +#include namespace openspace{ class DataProcessor{ @@ -57,23 +58,33 @@ public: std::vector readHeader(std::string& dataBuffer); std::vector readData(std::string& dataBuffer, properties::SelectionProperty dataOptions); + std::vector readData2(std::string& dataBuffer, properties::SelectionProperty dataOptions); + void addValues(std::string& dataBuffer, properties::SelectionProperty dataOptions); std::vector readJSONHeader(std::string& dataBuffer); std::vector readJSONData(std::string& dataBuffer, properties::SelectionProperty dataOptions); + std::vector readJSONData2(std::string& dataBuffer, properties::SelectionProperty dataOptions); + void addValuesFromJSON(std::string& dataBuffer, properties::SelectionProperty dataOptions); std::vector processKameleonData(std::vector kdata, glm::size3_t dimensions, properties::SelectionProperty dataOptions); + std::vector processKameleonData2(std::vector 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& 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 _min; + std::vector _max; + std::vector _sum; + std::vector _sd; + std::vector _numValues; + std::vector> _histograms; + // int _numValues; std::set _coordinateVariables; }; diff --git a/modules/iswa/util/iswamanager.cpp b/modules/iswa/util/iswamanager.cpp index 4cdfbe9b55..e56520da6e 100644 --- a/modules/iswa/util/iswamanager.cpp +++ b/modules/iswa/util/iswamanager.cpp @@ -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 IswaManager::registerToGroup(std::string name, CygnetType type, IswaCygnet* cygnet){ if(_groups.find(name) == _groups.end()){ _groups.insert(std::pair>(name, std::make_shared(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', " diff --git a/modules/iswa/util/iswamanager.h b/modules/iswa/util/iswamanager.h index 63144923a1..5b8811159c 100644 --- a/modules/iswa/util/iswamanager.h +++ b/modules/iswa/util/iswamanager.h @@ -83,7 +83,7 @@ public: std::future fetchDataCygnet(int id); std::string iswaUrl(int id, std::string type = "image"); - void registerToGroup(std::string name, CygnetType type, IswaCygnet* cygnet); + std::shared_ptr registerToGroup(std::string name, CygnetType type, IswaCygnet* cygnet); void unregisterFromGroup(std::string name, IswaCygnet* cygnet); void registerOptionsToGroup(std::string name, const std::vector& options); std::shared_ptr iswaGroup(std::string name); diff --git a/modules/onscreengui/src/renderproperties.cpp b/modules/onscreengui/src/renderproperties.cpp index 756d0e8f94..f9b1bf42ad 100644 --- a/modules/onscreengui/src/renderproperties.cpp +++ b/modules/onscreengui/src/renderproperties.cpp @@ -75,7 +75,7 @@ void renderOptionProperty(Property* prop) { void renderSelectionProperty(Property* prop) { SelectionProperty* p = static_cast(prop); std::string name = p->guiName(); - + if (ImGui::CollapsingHeader((name).c_str())) { const std::vector& options = p->options(); std::vector newSelectedIndices;