Feature/WSAdocs (#3715)

* documentation in FITS renderable

* selected color range bug fix, parameter documentation for fits sphere and field lines sequence renderables

* Very compact description in mission panel

* field line vs fieldline

* Alex comments

* Add missing punctuation

* emmas comments

---------

Co-authored-by: Emma Broman <emma.broman@liu.se>
This commit is contained in:
ElonOlsson
2025-06-16 11:09:06 -04:00
committed by GitHub
parent f8672d6064
commit 2829f259ac
7 changed files with 109 additions and 61 deletions

View File

@@ -4,35 +4,19 @@ local Mission = {
Name = "The WSA Simulation Model",
TimeRange = { Start = "2022 DEC 09 16:14:00", End = timeNow },
Description = [[
This profile shows the Sun and its magnetic polarities, using data from the WSA
(Wang-Sheeley-Arge) simulation model version 5.4. The solar coronal portion of WSA is
comprised of two potential field type models. The inner model is Potential Field
Source Surface (PFSS) which specifies the coronal field from the inner, photospheric
boundary at 1 solar radii (Rs) to its outer boundary or source surface at 2.5Rs. The
outer model is the Schatten Current Sheet (SCS) model. The radial magnetic field
components of the PFSS magnetic field solution at 2.5Rs are used as the inner boundary
condition to the SCS model. All data is downloaded dynamically, bringing you the
latest data from the model. You can find these assets in the Scene menu under
"Solar System/Heliosphere". Under the "WSA Coronal Model" submenu, you will find extra
options for the solar field lines and surface features. The four different sets of
field lines are all following the magnetic fields but traced from different locations.
They can be colored by their different parameters in the data, for example polarity or
open or closed field lines. The two elements named "Solar Surface" show the magnetic
polarities, but have other options in the settings under "Texture Layer Options". The
same goes for the two named "Velocity at Outer Boundary". However, the two named
"Magnetic Field at 5Rs" do not have other options. Each asset includes settings for
appearance. If field lines are looking too bright against a bright background, try
changing the setting for additive blending. Additionally there is an option to save
the downloaded data for future use (by default, the data is not cached). Each data
file remains active until the next one in the sequence becomes available. To see which
file is currently being used, check the "Texture Source" field for each asset in the
GUI. In the visualization, the white line shooting out from the Sun, along with the
white arc, always points in the direction of Earth. The red arc is the Carrington
prime meridian which is longitude 0 of the Sun, and the green grid shows lines with a
10-degree separation. If no data is showing, most likely the selected time is outside
of the data range (e.g., too far in the future or the past for the dynamic data to be
available). Alternatively, the files failed to download. For more information on the
simulation model, see https://ccmc.gsfc.nasa.gov/models/WSA~5.4.
This visualization shows the Sun's magnetic field using data from the WSA
(Wang-Sheeley-Arge) simulation model. The field lines trace the Sun's magnetic field.
Some loop back into the Sun (closed, shown in yellow), while others stream into space
(open). The simulation data throughout this visualization is colored red for positive
values and blue for negative. Red field lines indicate that the direction of the field
is pointing away from the sun and blue that it is pointing inward toward the Sun. The
direction of the field is opposite on either side of whats called the heliospheric
current sheet. On the Sun's surface, white and black indicate areas of positive and
negative magnetic polarity, respectively. Understanding these fields is critical:
solar activity like Coronal Mass Ejections (CMEs) can disrupt satellites, power grids,
and pose risks to astronauts and spacecraft throughout the solar system. All
simulation data in this profile is fetched live, giving you the latest view of our
dynamic Sun.
]],
Milestones = {
{

View File

@@ -107,7 +107,8 @@ local WSA_54_Magnetograms_GONGZ = {
['1'] = "Flux tube expansion factor evaluated at the source surface",
['4'] = "Observed Photospheric Field (Gauss)",
['5'] = "Distance from open field footpoint to nearest coronal boundary (deg)",
['6'] = "Open (1,2,3) and closed (0) regions on the photosphere [1=in-to-out tracing; 2=out-to-in tracing; 3=both] (no units)",
['6'] = [[Open (1,2,3) and closed (0) regions on the photosphere [1=in-to-out
tracing; 2=out-to-in tracing; 3=both] (no units)]],
['7'] = "Distance to current sheet at outer boundary (degrees)"
},
LayerMinMaxCapValues = {
@@ -147,7 +148,8 @@ local WSA_54_Magnetograms_ADAPT = {
['1'] = "Flux tube expansion factor evaluated at the source surface",
['4'] = "Observed Photospheric Field (Gauss)",
['5'] = "Distance from open field footpoint to nearest coronal boundary (deg)",
['6'] = "Open (1,2,3) and closed (0) regions on the photosphere [1=in-to-out tracing; 2=out-to-in tracing; 3=both] (no units)",
['6'] = [[Open (1,2,3) and closed (0) regions on the photosphere [1=in-to-out
tracing; 2=out-to-in tracing; 3=both] (no units)]],
['7'] = "Distance to current sheet at outer boundary (degrees)"
},
LayerMinMaxCapValues = {

View File

@@ -81,7 +81,7 @@
"value": "false"
},
{
"name": "Scene.GanymedeMagnetosphere.Renderable.DomainEnabled",
"name": "Scene.GanymedeMagnetosphere.Renderable.Domain.DomainEnabled",
"type": "setPropertyValueSingle",
"value": "false"
},
@@ -106,12 +106,12 @@
"value": "40"
},
{
"name": "Scene.GanymedeMagnetosphere.Renderable.Flow.Speed",
"name": "Scene.GanymedeMagnetosphere.Renderable.Flow.FlowSpeed",
"type": "setPropertyValueSingle",
"value": "150.000000"
},
{
"name": "Scene.GanymedeMagnetosphere.Renderable.FlowEnabled",
"name": "Scene.GanymedeMagnetosphere.Renderable.Flow.FlowEnabled",
"type": "setPropertyValueSingle",
"value": "true"
},

View File

@@ -72,9 +72,10 @@ namespace {
};
constexpr openspace::properties::Property::PropertyInfo ColorMinMaxInfo = {
"ColorQuantityMinMax",
"ColorTable Min Value",
"Value to map to the lowest and highest end of the color table.",
"ColorMinMaxRange",
"Color Min Max Range",
"A min-max range for what the lowest and highest values of the color table can "
"be set to.",
openspace::properties::Property::Visibility::AdvancedUser
};
@@ -150,7 +151,7 @@ namespace {
};
constexpr openspace::properties::Property::PropertyInfo FlowReversedInfo = {
"Reversed",
"ReversedFlow",
"Reversed Flow",
"Toggle to make the flow move in the opposite direction.",
openspace::properties::Property::Visibility::User
@@ -171,7 +172,7 @@ namespace {
};
constexpr openspace::properties::Property::PropertyInfo FlowSpeedInfo = {
"Speed",
"FlowSpeed",
"Speed",
"Speed of the flow.",
openspace::properties::Property::Visibility::User
@@ -223,6 +224,28 @@ namespace {
openspace::properties::Property::Visibility::User
};
// This `Renderable` visualizes field lines, mainly a sequence of time steps but works
// with only one time step, too. A sequence is a data source consisting of multiple
// data files that each correspond to a specific time and is therefore time varying
// like the name of the renderable suggests.
//
// `LoadingType` can be specified in two ways;
// 1. `StaticLoading`: In this case all data is loaded when starting OpenSpace. A
// `SourceFolder` is then required. The data format is also required to be set with
// `InputFileType`.
//
// 2. `DynamicDownloading`: This case downloads the data during runtime. For this, a
// few parameters are required: `InfoURL` together with `DataID` will construct a URL
// that is used for a HTTP request that returns meta data. `DataURL` and `DataID`,
// together with this meta data, will be used in constructing another HTTP request
// that returns the list with data files. The `DataID` specify which data source to
// use.
//
// When using CDF data `SeedPointDirectory` is required. Some prior knowledge of the
// data is needed to use it in this way. `TracingVariable` needs to be set and
// `ExtraVariables` will have to match what parameters are in the CDF data. Using CDF
// directly in this `Renderable` is not recommended. Rather use the
// `KameleonVolumeToFieldlinesTask` task first, to save the data to .osfls or .json.
struct [[codegen::Dictionary(RenderableFieldlinesSequence)]] Parameters {
enum class [[codegen::map(openspace::RenderableFieldlinesSequence::ColorMethod)]]
ColorMethod {
@@ -240,14 +263,14 @@ namespace {
std::optional<glm::vec4> color [[codegen::color()]];
// A list of paths to transferfunction .txt files containing color tables
// used for colorizing the fieldlines according to different parameters
// used for colorizing the fieldlines according to different parameters.
std::optional<std::vector<std::filesystem::path>> colorTablePaths;
// Ranges for which their corresponding parameters values will be
// colorized by. Should be entered as min value, max value
// colorized by. Should be entered as min value, max value.
std::optional<std::vector<glm::vec2>> colorTableRanges;
// Specifies the total data range to where color map will be applied
// [[codegen::verbatim(ColorMinMaxInfo.description)]]
std::optional<glm::vec2> colorMinMaxRange;
// [[codegen::verbatim(FlowEnabledInfo.description)]]
@@ -275,7 +298,7 @@ namespace {
std::optional<int> maskingQuantity;
// Ranges for which their corresponding quantity parameter value will be
// masked by. Should be entered as a min value, max value pair.
// masked by. Should be entered as a list of min value, max value pairs.
std::optional<std::vector<glm::vec2>> maskingRanges;
// Ranges for which their corresponding parameters values will be
@@ -291,8 +314,10 @@ namespace {
// [[codegen::verbatim(ColorUseABlendingInfo.description)]]
std::optional<bool> alphaBlendingEnabled;
// Set if first/last file should render forever.
bool showAtAllTimes;
// Set if first/last file should render when time is outside of the sequence
// interval. This can be used regardless of LoadingType. If this value is not
// specified, the field lines are shown at all times.
std::optional<bool> showAtAllTimes;
// If data sets parameter start_time differ from start of run,
// elapsed_time_in_seconds might be in relation to start of run.
@@ -327,13 +352,13 @@ namespace {
// `DynamicDownloading`: Download and load files during run time.
std::optional<LoadingType> loadingType;
// A maximum number to limit the number of files being downloaded simultaneously.
std::optional<int> numberOfFilesToQueue;
// A data ID that corresponds to what dataset to use if using dynamic data
// downloading.
std::optional<int> dataID;
// A maximum number to limit the number of files being downloaded simultaneously.
std::optional<int> numberOfFilesToQueue;
// A URL to a JSON-formatted page with metadata for the `DataURL`.
// Required if using dynamic downloading.
std::optional<std::string> infoURL;
@@ -364,7 +389,8 @@ namespace {
// Extra variables that can be used to color the field lines.
std::optional<std::vector<std::string>> extraVariables;
// Which variable in CDF file to trace.
// Which variable in CDF file that represents which vector field in the data to
// trace field lines in.
std::optional<std::string> tracingVariable;
// Decides whether or not to cache the downloaded data between runs. By default,
@@ -531,7 +557,7 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(
_domainEnabled = p.domainEnabled.value_or(_domainEnabled);
_lineWidth = p.lineWidth.value_or(_lineWidth);
_colorABlendEnabled = p.alphaBlendingEnabled.value_or(_colorABlendEnabled);
_renderForever = p.showAtAllTimes;
_renderForever = p.showAtAllTimes.value_or(_renderForever);
_manualTimeOffset = p.manualTimeOffset.value_or(_manualTimeOffset);
_saveDownloadsOnShutdown = p.cacheData.value_or(_saveDownloadsOnShutdown);
@@ -539,7 +565,7 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(
staticallyLoadFiles(p.seedPointDirectory, p.tracingVariable);
computeSequenceEndTime();
}
// Color group
_colorTablePath = FieldlinesSequenceModule::DefaultTransferFunctionFile.string();
if (p.colorTablePaths.has_value()) {
for (const std::filesystem::path& path : *p.colorTablePaths) {
@@ -573,6 +599,12 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(
if (p.colorTableRanges.has_value()) {
_colorTableRanges = *p.colorTableRanges;
if (_colorTableRanges.size() > _colorQuantityTemp && _colorQuantityTemp >= 0) {
_selectedColorRange = _colorTableRanges[_colorQuantityTemp];
}
else {
_selectedColorRange = _colorTableRanges[0];
}
}
else {
_colorTableRanges.push_back(glm::vec2(0.f, 1.f));
@@ -583,6 +615,7 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(
_selectedColorRange.setMinValue(glm::vec2(p.colorMinMaxRange->x));
_selectedColorRange.setMaxValue(glm::vec2(p.colorMinMaxRange->y));
}
if (p.maskingRanges.has_value()) {
_maskingRanges = *p.maskingRanges;
}

View File

@@ -123,7 +123,7 @@ private:
// Estimated / calculated end of sequence
double _sequenceEndTime = 0.0;
// If there's just one state it should never disappear
bool _renderForever = false;
bool _renderForever = true;
bool _inInterval = false;
// Data ID that corresponds to what dataset to use if using DynamicDownloading

View File

@@ -106,7 +106,7 @@ private:
int _fitsLayerTemp = -1;
// If there's just one state it should never disappear
bool _renderForever = false;
bool _renderForever = true;
bool _inInterval = false;
bool _isLoadingStateFromDisk = false;

View File

@@ -99,7 +99,9 @@ namespace {
constexpr openspace::properties::Property::PropertyInfo FitsLayerInfo = {
"FitsLayer",
"Texture Layer",
"The index of the layer in the FITS file to use as texture.",
"The index, a whole positive number, of the layer in the FITS file to use as "
"texture. If not specified, the first layer in the data will be used regardless. "
"When specified, that data layer will be the option used.",
openspace::properties::Property::Visibility::AdvancedUser
};
@@ -125,6 +127,30 @@ namespace {
openspace::properties::Property::Visibility::AdvancedUser
};
// This `Renderable` reads a data sequence from specifically FITS files and makes
// textures from them and wraps them onto a sphere. A sequence is a data source
// consisting of multiple data files that each correspond to a specific
// time and is therefore time varying like the name of the renderable suggests.
//
// `LoadingType` can be specified in two ways;
// 1. `StaticLoading`: In this case, all data will be loaded on startup, from the
// location specified in the `TextureSource` parameter. Other required parameters are
// `LayerNames` and `LayerMinMaxCapValues` that require at least one entry each.
// `LayerNames` assigns a name to an index that corresponds to a layer in the FITS
// data to use. For each entry in `LayerNames`, there should also be a matching entry
// in the `LayerMinMaxCapValues` that specifies the min and max range for the data.
//
// 2. `DynamicDownloading`: This case downloads the data during runtime. In addition
// to `LayerNames` and `LayerMinMaxCapValues`, a few more parameters are required in
// this case: `InfoURL` together with `DataID` will construct a URL that is used for a
// HTTP request that returns meta data. `DataURL` and `DataID`, together with this
// meta data, will be used in constructing another HTTP request that returns the list
// with data files. The `DataID` specify which data source to use.
//
// In addition, but not required, the `FitsLayer` parameter can be specified to use a
// specific data layer for the sphere texture. The index should match one of the
// layers in `LayerNames` and `LayerMinMaxCapValues`. `CacheData` and `showAtAllTimes`
// are two other optional parameters.
struct [[codegen::Dictionary(RenderableTimeVaryingFitsSphere)]] Parameters {
// [[codegen::verbatim(TextureSourceInfo.description)]]
std::optional<std::filesystem::path> textureSource;
@@ -141,13 +167,13 @@ namespace {
// DynamicDownloading: Download and load files during run time.
std::optional<LoadingType> loadingType;
// A data ID that corresponds to what dataset to use if using dynamicWebContent.
std::optional<int> dataID;
// This is a max value of the amount of files to queue up
// so that not to big of a data set is downloaded.
std::optional<int> numberOfFilesToQueue;
// A data ID that corresponds to what dataset to use if using dynamic downloading.
std::optional<int> dataID;
// A URL that returns a JSON formated page with metadata needed for the dataURL.
std::optional<std::string> infoURL;
@@ -166,11 +192,14 @@ namespace {
std::optional<ghoul::Dictionary> layerMinMaxCapValues;
// This is set to false by default and will delete all the downloaded content when
// OpenSpace is shut down. Set to true to save all the downloaded files.
// OpenSpace is shut down, if using dynamic downloading. Set to true to save all
// the downloaded files.
std::optional<bool> cacheData;
// Set if first/last file should render outside of the sequence interval.
std::optional<bool> showPastFirstAndLastFile;
// Set if first/last file should render when time is outside of the sequence
// interval. This can be used regardless of LoadingType. If this value is not
// specified, the field lines are shown at all times.
std::optional<bool> showAtAllTimes;
};
#include "renderabletimevaryingfitssphere_codegen.cpp"
} // namespace
@@ -223,7 +252,7 @@ RenderableTimeVaryingFitsSphere::RenderableTimeVaryingFitsSphere(
ghoul::opengl::Texture::FilterMode::Nearest
);
_renderForever = p.showPastFirstAndLastFile.value_or(_renderForever);
_renderForever = p.showAtAllTimes.value_or(_renderForever);
_textureFilterProperty.onChange([this]() {
switch (_textureFilterProperty) {