Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 244 additions & 18 deletions src/wxNcVisFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,77 @@ wxNcVisFrame::wxNcVisFrame(
m_vecwxImageBounds[2] = NULL;
m_vecwxImageBounds[3] = NULL;

for (size_t i = 0; i < vecFilenames.size(); i++) {
NcVisFileInfo info;
info.filename = vecFilenames[i];
m_vecInputFileInfo.push_back(info);
}

std::cout << "Multi-file input count: " << m_vecInputFileInfo.size() << std::endl;
for (size_t i = 0; i < m_vecInputFileInfo.size(); i++) {
std::cout << " [" << i << "] "
<< m_vecInputFileInfo[i].filename.ToStdString()
<< std::endl;
}


for (size_t i = 0; i < m_vecInputFileInfo.size(); i++) {

NcFile ncfile(m_vecInputFileInfo[i].filename.mb_str());

if (!ncfile.is_valid()) {
_EXCEPTION1("Unable to open file \"%s\"",
m_vecInputFileInfo[i].filename.ToStdString().c_str());
}

NcDim * dimTime = ncfile.get_dim("time");
NcDim * dimLat = ncfile.get_dim("lat");
NcDim * dimLon = ncfile.get_dim("lon");

if (dimTime != NULL) {
m_vecInputFileInfo[i].timeCount = dimTime->size();
} else {
m_vecInputFileInfo[i].timeCount = 1;
}

if (dimLat != NULL) {
m_vecInputFileInfo[i].latCount = dimLat->size();
}

if (dimLon != NULL) {
m_vecInputFileInfo[i].lonCount = dimLon->size();
}
}

if (m_vecInputFileInfo.size() > 1) {
for (size_t i = 1; i < m_vecInputFileInfo.size(); i++) {
if (m_vecInputFileInfo[i].latCount != m_vecInputFileInfo[0].latCount) {
_EXCEPTION1(
"Latitude dimension mismatch at file %i",
i);
}

if (m_vecInputFileInfo[i].lonCount != m_vecInputFileInfo[0].lonCount) {
_EXCEPTION1(
"Longitude dimension mismatch at file %i",
i);
}
}
}

m_vecGlobalTime.clear();

for (size_t i = 0; i < m_vecInputFileInfo.size(); i++) {
for (int t = 0; t < m_vecInputFileInfo[i].timeCount; t++) {
NcVisTimeRef ref;
ref.fileIndex = i;
ref.localTimeIndex = t;
m_vecGlobalTime.push_back(ref);
}
}

m_iCurrentGlobalTimeIndex = 0;

for (size_t d = 0; d < NcVarMaximumDimensions; d++) {
m_vecwxDimIndex[d] = NULL;
m_vecwxPlayButton[d] = NULL;
Expand Down Expand Up @@ -705,6 +776,45 @@ void wxNcVisFrame::OpenFiles(

////////////////////////////////////////////////////////////////////////////////

int wxNcVisFrame::GetCurrentFileIndex() const {
if (m_vecGlobalTime.size() == 0) {
return -1;
}
return m_vecGlobalTime[m_iCurrentGlobalTimeIndex].fileIndex;
}

int wxNcVisFrame::GetCurrentLocalTimeIndex() const {
if (m_vecGlobalTime.size() == 0) {
return -1;
}
return m_vecGlobalTime[m_iCurrentGlobalTimeIndex].localTimeIndex;
}

////////////////////////////////////////////////////////////////////////////////

void wxNcVisFrame::UpdateActiveVariableFromGlobalTime() {
if (m_strVarActiveName == "") {
return;
}

if (m_vecGlobalTime.size() == 0) {
return;
}

int iFile = GetCurrentFileIndex();
if (iFile < 0) {
return;
}

_ASSERT(iFile < static_cast<int>(m_vecpncfiles.size()));
_ASSERT(m_vecpncfiles[iFile] != NULL);

m_varActive = m_vecpncfiles[iFile]->get_var(m_strVarActiveName.c_str());
_ASSERT(m_varActive != NULL);
}

////////////////////////////////////////////////////////////////////////////////

void wxNcVisFrame::InitializeWindow() {

// Get the list of shapefiles in the resource dir
Expand Down Expand Up @@ -895,6 +1005,8 @@ void wxNcVisFrame::LoadData() {
std::cout << "LOAD DATA" << std::endl;
}

UpdateActiveVariableFromGlobalTime();

// Assume data is not unstructured
m_fIsVarActiveUnstructured = false;

Expand Down Expand Up @@ -1453,10 +1565,83 @@ void wxNcVisFrame::SetDisplayedDimensionValue(
_ASSERT(m_varActive != NULL);
_ASSERT(m_vecwxDimIndex[lDim] != NULL);

m_vecwxDimIndex[lDim]->ChangeValue(wxString::Format("%li", lValue));
//m_vecwxDimIndex[lDim]->ChangeValue(wxString::Format("%li", lValue));

std::string strDimName(m_varActive->get_dim(lDim)->name());

if ((strDimName == "time") && (m_vecGlobalTime.size() > 0)) {
m_vecwxDimIndex[lDim]->ChangeValue(
wxString::Format("%i", m_iCurrentGlobalTimeIndex));
} else {
m_vecwxDimIndex[lDim]->ChangeValue(wxString::Format("%li", lValue));
}

if (m_vecwxDimValue[lDim] != NULL) {
std::string strDimName(m_varActive->get_dim(lDim)->name());
//std::string strDimName(m_varActive->get_dim(lDim)->name());

if (strDimName == "time") {
int iFile = GetCurrentFileIndex();
if ((iFile >= 0) && (iFile < static_cast<int>(m_vecpncfiles.size()))) {
NcVar * varTime = m_vecpncfiles[iFile]->get_var("time");
if (varTime != NULL) {
NcAtt * attUnits = varTime->get_att("units");
NcAtt * attCalendar = varTime->get_att("calendar");

std::string strUnits;
std::string strCalendar = "standard";

if (attUnits != NULL) {
NcValues * pValues = attUnits->values();
if (pValues != NULL) {
const char * szUnits = pValues->as_string(0);
if (szUnits != NULL) {
strUnits = szUnits;
}
delete pValues;
}
delete attUnits;
}

if (attCalendar != NULL) {
NcValues * pValues = attCalendar->values();
if (pValues != NULL) {
const char * szCalendar = pValues->as_string(0);
if (szCalendar != NULL) {
strCalendar = szCalendar;
}
delete pValues;
}
delete attCalendar;
}

double dTimeValue = 0.0;
long lLocalTime = GetCurrentLocalTimeIndex();
varTime->set_cur(lLocalTime);
varTime->get(&dTimeValue, 1);

if (strUnits != "") {
Time time(Time::CalendarTypeFromString(strCalendar));
if (time.FromCFCompliantUnitsOffsetDouble(strUnits, dTimeValue)) {
m_vecwxDimValue[lDim]->ChangeValue(time.ToString());
} else {
m_vecwxDimValue[lDim]->ChangeValue(
wxString::Format("%g %s", dTimeValue, strUnits));
}
} else {
m_vecwxDimValue[lDim]->ChangeValue(wxString::Format("%g", dTimeValue));
}
return;
}
}
}

std::cout
<< "SetDisplayedDimensionValue: dim=" << strDimName
<< ", file=" << GetCurrentFileIndex()
<< ", local=" << GetCurrentLocalTimeIndex()
<< ", shown index=" << lValue
<< std::endl;

auto it = m_mapDimData.find(strDimName);
if (it != m_mapDimData.end()) {
std::string strDimUnits(it->second.units());
Expand Down Expand Up @@ -1954,6 +2139,7 @@ void wxNcVisFrame::OnVariableSelected(

// Change the active variable
std::string strValue = event.GetString().ToStdString();
m_strVarActiveName = strValue;

int vc = static_cast<int>(event.GetId() - ID_VARSELECTOR);
_ASSERT((vc >= 0) && (vc < NcVarMaximumDimensions));
Expand Down Expand Up @@ -2336,28 +2522,68 @@ void wxNcVisFrame::OnDimButtonClicked(wxCommandEvent & event) {
eDimCommand = DIMCOMMAND_DECREMENT;
d -= ID_DIMDOWN;

long lDimSize = m_varActive->get_dim(d)->size();
if (m_lVarActiveDims[d] == 0) {
m_lVarActiveDims[d] = lDimSize-1;
} else {
m_lVarActiveDims[d]--;
}

SetDisplayedDimensionValue(d, m_lVarActiveDims[d]);
if ((std::string(m_varActive->get_dim(d)->name()) == "time") && (m_vecGlobalTime.size() > 0)) {
if (m_iCurrentGlobalTimeIndex == 0) {
m_iCurrentGlobalTimeIndex = m_vecGlobalTime.size() - 1;
} else {
m_iCurrentGlobalTimeIndex--;
}

m_lVarActiveDims[d] = GetCurrentLocalTimeIndex();

} else {
long lDimSize = m_varActive->get_dim(d)->size();
if (m_lVarActiveDims[d] == 0) {
m_lVarActiveDims[d] = lDimSize-1;
} else {
m_lVarActiveDims[d]--;
}
}

SetDisplayedDimensionValue(d, m_lVarActiveDims[d]);

// long lDimSize = m_varActive->get_dim(d)->size();
// if (m_lVarActiveDims[d] == 0) {
// m_lVarActiveDims[d] = lDimSize-1;
// } else {
// m_lVarActiveDims[d]--;
// }
//
// SetDisplayedDimensionValue(d, m_lVarActiveDims[d]);

// Increment dimension
} else if ((d >= ID_DIMUP) && (d < ID_DIMUP + 100)) {
eDimCommand = DIMCOMMAND_INCREMENT;
d -= ID_DIMUP;

long lDimSize = m_varActive->get_dim(d)->size();
if (m_lVarActiveDims[d] == lDimSize-1) {
m_lVarActiveDims[d] = 0;
} else {
m_lVarActiveDims[d]++;
}

SetDisplayedDimensionValue(d, m_lVarActiveDims[d]);
if ((std::string(m_varActive->get_dim(d)->name()) == "time") && (m_vecGlobalTime.size() > 0)) {
if (m_iCurrentGlobalTimeIndex == static_cast<int>(m_vecGlobalTime.size()) - 1) {
m_iCurrentGlobalTimeIndex = 0;
} else {
m_iCurrentGlobalTimeIndex++;
}

m_lVarActiveDims[d] = GetCurrentLocalTimeIndex();

} else {
long lDimSize = m_varActive->get_dim(d)->size();
if (m_lVarActiveDims[d] == lDimSize-1) {
m_lVarActiveDims[d] = 0;
} else {
m_lVarActiveDims[d]++;
}
}

SetDisplayedDimensionValue(d, m_lVarActiveDims[d]);

// long lDimSize = m_varActive->get_dim(d)->size();
// if (m_lVarActiveDims[d] == lDimSize-1) {
// m_lVarActiveDims[d] = 0;
// } else {
// m_lVarActiveDims[d]++;
// }
//
// SetDisplayedDimensionValue(d, m_lVarActiveDims[d]);

// Reset dimension
} else if ((d >= ID_DIMRESET) && (d < ID_DIMRESET + 100)) {
Expand Down
36 changes: 35 additions & 1 deletion src/wxNcVisFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@ class wxNcVisExportDialog;

////////////////////////////////////////////////////////////////////////////////

// Multi-file metadata for virtual time navigation
struct NcVisFileInfo {
wxString filename;
int timeCount = 0;
int latCount = 0;
int lonCount = 0;
};

struct NcVisTimeRef {
int fileIndex = -1;
int localTimeIndex = -1;
};

////////////////////////////////////////////////////////////////////////////////

/// <summary>
/// A class that manages the NcVis app frame.
/// </summary>
Expand Down Expand Up @@ -315,7 +330,14 @@ class wxNcVisFrame : public wxFrame {
/// </summary>
const std::string & GetVarActiveUnits() const {
return m_strVarActiveUnits;
}
}

/// <summary>
/// multi file helper functions
/// </summary>
int GetCurrentFileIndex() const;
int GetCurrentLocalTimeIndex() const;
void UpdateActiveVariableFromGlobalTime();

private:
/// <summary>
Expand Down Expand Up @@ -560,6 +582,11 @@ class wxNcVisFrame : public wxFrame {
/// </summary>
std::string m_strLatVarName;

/// <summary>
/// Name of the active variable.
/// </summary>
std::string m_strVarActiveName;

/// <summary>
/// A map of alternate longitude variables.
/// </summary>
Expand Down Expand Up @@ -676,6 +703,13 @@ class wxNcVisFrame : public wxFrame {
/// </summary>
VariableNameFileIxMap m_mapVarNames[10];

/// <summary>
/// Multi-file virtual time navigation
/// </summary>
std::vector<NcVisFileInfo> m_vecInputFileInfo;
std::vector<NcVisTimeRef> m_vecGlobalTime;
int m_iCurrentGlobalTimeIndex = 0;

private:
/// <summary>
/// ColorMap index.
Expand Down