Commit 5ec4ff32 authored by bonnell's avatar bonnell

Fix issue with query-over-time returning different results than manual...

Fix issue with query-over-time returning different results than manual change-time-state-then-query, eg for Boundary plots or when Isosurface operator applied.  Resolves #2821.

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@31009 18c085ea-50e0-402c-830e-de6fd14e8384
parent aa8433a6
......@@ -357,10 +357,15 @@ avtContourFilter::ModifyContract(avtContract_p in_contract)
// in case it can limit its reads to only the domains/elements that
// cross the isolevel.
//
avtIsolevelsSelection *sel = new avtIsolevelsSelection;
sel->SetVariable(varname);
sel->SetIsolevels(isoValues);
contract->GetDataRequest()->AddDataSelection(sel);
if (!isoValues.empty())
{
avtIsolevelsSelection *sel = new avtIsolevelsSelection;
sel->SetVariable(varname);
sel->SetIsolevels(isoValues);
contract->GetDataRequest()->AddDataSelection(sel);
}
if (it == NULL)
{
......@@ -1244,6 +1249,10 @@ avtContourFilter::UpdateDataObjectInfo(void)
// Hank Childs, Sun Jun 24 19:48:46 PDT 2001
// When there is an error, clear the isoValues if they are *not* empty.
//
// Kathleen Biagas, Wed May 24 17:15:11 PDT 2017
// Clear out isoValues when ContourMethod is Level. Ensures the values
// are correct for this min and max.
// ****************************************************************************
void
......@@ -1262,6 +1271,13 @@ avtContourFilter::SetIsoValues(double min, double max)
return;
}
if (atts.GetContourMethod() == ContourOpAttributes::Level)
{
// Make sure the iso values are in sync with this min/max
// by clearing them out and recreating.
isoValues.clear();
}
if (isoValues.empty())
{
CreateNIsoValues(min, max);
......
......@@ -104,11 +104,11 @@ avtTimeLoopFilter::~avtTimeLoopFilter()
// ****************************************************************************
// Method: avtTimeLoopFilter::Update
//
// Purpose:
// Purpose:
// Loops through specified timesteps: retrieves correct SILRestriction,
// creates appropriate avtDataRequest and avtContract
// for each timestep and calls avtFilter::Update to initiate a new
// pipeline execution for each timestep.
// for each timestep and calls avtFilter::Update to initiate a new
// pipeline execution for each timestep.
//
// Arguments:
// spec The pipeline specification.
......@@ -160,6 +160,9 @@ avtTimeLoopFilter::~avtTimeLoopFilter()
// Dave Pugmire, Tue Aug 13 11:55:59 EDT 2013
// Fix error in determing which slice is owned by a rank.
//
// Kathleen Biagas, Mon Jun 5 16:39:32 PDT 2017
// Call ResetAllExtents prior to changing timestates.
//
// ****************************************************************************
bool
......@@ -201,19 +204,21 @@ avtTimeLoopFilter::Update(avtContract_p spec)
bool shouldDoThisTimeSlice = true;
if (parallelizingOverTime)
shouldDoThisTimeSlice = RankOwnsTimeSlice(currentTime);
if (!shouldDoThisTimeSlice)
continue;
// Depending on the stride the last frame may be before
// the end.
if (currentTime > endTime)
currentTime = endTime;
if (!NeedCurrentTimeSlice())
continue;
debug4 << "Time loop filter updating with time slice #"
avtFilter::ResetAllExtents();
debug4 << "Time loop filter updating with time slice #"
<< currentTime << endl;
avtSIL *sil = GetInput()->GetOriginatingSource()->GetSIL(currentTime);
......@@ -222,7 +227,7 @@ avtTimeLoopFilter::Update(avtContract_p spec)
debug4 << "Could not read the SIL at state " << currentTime << endl;
currentSILR = orig_SILR;
}
else
else
{
currentSILR = new avtSILRestriction(sil);
currentSILR->SetTopSet(orig_SILR->GetTopSet());
......@@ -235,7 +240,7 @@ avtTimeLoopFilter::Update(avtContract_p spec)
avtDataRequest_p newDS = new avtDataRequest(orig_DS, currentSILR);
newDS->SetTimestep(currentTime);
avtContract_p contract =
avtContract_p contract =
new avtContract(newDS, spec->GetPipelineIndex());
if (parallelizingOverTime)
{
......@@ -244,23 +249,25 @@ avtTimeLoopFilter::Update(avtContract_p spec)
}
else
contract->NoStreaming();
modified |= avtFilter::Update(contract);
if (ExecutionSuccessful())
{
validTimes.push_back(currentTime);
}
else
else
{
skippedTimes.push_back(currentTime);
}
avtCallback::ResetTimeout(5*60);
}
}
visitTimer->StopTimer(t0, "avtTimeLoopFilter Read time slices");
avtFilter::ResetAllExtents();
int t1 = visitTimer->StartTimer();
//
// It is possible that execution of some timesteps may have resulted
......@@ -281,8 +288,8 @@ avtTimeLoopFilter::Update(avtContract_p spec)
//
GetInput()->Update(spec);
visitTimer->StopTimer(t1, "avtTimeLoopFilter CreateFinalOutput");
//
//
// Set the time information to be the time from the input, not from the
// last execution. This is particularly important when we parallelize
// over time, since each MPI task will have a different cycle/time and then
......
......@@ -941,7 +941,7 @@ avtFilter::GetDataExtents(double *outexts, const char *varname)
avtExtents *e = NULL;
TRY
{
e = GetInput()->GetInfo().GetAttributes().GetOriginalDataExtents(varname);
e = atts.GetOriginalDataExtents(varname);
}
CATCH(ImproperUseException)
{
......@@ -1851,3 +1851,22 @@ avtFilter::CanCacheConnectivityItem(void)
}
// ****************************************************************************
// Method: avtFilter::ResetAllExtents
//
// Purpose:
// Walks up a pipeline resetting extents.
//
// Programmer: Kathleen Biagas
// Creation: June 5, 2017
//
// Modifications:
//
// ****************************************************************************
void
avtFilter::ResetAllExtents()
{
avtDataObjectSink::ResetAllExtents();
}
......@@ -129,6 +129,9 @@ class avtWebpage;
// filter facades can correctly affect the output data object info.
// Work partially supported by DOE Grant SC0007548.
//
// Kathleen Biagas, Mon Jun 5 16:46:14 PDT 2017
// Added ResetAllExtents.
//
// ****************************************************************************
class PIPELINE_API avtFilter
......@@ -147,6 +150,7 @@ class PIPELINE_API avtFilter
{ return false; };
virtual bool Update(avtContract_p);
virtual void ResetAllExtents(void);
virtual avtOriginatingSource *GetOriginatingSource(void);
virtual avtQueryableSource *GetQueryableSource(void);
......
......@@ -5128,6 +5128,9 @@ avtDataAttributes::GetFilterMetaData(stringVector &filterNames,
// Brad Whitlock, Wed Mar 19 14:15:56 PDT 2014
// Print the plot information to the debug dump.
//
// Kathleen Biagas, Thu Jun 1 08:47:46 PDT 2017
// Print OriginalDataExtents.
//
// ****************************************************************************
static const char *
......@@ -5385,6 +5388,8 @@ avtDataAttributes::DebugDump(avtWebpage *webpage)
YesOrNo(variables[i]->treatAsASCII));
SNPRINTF(str, 4096, "%d", variables[i]->useForAxis);
webpage->AddTableEntry3(NULL, "Use for axis", str);
ExtentsToString(variables[i]->originalData, str, 4096);
webpage->AddTableEntry3(NULL, "Original data extents", str);
ExtentsToString(variables[i]->thisProcsOriginalData, str, 4096);
webpage->AddTableEntry3(NULL, "ThisProcs original data extents", str);
ExtentsToString(variables[i]->desiredData, str, 4096);
......@@ -5424,6 +5429,40 @@ avtDataAttributes::DebugDump(avtWebpage *webpage)
webpage->EndTable();
}
// ****************************************************************************
// Method: avtDataAttributes::ResetAllExtents
//
// Purpose:
// Clears out all extent information.
//
// Programmer: Kathleen Biagas
// Creation: June 1, 2017
//
// Modifications:
//
// ****************************************************************************
void
avtDataAttributes::ResetAllExtents()
{
originalSpatial->Clear();
thisProcsOriginalSpatial->Clear();
desiredSpatial->Clear();
actualSpatial->Clear();
thisProcsActualSpatial->Clear();
for (size_t i = 0; i < variables.size(); ++i)
{
variables[i]->originalData->Clear();
variables[i]->thisProcsOriginalData->Clear();
variables[i]->desiredData->Clear();
variables[i]->actualData->Clear();
variables[i]->thisProcsActualData->Clear();
}
}
// ****************************************************************************
// Method: avtDataAttributes::VarInfo::VarInfo
//
......
......@@ -274,6 +274,9 @@ class avtWebpage;
// Added logic to support presentGhostZoneTypes, which allows us to
// differentiate between ghost zones for boundaries & nesting.
//
// Kathleen Biagas, Thu Jun 1 08:47:13 PDT 2017
// Added ResetAllExtents.
//
// ****************************************************************************
class PIPELINE_API avtDataAttributes
......@@ -589,6 +592,8 @@ class PIPELINE_API avtDataAttributes
bool GetConstructMultipleCurves() const
{ return constructMultipleCurves; }
void ResetAllExtents();
protected:
int spatialDimension;
int topologicalDimension;
......
......@@ -462,3 +462,25 @@ avtDataObject::DebugDump(avtWebpage *webpage, const char *prefix)
}
// ****************************************************************************
// Method: avtDataObject::ResetAllExtents
//
// Purpose:
// Propagates a ResetAllExtents up the pipeline.
//
// Programmer: Kathleen Biagas
// Creation: June 5, 2017
//
// Modifications:
//
// ****************************************************************************
void
avtDataObject::ResetAllExtents()
{
info.GetAttributes().ResetAllExtents();
if (source != NULL)
{
source->ResetAllExtents();
}
}
......@@ -93,6 +93,9 @@ class avtWebpage;
// Burlen Loring, Sun Sep 6 14:58:03 PDT 2015
// Changed the return type of GetNumberOfCells to long long
//
// Kathleen Biagas, Mon Jun 5 16:21:30 PDT 2017
// Add ResetAllExtents.
//
// ****************************************************************************
class PIPELINE_API avtDataObject
......@@ -105,6 +108,7 @@ class PIPELINE_API avtDataObject
avtQueryableSource *GetQueryableSource(void);
bool Update(avtContract_p);
void ResetAllExtents(void);
void SetSource(avtDataObjectSource *);
avtDataObjectSource *GetSource(void) { return source; };
......
......@@ -158,3 +158,22 @@ avtDataObjectSink::UpdateInput(avtContract_p spec)
}
// ****************************************************************************
// Method: avtDataObjectSink::ResetAllExtents
//
// Purpose:
// Resets the extents.
//
// Programmer: Kathleen Biagas
// Creation: June 5, 2017
//
// ****************************************************************************
void
avtDataObjectSink::ResetAllExtents()
{
avtDataObject_p input = GetInput();
if (*input != NULL)
input->ResetAllExtents();
}
......@@ -79,6 +79,9 @@
// Tom Fogal, Tue Jun 23 19:54:03 MDT 2009
// Added a const version of GetInput.
//
// Kathleen Biagas, Mon Jun 5 16:27:45 PDT 2017
// Added ResetAllExtents.
//
// ****************************************************************************
class PIPELINE_API avtDataObjectSink
......@@ -97,6 +100,7 @@ class PIPELINE_API avtDataObjectSink
virtual void SetTypedInput(avtDataObject_p) = 0;
virtual void ChangedInput(void);
virtual bool UpdateInput(avtContract_p);
virtual void ResetAllExtents(void);
private:
// These methods are defined to prevent accidental use of bitwise copy
......
......@@ -92,6 +92,9 @@ class avtQueryableSource;
// Hank Childs, Mon Feb 9 15:09:29 PST 2009
// Added method CreateNamedSelection.
//
// Kathleen Biagas, Mon Jun 5 16:29:43 PDT 2017
// Added ResetAllExtents.
//
// ****************************************************************************
class PIPELINE_API avtDataObjectSource
......@@ -101,6 +104,7 @@ class PIPELINE_API avtDataObjectSource
virtual ~avtDataObjectSource();
virtual bool Update(avtContract_p) = 0;
virtual void ResetAllExtents(void) = 0;
virtual avtOriginatingSource *GetOriginatingSource(void) = 0;
virtual avtQueryableSource *GetQueryableSource(void) = 0;
......
......@@ -251,10 +251,10 @@ avtOriginatingSource::Update(avtContract_p contract)
GetOutput()->GetInfo().GetValidity().Reset();
int t0 = visitTimer->StartTimer();
avtDataRequest_p data = BalanceLoad(contract);
visitTimer->StopTimer(t0, "Calling BalanceLoad in avtTermSrc::Update");
visitTimer->StopTimer(t0, "Calling BalanceLoad in avtOrigSrc::Update");
int t1 = visitTimer->StartTimer();
bool rv = FetchData(data);
visitTimer->StopTimer(t1, "Calling avtTermSrc::FetchData");
visitTimer->StopTimer(t1, "Calling avtOrigSrc::FetchData");
return rv;
}
......@@ -882,3 +882,22 @@ avtOriginatingSource::FetchArbitraryRefPtr(const char *name, int domain,
}
// ****************************************************************************
// Method: avtOriginatingSource::ResetAllExtents
//
// Purpose:
// This is the termination of a pipeline, nothing to do here.
//
// Programmer: Kathleen Biagas
// Creation: June 5, 2017
//
// Modifications:
//
// ****************************************************************************
void
avtOriginatingSource::ResetAllExtents()
{
; // nothing to do here
}
......@@ -132,6 +132,9 @@ typedef void (*InitializeProgressCallback)(void *, int);
// Hank Childs, Tue Dec 11 14:39:58 PST 2012
// Add method for getting last data selections.
//
// Kathleen Biagas, Mon Jun 5 16:41:17 PDT 2017
// Added ResetAllExtents.
//
// ****************************************************************************
class PIPELINE_API avtOriginatingSource : virtual public avtQueryableSource
......@@ -174,6 +177,7 @@ class PIPELINE_API avtOriginatingSource : virtual public avtQueryableSource
void_ref_ptr);
virtual bool Update(avtContract_p);
virtual void ResetAllExtents(void);
virtual bool CanDoStreaming(avtContract_p) {return true;}
static void SetLoadBalancer(LoadBalanceFunction,void *);
......
......@@ -420,13 +420,28 @@ avtBoundaryPlot::NeedZBufferToCompositeEvenIn2D(void)
// Creation: June 12, 2003
//
// Modifications:
// Kathleen Biagas, Tue Jun 6 16:14:47 PDT 2017
// Moved smooth and subset filters from 'ApplyReneringTransformation',
// so that Query over time will have the correct inputs.
//
// ****************************************************************************
avtDataObject_p
avtBoundaryPlot::ApplyOperators(avtDataObject_p input)
{
return input;
// Set the amount of smoothing required
smooth->SetSmoothingLevel(atts.GetSmoothingLevel());
if (atts.GetSmoothingLevel() > 0)
{
smooth->SetInput(input);
sub->SetInput(smooth->GetOutput());
}
else
{
sub->SetInput(input);
}
return sub->GetOutput();
}
// ****************************************************************************
......@@ -445,33 +460,23 @@ avtBoundaryPlot::ApplyOperators(avtDataObject_p input)
// Creation: June 12, 2003
//
// Modifications:
// Kathleen Biagas, Tue Jun 6 16:14:47 PDT 2017
// Move smooth and subset filters into 'ApplyOperators', so that
// Query over time will have the correct inputs.
//
// ****************************************************************************
avtDataObject_p
avtBoundaryPlot::ApplyRenderingTransformation(avtDataObject_p input)
{
// Set the amount of smoothing required
smooth->SetSmoothingLevel(atts.GetSmoothingLevel());
if (atts.GetSmoothingLevel() > 0)
{
smooth->SetInput(input);
sub->SetInput(smooth->GetOutput());
}
else
{
sub->SetInput(input);
}
if (atts.GetWireframe())
{
wf->SetInput(sub->GetOutput());
wf->SetInput(input);
gz->SetInput(wf->GetOutput());
}
else
{
gz->SetInput(sub->GetOutput());
gz->SetInput(input);
}
return gz->GetOutput();
......
......@@ -27,6 +27,7 @@ enhancements and bug-fixes that were added to this release.</p>
<li>The Pick window wouldn't update the number of tabs displayed if picks were performed after changing number of tabs, but before 'Apply' was clicked.</li>
<li>Fixed reading of numpy files on Windows.</li>
<li>Fixed the issue with expressions involving multiple matvf functions using the same material name.</li>
<li>Fixed query-over-time bug where in certain instances it would yield different results than a manual change-time-state-then-query. In particular, for Boundary plots or when an Isosurface operator were used.</li>
</ul>
<a name="Enhancements"></a>
......
......@@ -1032,11 +1032,16 @@ ViewerQueryManager::DisableTool(ViewerWindow *oWin, avtToolInterface &ti)
// Kathleen Biagas, Tue Mar 25 07:56:00 PDT 2014
// Check if 'vars' is a single string.
//
// Kathleen Biagas, Thu May 25 15:08:23 PDT 2017
// Copy in the input params, need to add 'use_actual_data' whether it is
// provided or not.
//
// ****************************************************************************
void
ViewerQueryManager::DatabaseQuery(const MapNode &queryParams)
ViewerQueryManager::DatabaseQuery(const MapNode &in_queryParams)
{
MapNode queryParams(in_queryParams);
string qName = queryParams.GetEntry("query_name")->AsString();
int doTimeQuery = 0;
if (queryParams.HasNumericEntry("do_time"))
......@@ -1119,9 +1124,22 @@ ViewerQueryManager::DatabaseQuery(const MapNode &queryParams)
}
}
int useActualData = 0;
int useActualData = 1;
if (queryParams.HasNumericEntry("use_actual_data"))
{
useActualData = queryParams.GetEntry("use_actual_data")->ToInt();
}
else
{
int winType = GetViewerState()->GetQueryList()->GetWindowType(qName);
if (winType == QueryList::ActualData || winType == QueryList::ActualDataVars)
useActualData = 0; // the default for actual/original supported queries
else
useActualData = 1; // the default for actual-data-only queries
}
// ensure we are all on the same page
queryParams["use_actual_data"] = useActualData;
if (qName == "SpatialExtents")
{
......
......@@ -120,6 +120,9 @@ PyMapNode_Wrap(const MapNode &node)
// Kathleen Biagas, Mon Mar 24 17:00:11 PDT 2014
// Parse Dict.
//
// Kathleen Biagas, Mon Jun 5 17:25:15 PDT 2017
// Allow for PyLong.
//
// ****************************************************************************
bool
......@@ -166,7 +169,7 @@ PyDict_To_MapNode(PyObject *obj, MapNode &mn)
}
mn[mkey] = mval;
}
else if (PyInt_Check(item))
else if (PyLong_Check(item) || PyInt_Check(item))
{
int ni = 1, nd = 0, no = 0;
for (Py_ssize_t i = 1; i < PySequence_Size(value); ++i)
......@@ -174,6 +177,8 @@ PyDict_To_MapNode(PyObject *obj, MapNode &mn)
item = PySequence_GetItem(value, i);
if (PyFloat_Check(item))
nd++;
else if (PyLong_Check(item))
ni++;
else if (PyInt_Check(item))
ni++;
else
......@@ -194,6 +199,8 @@ PyDict_To_MapNode(PyObject *obj, MapNode &mn)
item = PySequence_GetItem(value, i);
if (PyFloat_Check(item))
mval.push_back(PyFloat_AS_DOUBLE(item));
else if (PyLong_Check(item))
mval.push_back((double)PyLong_AsLong(item));
else if (PyInt_Check(item))
mval.push_back((double)PyInt_AS_LONG(item));
}
......@@ -205,7 +212,10 @@ PyDict_To_MapNode(PyObject *obj, MapNode &mn)
for (Py_ssize_t i = 0; i < PySequence_Size(value); ++i)
{
item = PySequence_GetItem(value, i);
mval.push_back(PyInt_AS_LONG(item));
if (PyLong_Check(item))
mval.push_back((double)PyLong_AsLong(item));
else if (PyInt_Check(item))
mval.push_back((double)PyInt_AS_LONG(item));
}
mn[mkey] = mval;
}
......@@ -239,6 +249,10 @@ PyDict_To_MapNode(PyObject *obj, MapNode &mn)
{
mn[mkey] = (double) PyFloat_AS_DOUBLE(value);
}
else if (PyLong_Check(value))
{
mn[mkey] = (int) PyLong_AsLong(value);
}
else if (PyInt_Check(value))
{
mn[mkey] = (int) PyInt_AS_LONG(value);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment