void
avtTimeLoopCollectorFilter::CreateFinalOutput()
{
    avtDataTree_p output = ExecuteAllTimesteps(trees);
    SetOutputDataTree(output);
    trees.clear();
}
void
avtSIMODataTreeIterator::Execute(void)
{
    //
    // This will walk through the data domains in a data tree.
    //
    avtDataTree_p tree    = GetInputDataTree();
    avtDataTree_p newTree;
    if (*tree != NULL)
    {
        totalNodes = tree->GetNumberOfLeaves();
        newTree = Execute(tree);
    }
    else
    {
        // This can happen when a filter serves up an empty data tree.
        // It can also happen when we claim memory from intermediate
        // data objects and then go back to execute them.
        debug1 << "Unusual situation: NULL input tree to SIMO iterator.  Likely "
               << "that an exception occurred previously." << endl;
    }

    if (*newTree == NULL)
    {
        //
        // Lots of code assumes that the root tree is non-NULL.  Put a dummy
        // tree in its place.
        //
        newTree = new avtDataTree();
    }

    SetOutputDataTree(newTree);
}
Пример #3
0
void
avtModelBasedClusteringFilter::Execute()
{
    std::string vlibdir = GetVisItLibraryDirectory() + VISIT_SLASH_CHAR + "r_support";
    std::string vlibrdir  = vlibdir  + VISIT_SLASH_CHAR + "Rscripts" + VISIT_SLASH_CHAR;
    
    avtRModelBasedClusteringFilter *f = new avtRModelBasedClusteringFilter;
    f->codeDir = vlibrdir;
    f->atts = atts;

    f->SetInput(GetInput());
    
    avtContract_p spec = GetInput()->GetOriginatingSource()->GetGeneralContract();
    avtDataObject_p dob = f->GetOutput();

    dob->Update(spec);
    avtDataTree_p tree = f->GetTypedOutput()->GetDataTree();

    //Set the output variable properly.
    int nleaves;
    vtkDataSet **leaves = tree->GetAllLeaves(nleaves);
    for (int i = 0; i < nleaves; i++)
    {
        if (leaves[i]->GetPointData()->GetScalars())
            leaves[i]->GetPointData()->GetScalars()->SetName(pipelineVariable);
        else if (leaves[i]->GetCellData()->GetScalars())
            leaves[i]->GetCellData()->GetScalars()->SetName(pipelineVariable);
    }
    delete [] leaves;

    SetOutputDataTree(tree);
    delete f;
}
void
avtTimeIteratorDataTreeIteratorExpression::FinalizeOutput(void)
{
    avtDataTree_p tree = GetInputDataTree();
    arrayIndex = 0;
    avtDataTree_p rv = ConstructOutput(tree);
    SetOutputDataTree(rv);
}
void
avtVTKDatasetToDatasetFilter::Execute(avtDomainList *dl)
{
    avtDataTree_p tree = source->FetchDomains(dl);

    //
    // Pass the output of the source on as the output of this filter.  
    // Since this is an AVT filter, there are no two filters owning 
    // the same output (there are in VTK).
    //
    SetOutputDataTree(tree);
}
Пример #6
0
void
avtLagrangianFilter::CreateIntegralCurveOutput(std::vector<avtIntegralCurve *> &ics)
{

    avtLagrangianIC *ic = (avtLagrangianIC*)ics[0];
    int nSamps = (int)ic->GetNumberOfSamples();

    vtkRectilinearGrid *rg = vtkVisItUtility::Create1DRGrid(nSamps,VTK_FLOAT);
    vtkFloatArray    *vals = vtkFloatArray::New();
    vals->SetNumberOfComponents(1);
    vals->SetNumberOfTuples(nSamps);
    vals->SetName("curve");

    rg->GetPointData()->SetScalars(vals);
    vtkFloatArray *xc = vtkFloatArray::SafeDownCast(rg->GetXCoordinates());

    avtStateRecorderIntegralCurve::Sample samp;

    float xi = 0, yi = 0;
    for (int j = 0; j < nSamps; j++)
    {
        samp = ic->GetSample(j);

        if (atts.GetXAxisSample() == LagrangianAttributes::Step)
            xi = j;
        else if (atts.GetXAxisSample() == LagrangianAttributes::Time)
            xi = samp.time;
        else if (atts.GetXAxisSample() == LagrangianAttributes::ArcLength)
            xi = samp.arclength;

        if (atts.GetYAxisSample() == LagrangianAttributes::Step)
            yi = j;
        else if (atts.GetYAxisSample() == LagrangianAttributes::Time)
            yi = samp.time;
        else if (atts.GetYAxisSample() == LagrangianAttributes::ArcLength)
            yi = samp.arclength;
        else if (atts.GetYAxisSample() == LagrangianAttributes::Speed)
            yi = samp.velocity.length();
        else if (atts.GetYAxisSample() == LagrangianAttributes::Vorticity)
            yi = samp.vorticity;
        else if (atts.GetYAxisSample() == LagrangianAttributes::Variable)
            yi = samp.variable;

        xc->SetValue(j, xi);
        vals->SetValue(j, yi);
    }

    avtDataTree_p rv = new avtDataTree(rg, -1);

    SetOutputDataTree(rv);
}
Пример #7
0
bool
avtLCSFilter::NativeMeshIterativeCalc(std::vector<avtIntegralCurve*> &ics)
{
    int offset = 0;

    if( *fsle_dt == NULL )
    {
      fsle_dt = CreateIterativeCalcDataTree(GetInputDataTree());
      
      if (GetInput()->GetInfo().GetAttributes().DataIsReplicatedOnAllProcessors())
        if (PAR_Rank() != 0)
          fsle_dt = new avtDataTree();

      SetOutputDataTree(fsle_dt);
    }

    return MultiBlockIterativeCalc(fsle_dt, ics, offset);
}
void
avtStreamlinePolyDataFilter::CreateIntegralCurveOutput(std::vector<avtIntegralCurve *> &ics)
{
    int numICs = ics.size(), numPts = 0;
    int numEarlyTerminators = 0;
    int numStiff = 0;
    int numCritPts = 0;

    if (DebugStream::Level5())
    {
        debug5 << "::CreateIntegralCurveOutput " << ics.size() << endl;
    }
    //See how many pts, ics we have so we can preallocate everything.
    for (int i = 0; i < numICs; i++)
    {
        avtStreamlineIC *ic = dynamic_cast<avtStreamlineIC*>(ics[i]);
        size_t numSamps = (ic ? ic->GetNumberOfSamples() : 0);
        if (numSamps > 1)
            numPts += numSamps;

        if (ic->CurrentVelocity().length() <= criticalPointThreshold)
          numCritPts++;

        if (ic->TerminatedBecauseOfMaxSteps())
          numEarlyTerminators++;

        if (ic->EncounteredNumericalProblems())
            numStiff++;
    }
    if ((doDistance || doTime) && issueWarningForMaxStepsTermination)
    {
        SumIntAcrossAllProcessors(numEarlyTerminators);
        if (numEarlyTerminators > 0)
        {
            char str[1024];
            SNPRINTF(str, 1024, 
               "%d of your streamlines terminated because they "
               "reached the maximum number of steps.  This may be indicative of your "
               "time or distance criteria being too large or of other attributes being "
               "set incorrectly (example: your step size is too small).  If you are "
               "confident in your settings and want the particles to advect farther, "
               "you should increase the maximum number of steps.  If you want to disable "
               "this message, you can do this under the Advaced tab of the streamline plot."
               "  Note that this message does not mean that an error has occurred; it simply "
               "means that VisIt stopped advecting particles because it reached the maximum "
               "number of steps. (That said, this case happens most often when other attributes "
               "are set incorrectly.)", numEarlyTerminators);
            avtCallback::IssueWarning(str);
        }
    }
    if (issueWarningForCriticalPoints)
    {
        SumIntAcrossAllProcessors(numCritPts);
        if (numCritPts > 0)
        {
            char str[1024];
            SNPRINTF(str, 1024, 
               "%d of your streamlines circled round and round a critical point (a zero"
               " velocity location).  Normally, VisIt is able to advect the particle "
               "to the critical point location and terminate.  However, VisIt was not able "
               "to do this for these particles due to numerical issues.  In all likelihood, "
               "additional steps will _not_ help this problem and only cause execution to "
               "take longer.  If you want to disable this message, you can do this under "
               "the Advanced tab of the streamline plot.", numCritPts);
            avtCallback::IssueWarning(str);
        }
    }
    if (issueWarningForStiffness)
    {
        SumIntAcrossAllProcessors(numStiff);
        if (numStiff > 0)
        {
            char str[1024];
            SNPRINTF(str, 1024, 
               "%d of your streamlines were unable to advect because of \"stiffness\".  "
               "When one component of a velocity field varies quickly and another stays "
               "relatively constant, then it is not possible to choose step sizes that "
               "remain within tolerances.  This condition is referred to as stiffness and "
               "VisIt stops advecting in this case.  If you want to disable this message, "
               "you can do this under the Advanced tab of the streamline plot.", numStiff);
            avtCallback::IssueWarning(str);
        }
    }
    if (numICs == 0)
        return;

    //Make a polydata.
    vtkPoints     *points   = vtkPoints::New();
    vtkCellArray  *lines    = vtkCellArray::New();
    vtkFloatArray *scalars  = vtkFloatArray::New();
    vtkFloatArray *params   = vtkFloatArray::New();
    vtkFloatArray *tangents = vtkFloatArray::New();
    vtkFloatArray *scaleTubeRad = NULL;
    vtkFloatArray *thetas   = NULL;
    vtkFloatArray *opacity  = NULL;

    lines->Allocate(numICs);
    points->Allocate(numPts);
    scalars->Allocate(numPts);
    params->Allocate(numPts);
    tangents->SetNumberOfComponents(3);
    tangents->SetNumberOfTuples(numPts);
    
    vtkPolyData *pd = vtkPolyData::New();
    pd->SetPoints(points);
    pd->SetLines(lines);
    scalars->SetName(colorvarArrayName.c_str());
    params->SetName(paramArrayName.c_str());
    tangents->SetName(tangentsArrayName.c_str());

    pd->GetPointData()->SetScalars(scalars);
    pd->GetPointData()->AddArray(scalars);
    pd->GetPointData()->AddArray(params);
    pd->GetPointData()->AddArray(tangents);

    if (displayMethod == PICS_DISPLAY_RIBBONS)
    {
        thetas = vtkFloatArray::New();
        thetas->Allocate(numPts);
        thetas->SetName(thetaArrayName.c_str());
        pd->GetPointData()->AddArray(thetas);
    }
    if (!opacityVariable.empty())
    {
        opacity = vtkFloatArray::New();
        opacity->Allocate(numPts);
        opacity->SetName(opacityArrayName.c_str());
        pd->GetPointData()->AddArray(opacity);
    }
    if (!scaleTubeRadiusVariable.empty())
    {
        scaleTubeRad = vtkFloatArray::New();
        scaleTubeRad->Allocate(numPts);
        scaleTubeRad->SetName(scaleRadiusArrayName.c_str());
        pd->GetPointData()->AddArray(scaleTubeRad);
    }

    double correlationDistMinDistToUse = correlationDistanceMinDist;
    double correlationDistAngTolToUse = 0.0;
    if (coloringMethod == PICS_CORRELATION_DISTANCE)
    {
        if (correlationDistanceDoBBox)
            correlationDistMinDistToUse *= GetLengthScale();
        correlationDistAngTolToUse = cos(correlationDistanceAngTol *M_PI/180.0);
    }

    if ( !scaleTubeRadiusVariable.empty())
        ProcessVaryTubeRadiusByScalar(ics);

    vtkIdType pIdx = 0;
    for (int i = 0; i < numICs; i++)
    {
        avtStateRecorderIntegralCurve *ic = dynamic_cast<avtStateRecorderIntegralCurve*>(ics[i]);
        size_t numSamps = (ic ? ic->GetNumberOfSamples() : 0);
        if (numSamps <= 1)
            continue;
        
        vtkPolyLine *line = vtkPolyLine::New();
        line->GetPointIds()->SetNumberOfIds(numSamps);

        float theta = 0.0, prevT = 0.0;

        for (size_t j = 0; j < numSamps; j++)
        {
            avtStateRecorderIntegralCurve::Sample s = ic->GetSample(j);
            line->GetPointIds()->SetId(j, pIdx);

            if( coordinateSystem == 0 )
            {
              if( phiScalingFlag && phiScaling != 0.0 )
                points->InsertPoint(pIdx, s.position.x, s.position.y / phiScaling, s.position.z);
              else
                points->InsertPoint(pIdx, s.position.x, s.position.y, s.position.z);
            }
            else if( coordinateSystem == 1 )
              points->InsertPoint(pIdx, 
                                  s.position.x*cos(s.position.y),
                                  s.position.x*sin(s.position.y),
                                  s.position.z);
            else if( coordinateSystem == 2 )
            {
              if( phiScalingFlag && phiScaling != 0.0 )
                points->InsertPoint(pIdx, 
                                    sqrt(s.position.x*s.position.x+
                                         s.position.y*s.position.y),
                                    (double) (j) / phiScaling,
                                    s.position.z);
              else
                points->InsertPoint(pIdx,
                                    sqrt(s.position.x*s.position.x+
                                         s.position.y*s.position.y),
                                    atan2( s.position.y, s.position.x ),
                                    s.position.z);
            }

            float speed = s.velocity.length();
            if (speed > 0)
                s.velocity *= 1.0f/speed;
            tangents->InsertTuple3(pIdx, s.velocity.x, s.velocity.y, s.velocity.z);

            // color scalars
            switch (coloringMethod)
            {
              case PICS_COLOR_TIME:
                scalars->InsertTuple1(pIdx, s.time);
                break;
              case PICS_COLOR_SPEED:
                scalars->InsertTuple1(pIdx, speed);
                break;
              case PICS_COLOR_VORTICITY:
                scalars->InsertTuple1(pIdx, s.vorticity);
                break;
              case PICS_COLOR_ARCLENGTH:
                scalars->InsertTuple1(pIdx, s.arclength);
                break;
              case PICS_COLOR_NUM_DOM_VISIT:
                scalars->InsertTuple1(pIdx, s.numDomainsVisited);
                break;
              case PICS_COLOR_VARIABLE:
                scalars->InsertTuple1(pIdx, s.secondarys[0]);
                break;
              case PICS_COLOR_ID:
                scalars->InsertTuple1(pIdx, ic->id);
                break;
              case PICS_COLOR_SOLID:
                scalars->InsertTuple1(pIdx, 0.0f);
                break;
              case PICS_CORRELATION_DISTANCE:
                scalars->InsertTuple1(pIdx, ComputeCorrelationDistance(j, ic, correlationDistAngTolToUse, correlationDistMinDistToUse));
                break;
            }

            // parameter scalars
            switch (referenceTypeForDisplay)
            {
              case 0: // Distance
                params->InsertTuple1(pIdx, s.arclength);
                break;
              case 1: // Time
                params->InsertTuple1(pIdx, s.time);
                break;
              case 2: // Steps
                params->InsertTuple1(pIdx, j);
                break;
            }
            
            // opacity/theta scalars
            if (opacity)
                opacity->InsertTuple1(pIdx, s.secondarys[1]);
            if (thetas)
            {
                float scaledVort = s.vorticity * (prevT-s.time);
                theta += scaledVort;
                thetas->InsertTuple1(pIdx, theta);
                prevT = s.time;
            }
            if (scaleTubeRad)
                scaleTubeRad->InsertTuple1(pIdx, s.secondarys[2]);
            
            pIdx++;
        }

        lines->InsertNextCell(line);
        line->Delete();
    }
    
    points->Delete();
    lines->Delete();
    scalars->Delete();
    params->Delete();
    tangents->Delete();
    if (thetas)
        thetas->Delete();
    if (opacity)
        opacity->Delete();

    vtkCleanPolyData *clean = vtkCleanPolyData::New();
    clean->ConvertLinesToPointsOff();
    clean->ConvertPolysToLinesOff();
    clean->ConvertStripsToPolysOff();
    clean->PointMergingOn();
    clean->SetInputData(pd);
    clean->Update();
    pd->Delete();

    vtkPolyData *cleanPD = clean->GetOutput();

    avtDataTree *dt = new avtDataTree(cleanPD, 0);
    SetOutputDataTree(dt);

    clean->Delete();

/*
    if (1)
    {
        char f[51];
        sprintf(f, "streamlines_%03d.txt", PAR_Rank());
        FILE *fp = fopen(f, "w");
        for (int i = 0; i < numICs; i++)
        {
            avtStateRecorderIntegralCurve *ic = dynamic_cast<avtStateRecorderIntegralCurve*>(ics[i]);
            size_t numSamps = (ic ? ic->GetNumberOfSamples() : 0);
            if (numSamps == 0)
                continue;

            fprintf(fp, "%d\n", (int)numSamps);
            for (int j = 0; j < numSamps; j++)
            {
                avtStateRecorderIntegralCurve::Sample s = ic->GetSample(j);
                fprintf(fp, "%lf %lf %lf %lf %lf\n", s.position.x, s.position.y, s.position.z, s.time, s.scalar0);
            
            }
        }
        fflush(fp);
        fclose(fp);
    }
 */
}
void
avtQueryOverTimeFilter::CreateFinalOutput()
{
    if (ParallelizingOverTime())
    {
        double *totalQRes;
        int    *qResMsgs;
        CollectDoubleArraysOnRootProc(totalQRes, qResMsgs,
                                      &(qRes[0]), qRes.size());
        double *totalTimes;
        int    *timesMsgs;
        CollectDoubleArraysOnRootProc(totalTimes, timesMsgs,
                                      &(times[0]), times.size());
        if (PAR_Rank() == 0)
        {
            int i;
            int nResults = 0;
            int maxIterations = 0;
            for (i = 0 ; i < PAR_Size() ; i++)
            {
                nResults += timesMsgs[i];
                maxIterations = (timesMsgs[i] > maxIterations ? timesMsgs[i]
                                 : maxIterations);
            }

            std::vector<double> finalQRes(nResults, 0.);
            std::vector<double> finalTimes(nResults, 0.);
            int index = 0;
            for (int j = 0 ; j < maxIterations ; j++)
            {
                int loc = 0;
                for (i = 0 ; i < PAR_Size() ; i++)
                {
                    if (timesMsgs[i] > j)
                    {
                        finalQRes[index]  = totalQRes[loc+j];
                        finalTimes[index] = totalTimes[loc+j];
                        index++;
                    }
                    loc += timesMsgs[i];
                }
            }
            qRes = finalQRes;
            times = finalTimes;
            delete [] totalQRes;
            delete [] qResMsgs;
            delete [] totalTimes;
            delete [] timesMsgs;
        }
        else
        {
            SetOutputDataTree(new avtDataTree());
            finalOutputCreated = true;
            return;
        }
    }

    if (qRes.size() == 0)
    {
        debug4 << "Query failed at all timesteps" << endl;
        avtCallback::IssueWarning("Query failed at all timesteps");
        avtDataTree_p dummy = new avtDataTree();
        SetOutputDataTree(dummy);
        return;
    }
    if (useTimeForXAxis && qRes.size()/nResultsToStore != times.size())
    {
        debug4 << "QueryOverTime ERROR, number of results ("
               << qRes.size() << ") does not equal number "
               << "of timesteps (" << times.size() << ")." << endl;
        avtCallback::IssueWarning(
            "\nQueryOverTime error, number of results does not equal "
            "number of timestates.  Curve being created may be missing "
            "some values.  Please contact a VisIt developer.");
    }
    else if (nResultsToStore > 1 && qRes.size() % nResultsToStore != 0)
    {
        debug4 << "QueryOverTime ERROR, number of results ("
               << qRes.size() << ") is not a multiple of " << nResultsToStore
               << "and therefore cannot generate x,y pairs." << endl;
        avtCallback::IssueWarning(
            "\nQueryOverTime error, number of results is incorrect.  "
            "Curve being created may be missing some values.  "
            "Please contact a VisIt developer.");
    }
    if (skippedTimes.size() != 0)
    {
        std::ostringstream osm;
        osm << "\nQueryOverTime (" << atts.GetQueryAtts().GetName().c_str()
            << ") experienced\n"
            << "problems with the following timesteps and \n"
            << "skipped them while generating the curve:\n   ";

        for (int j = 0; j < skippedTimes.size(); j++)
            osm << skippedTimes[j] << " ";
        osm << "\nLast message received: " << errorMessage.c_str() << ends;
        debug4 << osm.str() << endl;
        avtCallback::IssueWarning(osm.str().c_str());
    }

    stringVector vars = atts.GetQueryAtts().GetVariables();
    bool multiCurve = false;
    if (atts.GetQueryAtts().GetQueryInputParams().HasNumericEntry("curve_plot_type"))
    {
        multiCurve = (atts.GetQueryAtts().GetQueryInputParams().GetEntry("curve_plot_type")->ToInt() == 1);
    }
    avtDataTree_p tree = CreateTree(times, qRes, vars, multiCurve);
    SetOutputDataTree(tree);
    finalOutputCreated = true;
}
Пример #10
0
void
avtDataBinningFilter::Execute(void)
{
    ConstructDataBinningAttributes dba = atts.CreateConstructionAtts();
    std::vector<double> bb = dba.GetBinBoundaries();
    if (! atts.GetDim1SpecifyRange())
    {
        if (atts.GetDim1BinBasedOn() == DataBinningAttributes::Variable)
        {
            std::string v1name = atts.GetDim1Var();
            if (v1name == "default")
                v1name = pipelineVariable;
            double range[2];
            GetDataExtents(range, v1name.c_str());
            bb[0] = range[0];
            bb[1] = range[1];
        }
        else
        {
            int dim = (atts.GetDim1BinBasedOn()-DataBinningAttributes::X);
            double range[6];
            GetSpatialExtents(range);
            bb[0] = range[2*dim];
            bb[1] = range[2*dim+1];
        }
    }
    if ((! atts.GetDim2SpecifyRange()) && (atts.GetNumDimensions() == DataBinningAttributes::Two ||
                                         atts.GetNumDimensions() == DataBinningAttributes::Three))
    {
        if (atts.GetDim2BinBasedOn() == DataBinningAttributes::Variable)
        {
            std::string v2name = atts.GetDim2Var();
            if (v2name == "default")
                v2name = pipelineVariable;
            double range[2];
            GetDataExtents(range, v2name.c_str());
            bb[2] = range[0];
            bb[3] = range[1];
        }
        else
        {
            int dim = (atts.GetDim2BinBasedOn()-DataBinningAttributes::X);
            double range[6];
            GetSpatialExtents(range);
            bb[2] = range[2*dim];
            bb[3] = range[2*dim+1];
        }
    }
    if ((! atts.GetDim3SpecifyRange()) && atts.GetNumDimensions() == DataBinningAttributes::Three)
    {
        if (atts.GetDim3BinBasedOn() == DataBinningAttributes::Variable)
        {
            std::string v3name = atts.GetDim3Var();
            if (v3name == "default")
                v3name = pipelineVariable;
            double range[2];
            GetDataExtents(range, v3name.c_str());
            bb[4] = range[0];
            bb[5] = range[1];
        }
        else
        {
            int dim = (atts.GetDim3BinBasedOn()-DataBinningAttributes::X);
            double range[6];
            GetSpatialExtents(range);
            bb[4] = range[2*dim];
            bb[5] = range[2*dim+1];
        }
    }
    dba.SetBinBoundaries(bb);

    avtDataBinningConstructor dbc;
    dbc.SetInput(GetInput());
    avtDataBinning *d = dbc.ConstructDataBinning(&dba, lastContract, false);

    if (atts.GetOutputType() == DataBinningAttributes::OutputOnBins)
    {
        if (PAR_Rank() == 0)
        {
            vtkDataSet *ds = d->CreateGrid();
            if (atts.GetNumDimensions() == DataBinningAttributes::One)
                ds->GetPointData()->GetScalars()->SetName(varname.c_str());
            else
                ds->GetCellData()->GetScalars()->SetName(varname.c_str());
            ds->GetCellData()->SetActiveScalars(varname.c_str());
            SetOutputDataTree(new avtDataTree(ds, -1));
            double range[2] = { FLT_MAX, -FLT_MAX };
            GetDataRange(ds, range, varname.c_str(), false);
            avtDataAttributes &dataAtts = GetOutput()->GetInfo().GetAttributes();
            dataAtts.GetThisProcsOriginalDataExtents(varname.c_str())->Set(range);
            dataAtts.GetThisProcsActualDataExtents(varname.c_str())->Set(range);
    
            ds->Delete();
        }
        else
            SetOutputDataTree(new avtDataTree());
     
        avtDataAttributes &dataAtts = GetOutput()->GetInfo().GetAttributes();
        int dim = ( (atts.GetNumDimensions() == DataBinningAttributes::One) ? 1
                  : ((atts.GetNumDimensions() == DataBinningAttributes::Two) ? 2 : 3));
        dataAtts.GetThisProcsOriginalSpatialExtents()->Set(&bb[0]);
        dataAtts.GetOriginalSpatialExtents()->Set(&bb[0]);
    }
    else if (atts.GetOutputType() == DataBinningAttributes::OutputOnInputMesh)
    {
        double range[2] = { FLT_MAX, -FLT_MAX };
        bool hadError = false;
        avtDataTree_p tree = CreateArrayFromDataBinning(GetInputDataTree(), d, range, hadError);
        if (UnifyMaximumValue((int) hadError) > 0)
        {
            avtCallback::IssueWarning("The data binning could not be placed on the input "
                    "mesh.  This is typically because the data binning is over different "
                    "centerings (zonal and nodal) and can not be meaningfully placed back "
                    "on the input mesh.  Try recentering one of the variables to remove "
                    "this ambiguity.");
            SetOutputDataTree(new avtDataTree());
        }
        else
        {
            SetOutputDataTree(tree);
            avtDataAttributes &dataAtts = GetOutput()->GetInfo().GetAttributes();
            dataAtts.GetThisProcsOriginalDataExtents(varname.c_str())->Set(range);
            dataAtts.GetThisProcsActualDataExtents(varname.c_str())->Set(range);
        }
    }
    
    delete d;
}
void
avtResampleFilter::BypassResample(void)
{
    SetOutputDataTree(GetInputDataTree());
}
void
avtPeaksOverThresholdFilter::Execute()
{
    if (atts.GetDataAnalysisYearRangeEnabled())
    {
        if (atts.GetDataYearBegin() < atts.GetDataAnalysisYear1() ||
                atts.GetDataYearBegin() > atts.GetDataAnalysisYear2())
        {
            EXCEPTION1(ImproperUseException, "Invalid data analysis begin year.");
        }

        if (atts.GetDataAnalysisYear1() >= atts.GetDataAnalysisYear2())
        {
            EXCEPTION1(ImproperUseException, "Invalid data analysis year range.");
        }
        if (atts.GetDataAnalysisYear1() < atts.GetDataYearBegin() ||
                atts.GetDataAnalysisYear2() < atts.GetDataYearBegin())
        {
            EXCEPTION1(ImproperUseException, "Invalid data analysis year range.");
        }
    }
    if (atts.GetEnsemble())
    {
        if (!atts.GetDataAnalysisYearRangeEnabled())
        {
            EXCEPTION1(ImproperUseException, "Ensemble usage requires year range to be set.");
        }
    }

    int t1 = visitTimer->StartTimer();
    avtRPOTFilter *f = new avtRPOTFilter();

    std::string vlibdir = GetVisItLibraryDirectory() + VISIT_SLASH_CHAR + "r_support";
    std::string vlibrdir  = vlibdir  + VISIT_SLASH_CHAR + "Rscripts" + VISIT_SLASH_CHAR;
    f->codeDir = vlibrdir;
    f->atts = atts;

    f->SetInput(GetInput());

    avtContract_p spec = GetInput()->GetOriginatingSource()->GetGeneralContract();
    avtDataObject_p dob = f->GetOutput();

    dob->Update(spec);
    avtDataTree_p tree = f->GetTypedOutput()->GetDataTree();

    visitTimer->StopTimer(t1, "avtPeaksOverThreshold: call avtRPOTFilter");

    //Set the output variable properly.
    int nleaves;
    vtkDataSet **leaves = tree->GetAllLeaves(nleaves);
    for (int i = 0; i < nleaves; i++)
    {
        if (leaves[i]->GetPointData()->GetScalars())
            leaves[i]->GetPointData()->GetScalars()->SetName(pipelineVariable);
        else if (leaves[i]->GetCellData()->GetScalars())
            leaves[i]->GetCellData()->GetScalars()->SetName(pipelineVariable);
    }
    delete [] leaves;

    SetOutputDataTree(tree);
    delete f;
}
void
avtChannelCommFilter::CreateIntegralCurveOutput(std::vector<avtIntegralCurve*> &ics)
{
    vtkRectilinearGrid *rg = vtkRectilinearGrid::New();
    int dims[3];
    int numInX = atts.GetNumInX();
    int numInY = atts.GetNumInY();
    dims[0] = numInX;
    dims[1] = numInY;
    dims[2] = 1;

    vtkFloatArray *x = vtkFloatArray::New();
    x->SetNumberOfTuples(numInX);
    for (int i = 0 ; i < dims[0] ; i++)
       x->SetTuple1(i, -10+20.0*i/(numInX-1.0));
    rg->SetXCoordinates(x);
    x->Delete();

    vtkFloatArray *y = vtkFloatArray::New();
    y->SetNumberOfTuples(numInY);
    for (int i = 0 ; i < dims[1] ; i++)
       y->SetTuple1(i, -10+20.0*i/(numInY-1.0));
    rg->SetYCoordinates(y);
    y->Delete();

    vtkFloatArray *z = vtkFloatArray::New();
    z->SetNumberOfTuples(1);
    z->SetTuple1(0, 0.0);
    rg->SetZCoordinates(z);
    z->Delete();

    vtkFloatArray *arr = vtkFloatArray::New();
    arr->SetNumberOfTuples(numInX*numInY);
    for (int i = 0 ; i < numInX*numInY ; i++)
        arr->SetTuple1(i, 0.);
    
    double max = 0;
    for (int i = 0 ; i < ics.size() ; i++)
    {
        avtChannelCommIC *cc = (avtChannelCommIC *) ics[i];
        const int *id = cc->GetIndex();
        int II = id[0];
        int JJ = id[1];
        int idx = JJ*numInX + II;
        arr->SetTuple1(idx, cc->GetDistance());
        if (cc->GetDistance() > max)
           max = cc->GetDistance();
    }

    arr->SetName("operators/ChannelComm/Mesh");
    rg->GetPointData()->AddArray(arr);
    arr->Delete();
    rg->GetPointData()->SetActiveScalars("operators/ChannelComm/Mesh");
    
    GetOutput()->GetInfo().GetAttributes().AddVariable("operators/ChannelComm/Mesh");
    double range[2] = { 0, max };
    GetOutput()->GetInfo().GetAttributes().SetVariableDimension(1, "operators/ChannelComm/Mesh");
    GetOutput()->GetInfo().GetAttributes().SetVariableType(AVT_SCALAR_VAR, "operators/ChannelComm/Mesh");
    GetOutput()->GetInfo().GetAttributes().GetActualDataExtents("operators/ChannelComm/Mesh")->Set(range);
    avtDataTree_p dt = new avtDataTree(rg, 0);
    rg->Delete();
    SetOutputDataTree(dt);
}
Пример #14
0
void 
avtLCSFilter::CreateRectilinearGridIterativeCalcOutput(std::vector<avtIntegralCurve*> &ics)
{
    //root should now have index into global structure and all
    //matching end positions.
    if(PAR_Rank() != 0)
    {
        avtDataTree* dummy = new avtDataTree();
        SetOutputDataTree(dummy);
    }
    else
    {
      if (fsle_ds->GetDataObjectType() != VTK_RECTILINEAR_GRID)
      {
        EXCEPTION1(VisItException,
                   "Can only compute CreateRectilinearGridIterativeCalcOutput on "
                   "rectilinear grids. ");
      }

      //variable name.
      std::string var = outVarRoot + outVarName;

      vtkDoubleArray *exponents = (vtkDoubleArray *)
        fsle_ds->GetPointData()->GetArray(var.c_str());

      int nTuples = exponents->GetNumberOfTuples();

      //min and max values over all datasets of the tree.
      double minv =  std::numeric_limits<double>::max();
      double maxv = -std::numeric_limits<double>::max();
      
      int count = 0;

      for(size_t i=0; i<ics.size(); ++i)
      {
        avtStreamlineIC * ic = (avtStreamlineIC *) ics[i];

        size_t l = ic->id; // The curve id is the index into the VTK data.

        double lambda = exponents->GetTuple1(l);

        if( lambda == -std::numeric_limits<double>::max() )
        {
          lambda = 0;
          exponents->SetTuple1(l, lambda );
        }
        else
        {
          ++count;
          ic->status.ClearTerminationMet();

          if( clampLogValues && lambda < 0 )
          {
            lambda = 0;
            exponents->SetTuple1(l, lambda );
          }
        }

        minv = std::min(lambda, minv);
        maxv = std::max(lambda, maxv);
      }

      if( count <= nTuples/10 )
      {
        if( minSizeValue == std::numeric_limits<double>::max() )
          minSizeValue = 0.0;

        if( maxSizeValue == -std::numeric_limits<double>::max() )
          maxSizeValue = 0.0;

        char str[1028];

        SNPRINTF(str, 1028, "\n%d%% of the nodes (%d of %d nodes) "
                 "exaimed produced a valid exponent (%f to %f). "
                 "This may be due to too large of a size limit (%f), "
                 "too small of an integration step (%f), or "
                 "too few integration steps (%d out of %d where taken), or "
                 "simply due to the nature of the data. "
                 "The size range was from %f to %f. ",
                 (int) (100.0 * (double) count / (double) nTuples),
                 count, nTuples,
                 minv, maxv,
                 maxSize, maxStepLength, numSteps, maxSteps,
                 minSizeValue, maxSizeValue );

        avtCallback::IssueWarning(str);
      }
      
      // Make the exponents the the active scalars.
      fsle_ds->GetPointData()->SetActiveScalars(var.c_str());

      // Remove the working arrays.
      fsle_ds->GetPointData()->RemoveArray("component");
      fsle_ds->GetPointData()->RemoveArray("times");

      std::string str = CreateCacheString();
      StoreArbitraryVTKObject(SPATIAL_DEPENDENCE | DATA_DEPENDENCE,
                              outVarName.c_str(), -1, -1,
                              str.c_str(), fsle_ds);
      
      int index = 0;//what does index mean in this context?
      avtDataTree* dt = new avtDataTree(fsle_ds,index);
      int x = 0;
      dt->GetAllLeaves(x);
      
      SetOutputDataTree(dt);
      
      //set atts.
      avtDataAttributes &dataatts = GetOutput()->GetInfo().GetAttributes();
      avtExtents* e = dataatts.GetThisProcsActualDataExtents();
      
      double range[2];
      range[0] = minv;
      range[1] = maxv;
      e->Set(range);
    }
}
void
avtExtractPointFunction2DFilter::Execute()
{
    // Check consistency
    if (atts.GetI().size() != atts.GetJ().size())
    {
        EXCEPTION1(ImproperUseException,
                "I and J arrays need to have the same number of elements.");
    }

    const size_t num_functions = atts.GetI().size();
    std::vector<double*> function_data(num_functions, 0);
    bool klInformationSet = false;
    double dvpar = 1.0;
    double dmu = 1.0;
    int v_base_index[2] = { 0, 0 };
    int v_dims[2] = { 0, 0 };

    // Get the input data tree
    avtDataTree_p in_tree = GetInputDataTree();

    if (in_tree->IsEmpty())
    {
        SetOutputDataTree(in_tree);
        return;
    }

    int nLeaves = 0;
    vtkDataSet **leaves = in_tree->GetAllLeaves(nLeaves);

    // Get all data sets
    // FIXME: Structured grids should be simple as well
    vtkRectilinearGrid *rgrid = 0; // HACK: This just uses the last instance
    vtkDataArray *data = 0; // HACK: This just uses the last instance
    for (int i = 0; i < nLeaves; ++i)
    {
        // Ensure that we are working on rectilinear grid
        rgrid = dynamic_cast<vtkRectilinearGrid*>(leaves[i]);
        if (!rgrid)
            EXCEPTION1(ImproperUseException,
                       "Can only extract point function for a rectilinear grid.");

        // Dimensions of data set
        int dims[3];
        rgrid->GetDimensions(dims);
        // We want number of cells as grid dimension, not number of samples
        for (int d=0; d<3; ++d)
            dims[d]--;

        vtkIntArray *arr = dynamic_cast<vtkIntArray*>(rgrid->GetFieldData()->GetArray("base_index"));
        int base_index[3] = { 0, 0, 0 };
        if (arr)
            for (int d = 0; d < 3; ++d)
                base_index[d] = arr->GetValue(d);

        int i_min = base_index[0];
        int i_max = base_index[0] + dims[0] - 1;
        int j_min = base_index[1];
        int j_max = base_index[1] + dims[1] - 1;

        // FIXME: Take avtRealDims into account
        // arr = dynamic_cast<vtkIntArray*>(rgrid->GetFieldData()->GetArray("avtRealDims"));
        // int avtRealDims[6] = { 0, 0, 0, 0, 0, 0 };
        // if (arr)
        //     for (int d = 0; d < 6; ++d)
        //         avtRealDims[d] = arr->GetValue(d);

        vtkDoubleArray *dx_arr = dynamic_cast<vtkDoubleArray*>(rgrid->GetFieldData()->GetArray("dx_array"));
        vtkIntArray *v_base_index_arr = dynamic_cast<vtkIntArray*>(rgrid->GetFieldData()->GetArray("v_base_index"));
        vtkIntArray *v_dims_arr = dynamic_cast<vtkIntArray*>(rgrid->GetFieldData()->GetArray("v_dims"));

        const char *justTheVar = pipelineVariable + strlen("operators/ExtractPointFunction2D/");
 
        if (!klInformationSet)
        {
           if (dx_arr)
            {
                dvpar = dx_arr->GetValue(0);
                dmu = dx_arr->GetValue(1);
            }
            if (v_base_index_arr && v_dims_arr)
            {
                for (int i = 0; i < 2; ++i)
                {
                    v_base_index[i] = v_base_index_arr->GetValue(i);
                    v_dims[i] = v_dims_arr->GetValue(i);
                }
            }
            else
            {
                EXCEPTION1(ImproperUseException,
                        "Internal error: Velocity base index and dimensions not set by database plugin.");
            }
        }
        else
        {
           if (dx_arr)
            {
                if (dvpar != dx_arr->GetValue(0))
                    EXCEPTION1(ImproperUseException, "Internal error: dvpar mismatch.");
                if (dmu != dx_arr->GetValue(1))
                    EXCEPTION1(ImproperUseException, "Internal error: dmu mismatch.");
            }
            if (v_base_index_arr && v_dims_arr)
            {
                for (int i = 0; i < 2; ++i)
                {
                    if (v_base_index[i] != v_base_index_arr->GetValue(i))
                        EXCEPTION1(ImproperUseException, "Internal error: v_base_index mismatch.");
                    if (v_dims[i] != v_dims_arr->GetValue(i))
                        EXCEPTION1(ImproperUseException, "Internal error: v_dims mismatch.");
                }
            }
        }

        data = rgrid->GetCellData()->GetArray(justTheVar); // FIXME HACK: Outside for loop to ensure that processor 0 has a data pointer

        if (!data)
        {
            EXCEPTION1(VisItException, "Internal error: Could not get data for array variable (maybe due to an operator requesting ghost zones).");
        }

        const std::vector<int> &i_vals = atts.GetI();
        const std::vector<int> &j_vals = atts.GetJ();
        for (size_t curr_tuple = 0; curr_tuple < i_vals.size(); ++curr_tuple)
            if (i_min <= i_vals[curr_tuple] && i_vals[curr_tuple] <= i_max && j_min <= j_vals[curr_tuple] && j_vals[curr_tuple] <= j_max)
            {
                int ijk_f[3] = { i_vals[curr_tuple] - base_index[0], j_vals[curr_tuple] - base_index[1], 0 };
                vtkIdType id_f = rgrid->ComputeCellId(ijk_f);
                function_data[curr_tuple] = new double[v_dims[0]*v_dims[1]];
                for (vtkIdType comp = 0; comp < v_dims[0]*v_dims[1]; ++comp)
                    function_data[curr_tuple][comp] = data->GetComponent(id_f, comp);
            }
    }

#ifdef PARALLEL
    // Determine (on processor 0) where data resides
    std::vector<int> function2proc_map(function_data.size(), -1);
    for (size_t curr_func = 0; curr_func < function_data.size(); ++curr_func)
        if (function_data[curr_func]) function2proc_map[curr_func] = PAR_Rank();
    std::vector<int> tmp_function2proc_map(function2proc_map);
    MPI_Reduce(&tmp_function2proc_map[0], &function2proc_map[0], function2proc_map.size(), MPI_INT, MPI_MAX, 0, VISIT_MPI_COMM);

    // HACK: Send all data to processor 0
    // FIXME: Better distribution among processors
    // FIXME: Non-blocking send/receive
    if (PAR_Rank() == 0)
    {
        for (size_t curr_func = 0; curr_func < function_data.size(); ++curr_func)
            if (function2proc_map[curr_func] >= 1)
            {
                function_data[curr_func] = new double[v_dims[0]*v_dims[1]];
                MPI_Status status;
                MPI_Recv(function_data[curr_func], v_dims[0]*v_dims[1], MPI_DOUBLE, function2proc_map[curr_func], MPI_ANY_TAG, VISIT_MPI_COMM, &status);
            }
    }
    else
    {
        for (size_t curr_func = 0; curr_func < function_data.size(); ++curr_func)
            if (function_data[curr_func])
                MPI_Send(function_data[curr_func], v_dims[0]*v_dims[1], MPI_DOUBLE, 0, 0, VISIT_MPI_COMM);
    }

    if (PAR_Rank() == 0)
    {
#endif
        vtkRectilinearGrid *ogrid = vtkRectilinearGrid::New();
        ogrid->SetDimensions(v_dims[0]+1, v_dims[1]+1, function_data.size());
        vtkDataArray *xCoords = rgrid->GetXCoordinates()->NewInstance();
        xCoords->SetNumberOfTuples(v_dims[0]+1);
        for (int k = 0; k < v_dims[0]+1; ++k)
            xCoords->SetTuple1(k, (v_base_index[0]+k)*dvpar);
        ogrid->SetXCoordinates(xCoords);
        xCoords->Delete();
        vtkDataArray *yCoords = rgrid->GetXCoordinates()->NewInstance();
        yCoords->SetNumberOfTuples(v_dims[1]+1);
        for (int l = 0; l < v_dims[1]+1; ++l)
            yCoords->SetTuple1(l, (v_base_index[1]+l)*dmu);
        ogrid->SetYCoordinates(yCoords);
        yCoords->Delete();
        vtkDataArray *zCoords = rgrid->GetXCoordinates()->NewInstance();
        zCoords->SetNumberOfTuples(function_data.size());
        for (int f = 0; f < function_data.size(); ++f)
            zCoords->SetTuple1(f, f);
        ogrid->SetZCoordinates(zCoords);
        zCoords->Delete();

        // FIXME: v_base_index, dvpar and dmu are only defined if there is any data on rank 0
        spatialExtents[0] = v_base_index[0] * dvpar;
        spatialExtents[1] = (v_base_index[0] + v_dims[0]) * dvpar;
        spatialExtents[2] = v_base_index[1] * dmu;
        spatialExtents[3] = (v_base_index[1] + v_dims[1]) * dmu;
        spatialExtents[4] = 0;
        spatialExtents[5] = function_data.size() - 1;

        // FIXME: data is only defined if there is any data on rank 0
        vtkDataArray *odata = data->NewInstance();
        odata->SetNumberOfComponents(1);
        odata->SetNumberOfTuples(v_dims[0]*v_dims[1]*function_data.size());
        for (int k = 0; k < v_dims[0]; ++k)
            for (int l = 0; l < v_dims[1]; ++l)
                for (int f = 0; f < function_data.size(); ++f)
                {
                    int ijk_t[3] = { k, l, f };
                    vtkIdType id_t = ogrid->ComputeCellId(ijk_t);
                    double val = function_data[f] ? function_data[f][k*v_dims[1]+l] : 0;
                    odata->SetTuple1(id_t, val);
                    if (val < range[0]) range[0] = val;
                    if (val > range[1]) range[1] = val;
                }
        odata->SetName(outVarName.c_str());
        ogrid->GetCellData()->SetScalars(odata);
        odata->Delete();

#if 0
        vtkDataSetWriter *wrtr = vtkDataSetWriter::New();
        wrtr->SetFileTypeToASCII();
        wrtr->SetInputData(ogrid);
        wrtr->SetFileName("debug.vtk");
        wrtr->Write();
#endif

        SetOutputDataTree(new avtDataTree(ogrid, 1));
#ifdef PARALLEL
    }
    else
    {
        SetOutputDataTree(new avtDataTree());
    }
#endif

    for (std::vector<double*>::iterator it = function_data.begin(); it != function_data.end(); ++it)
        delete[] *it;
}
void
avtActualExtentsFilter::Execute(void)
{
    UpdateExtents();
    SetOutputDataTree(GetInputDataTree());
}
Пример #17
0
void
avtResampleFilter::ResampleInput(void)
{
    int  i, j, k;

    avtDataset_p output = GetTypedOutput();
    double bounds[6] = { 0, 0, 0, 0, 0, 0 };
    bool is3D = GetBounds(bounds);

    debug4 << "Resampling over space: " << bounds[0] << ", " << bounds[1]
           << ": " << bounds[2] << ", " << bounds[3] << ": " << bounds[4]
           << ", " << bounds[5] << endl;
    
    //
    // Our resampling leaves some invalid values in the data range.  The
    // easiest way to bypass this is to get the data range from the input and
    // pass it along (since resampling does not change it in theory).
    //
    double range[2];
    if (GetInput()->GetInfo().GetAttributes().ValidActiveVariable())
    {
        GetDataExtents(range);
        output->GetInfo().GetAttributes().GetDesiredDataExtents()->Set(range);
    }

    avtViewInfo view;
    double scale[3];
    CreateViewFromBounds(view, bounds, scale);

    //
    // What we want the width, height, and depth to be depends on the
    // attributes.
    //
    int width, height, depth;
    GetDimensions(width, height, depth, bounds, is3D);

    //
    // If there are no variables, then just create the mesh and exit.
    //
    bool thereAreNoVariables = 
          (GetInput()->GetInfo().GetAttributes().GetNumberOfVariables() <= 0);
    if (thereAreNoVariables)
    {
        if (PAR_Rank() == 0)
        {
            vtkRectilinearGrid *rg = CreateGrid(bounds, width, height, depth,
                                      0, width, 0, height, cellCenteredOutput, is3D);
            avtDataTree_p tree = new avtDataTree(rg, 0);
            rg->Delete();
            SetOutputDataTree(tree);
        }
        else
        {
            //
            // Putting in a NULL data tree can lead to seg faults, etc.
            //
            avtDataTree_p dummy = new avtDataTree();
            SetOutputDataTree(dummy);
        }

        return;
    }

    //
    // World space is a right-handed coordinate system.  Image space (as used
    // in the sample point extractor) is a left-handed coordinate system.
    // This is because large X is at the right and large Y is at the top.
    // The z-buffer has the closest points at z=0, so Z is going away from the
    // screen ===> left handed coordinate system.  If we reflect across X,
    // then this will account for the difference between the coordinate 
    // systems.
    //
    scale[0] *= -1.;

    //
    // We don't want an Update to go all the way up the pipeline, so make
    // a terminating source corresponding to our input.
    //
    avtDataset_p ds;
    avtDataObject_p dObj = GetInput();
    CopyTo(ds, dObj);
    avtSourceFromAVTDataset termsrc(ds);

    //
    // The sample point extractor expects everything to be in image space.
    //
    avtWorldSpaceToImageSpaceTransform trans(view, scale);
    trans.SetInput(termsrc.GetOutput());

    bool doKernel = 
        (GetInput()->GetInfo().GetAttributes().GetTopologicalDimension() == 0);
    avtSamplePointExtractor extractor(width, height, depth);
    extractor.SendCellsMode(false);
    extractor.Set3DMode(is3D);
    extractor.SetInput(trans.GetOutput());
    if (doKernel)
        extractor.SetKernelBasedSampling(true);
    avtSamplePoints_p samples = extractor.GetTypedOutput();

    //
    // If the selection this filter exists to create has already been handled,
    // or if there are no pieces for this processor to process, then we can skip
    // execution. But, take care to emulate the same collective
    // calls other processors may make before returning.
    //
    if (GetInput()->GetInfo().GetAttributes().GetSelectionApplied(selID))
    {
        debug1 << "Bypassing Resample operator because database plugin "
                  "claims to have applied the selection already" << endl;

        SetOutputDataTree(GetInputDataTree());

        // we can save a lot of time if we know everyone can bypass
        if (UnifyMaximumValue(0) == 0)
            return;

        // here is some dummied up code to match collective calls below
        int effectiveVars = samples->GetNumberOfRealVariables();
        double *ptrtmp = new double[width*height*depth];
        for (int jj = 0; jj < width*height*depth; jj++)
            ptrtmp[jj] = -FLT_MAX;
        for (i = 0 ; i < effectiveVars ; i++)
            Collect(ptrtmp, width*height*depth);
        delete [] ptrtmp;
        return;
    }
    else
    {
        UnifyMaximumValue(1);
    }

    //
    //
    // PROBLEM SIZED WORK OCCURS BEYOND THIS POINT
    // If you add (or remove) collective calls below this point, make sure to
    // put matching sequence into bypass code above
    //
    //

    avtSamplePointCommunicator communicator;
    avtImagePartition partition(width, height, PAR_Size(), PAR_Rank());
    communicator.SetImagePartition(&partition);
    bool doDistributedResample = false;
#ifdef PARALLEL
    doDistributedResample = atts.GetDistributedResample();
#endif

    if (doDistributedResample)
    {
        partition.SetShouldProduceOverlaps(true);
        avtDataObject_p dob;
        CopyTo(dob, samples);
        communicator.SetInput(dob);
        samples = communicator.GetTypedOutput();
    }

    // Always set up an arbitrator, even if user selected random.
    bool arbLessThan = !atts.GetUseArbitrator() || atts.GetArbitratorLessThan();
    std::string arbName = atts.GetArbitratorVarName();
    if (arbName == "default")
        arbName = primaryVariable;
    extractor.SetUpArbitrator(arbName, arbLessThan);

    //
    // Since this is Execute, forcing an update is okay...
    //
    samples->Update(GetGeneralContract());

    if (samples->GetInfo().GetValidity().HasErrorOccurred())
    {
        GetOutput()->GetInfo().GetValidity().ErrorOccurred();
        GetOutput()->GetInfo().GetValidity().SetErrorMessage(
                          samples->GetInfo().GetValidity().GetErrorMessage());
    }

    //
    // Create a rectilinear dataset that is stretched according to the 
    // original bounds.
    //
    int width_start  = 0;
    int width_end    = width;
    int height_start = 0;
    int height_end   = height;
    if (doDistributedResample)
    {
        partition.GetThisPartition(width_start, width_end, height_start, 
                                   height_end);
        width_end += 1;
        height_end += 1;
    }

    //
    // If we have more processors than domains, we have to handle that
    // gracefully.  Communicate how many variables there are so that those
    // that don't have data can play well.
    //
    int realVars  = samples->GetNumberOfRealVariables();
    int numArrays = realVars;
    if (doKernel)
        numArrays++;
    vtkDataArray **vars = new vtkDataArray*[numArrays];
    for (i = 0 ; i < numArrays ; i++)
    {
        vars[i] = vtkDoubleArray::New();
        if (doKernel && (i == numArrays-1))
            vars[i]->SetNumberOfComponents(1);
        else
        {
            vars[i]->SetNumberOfComponents(samples->GetVariableSize(i));
            vars[i]->SetName(samples->GetVariableName(i).c_str());
        }
    }

    if (doKernel)
        samples->GetVolume()->SetUseKernel(true);

    avtImagePartition *ip = NULL;
    if (doDistributedResample)
        ip = &partition;

    // We want all uncovered regions to get the default value.  That is
    // what the first argument of GetVariables is for.  But if the
    // default value is large, then it will screw up the collect call below,
    // which uses MPI_MAX for an all reduce.  So give uncovered regions very
    // small values now (-FLT_MAX) and then replace them later.
    double defaultPlaceholder = -FLT_MAX;
    samples->GetVolume()->GetVariables(defaultPlaceholder, vars, 
                                       numArrays, ip);

    if (!doDistributedResample)
    {
        //
        // Collect will perform the parallel collection.  Does nothing in
        // serial.  This will only be valid on processor 0.
        //
        for (i = 0 ; i < numArrays ; i++)
        {
            double *ptr = (double *) vars[i]->GetVoidPointer(0);
            Collect(ptr, vars[i]->GetNumberOfComponents()*width*height*depth);
        }
    }
    
    // Now replace the -FLT_MAX's with the default value.  (See comment above.)
    for (i = 0 ; i < numArrays ; i++)
    {
        int numTups = vars[i]->GetNumberOfComponents()
                    * vars[i]->GetNumberOfTuples();
        if (numTups > 0)
        {
            double *ptr = (double *) vars[i]->GetVoidPointer(0);
            for (j = 0 ; j < numTups ; j++)
                ptr[j] = (ptr[j] == defaultPlaceholder 
                                 ? atts.GetDefaultVal() 
                                 : ptr[j]);
        }
    }
   
    bool iHaveData = false;
    if (doDistributedResample)
        iHaveData = true;
    if (PAR_Rank() == 0)
        iHaveData = true;
    if (height_end > height)
        iHaveData = false;
    if (iHaveData)
    {
        vtkRectilinearGrid *rg = CreateGrid(bounds, width, height, depth,
                                        width_start, width_end, height_start,
                                        height_end, cellCenteredOutput, is3D);

        if (doKernel)
        {
            double min_weight = avtPointExtractor::GetMinimumWeightCutoff();
            vtkDataArray *weights = vars[numArrays-1];
            int numVals = weights->GetNumberOfTuples();
            for (i = 0 ; i < realVars ; i++)
            {
                for (j = 0 ; j < vars[i]->GetNumberOfComponents() ; j++)
                {
                    for (k = 0 ; k < numVals ; k++)
                    {
                        double weight = weights->GetTuple1(k);
                        if (weight <= min_weight)
                            vars[i]->SetComponent(k, j, atts.GetDefaultVal());
                        else
                            vars[i]->SetComponent(k, j, 
                                         vars[i]->GetComponent(k, j) / weight);
                    }
                }
            }
        }

        //
        // Attach these variables to our rectilinear grid.
        //
        for (i = 0 ; i < realVars ; i++)
        {
            const char *varname = vars[i]->GetName();
            if (strcmp(varname, primaryVariable) == 0)
            {
                if (vars[i]->GetNumberOfComponents() == 3)
                    if (cellCenteredOutput)
                        rg->GetCellData()->SetVectors(vars[i]);
                    else
                        rg->GetPointData()->SetVectors(vars[i]);
                else if (vars[i]->GetNumberOfComponents() == 1)
                {
                    if (cellCenteredOutput)
                    {
                        rg->GetCellData()->AddArray(vars[i]);
                        rg->GetCellData()->SetScalars(vars[i]);
                    }
                    else
                    {
                        rg->GetPointData()->AddArray(vars[i]);
                        rg->GetPointData()->SetScalars(vars[i]);
                    }
                }
                else
               {
                    if (cellCenteredOutput)
                        rg->GetCellData()->AddArray(vars[i]);
                    else
                        rg->GetPointData()->AddArray(vars[i]);
               }
            }
            else
            {
                if (cellCenteredOutput)
                    rg->GetCellData()->AddArray(vars[i]);
                else
                    rg->GetPointData()->AddArray(vars[i]);
            }
        }

        avtDataTree_p tree = new avtDataTree(rg, 0);
        rg->Delete();
        SetOutputDataTree(tree);
    }
    else
    {
        //
        // Putting in a NULL data tree can lead to seg faults, etc.
        //
        avtDataTree_p dummy = new avtDataTree();
        SetOutputDataTree(dummy);
    }

    for (i = 0 ; i < numArrays ; i++)
    {
        vars[i]->Delete();
    }
    delete [] vars;
}
void
avtPythonExpression::Execute()
{
    //
    // the real outputVariableName is not avalaible until well after
    // ProcessArguments is called - set it here so the filter can use the 
    // the proper output name.
    //
    pyEnv->Filter()->SetAttribute("output_var_name",std::string(outputVariableName));

    // get input data tree to obtain datasets
    avtDataTree_p tree = GetInputDataTree();
    // holds number of datasets
    int nsets;

    // get datasets
    vtkDataSet **data_sets = tree->GetAllLeaves(nsets);

    // get dataset domain ids
    std::vector<int> domain_ids;
    tree->GetAllDomainIds(domain_ids);

    // create a tuple holding to hold the datasets
    PyObject *py_dsets  = PyTuple_New(nsets);
    PyObject *py_domids = PyTuple_New(nsets);

     if(py_dsets == NULL || py_domids == NULL)
     {
            delete [] data_sets;
            PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                         "Unable to create execution input lists");
     }

    // array to hold output leaves
    avtDataTree_p *leaves = new avtDataTree_p[nsets];

    // hand data_sets and domain_ids to the python expression
    for(int i = 0; i < nsets ; i++)
    {
        if(PyTuple_SetItem(py_dsets,i,pyEnv->WrapVTKObject(data_sets[i],"vtkDataSet")) != 0)
        {
            delete [] data_sets;
            PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                         "Unable to add data set to execution input list");
        }
        if(PyTuple_SetItem(py_domids,i,PyInt_FromLong(domain_ids[i])) != 0)
        {
            delete [] data_sets;
            PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                         "Unable to add domain id to execution input list");
        }

    }
    delete [] data_sets;

    // call execute on Filter
    PyObject *py_filter = pyEnv->Filter()->PythonObject();
    if(py_filter == NULL)
        PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                     "Python filter not initialized.");

    // get the execute method
    PyObject *py_exe= PyString_FromString("execute");
    if(py_exe == NULL)
        PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                     "Error preparing for call of 'execute' method.");
    // call with py_dsets, py_domids
    PyObject *py_exe_res = PyObject_CallMethodObjArgs(py_filter,
                                                      py_exe,
                                                      py_dsets,py_domids,
                                                      NULL);
    if(py_exe_res == NULL)
        PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                     "Python Expression 'execute' method failed");
    if(PySequence_Check(py_exe_res) == 0)
        PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                     "Python Expression 'execute' method must return a sequence of "
                     "data sets & a sequence of domain_ids");

    Py_DECREF(py_dsets);
    Py_DECREF(py_domids);
    Py_DECREF(py_exe);


    // result should be a list with datasets and domain ids

    PyObject *py_result_dsets  = PySequence_GetItem(py_exe_res,0);
    PyObject *py_result_domids = PySequence_GetItem(py_exe_res,1);

    

    if(py_result_dsets == NULL || PySequence_Check(py_result_dsets) == 0)
        PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                     "Python Expression execute method must return a sequence of "
                     "data sets & a sequence of domain_ids");

    if(py_result_domids == NULL || PySequence_Check(py_result_domids) == 0)
        PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                     "Python Expression execute method must return a sequence of "
                     "data sets & a sequence of domain_ids");

    PyObject *py_r_dsets  = PySequence_Fast(py_result_dsets,"Expected Sequence");
    PyObject *py_r_domids = PySequence_Fast(py_result_domids,"Expected Sequence");

    if(py_r_dsets == NULL || py_r_domids == NULL)
        PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                     "Unable to obtain result sequences.");


    // int n_r_dsets  = PySequence_Size(py_r_dsets);
    // int n_r_domids = PySequence_Size(py_r_domids);

    // check that the lists are the correct size?

    std::vector<vtkDataSet*> res_dsets;
    std::vector<int>         res_domids;
    
    // process all local sets
    for(int i = 0; i < nsets ; i++)
    {
        // get current set
        vtkDataSet *res_dset = NULL; // fetch each set from vtk output
        int         res_domid = -1;

        PyObject *py_dset  = PySequence_Fast_GET_ITEM(py_r_dsets,i);  // borrowed
        PyObject *py_domid = PySequence_Fast_GET_ITEM(py_r_domids,i); // borrowed
        
        if(py_dset == NULL)
            PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                         "Unable fetch result data set.");

        if(py_dset != Py_None) // allow 'None' as return
        {
            res_dset = (vtkDataSet*) pyEnv->UnwrapVTKObject(py_dset,"vtkDataSet");
            if(res_dset == NULL)
                PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                             "Error unwraping vtkDataSet result.");
             if(py_domid == NULL || PyInt_Check(py_domid) == 0)
                 PYEXPR_ERROR("avtPythonExpression::Execute Error - "
                              "Unable fetch result domain id.");
             res_domid = (int) PyInt_AsLong(py_domid);
        }
        
        res_dsets.push_back(res_dset);
        res_domids.push_back(res_domid);
    }
    
    // if we have no errors, register the datasets & create the output 
    // data tree
    for(int i = 0; i < nsets ; i++)
    {
        if(res_dsets[i]) // add result as new leaf
        {
            res_dsets[i]->Register(NULL);
            leaves[i] = new avtDataTree(res_dsets[i],res_domids[i]);
        }
        else // if the dataset only contained ghost zones we could end up here
            leaves[i] = NULL;
        
    }

    Py_DECREF(py_result_dsets);
    Py_DECREF(py_result_domids);
    Py_DECREF(py_r_dsets);
    Py_DECREF(py_r_domids);
    Py_DECREF(py_exe_res);

    // create output data tree
    avtDataTree_p result_tree = new avtDataTree(nsets,leaves);
    // set output data tree
    SetOutputDataTree(result_tree);

    // cleanup leaves array
    delete [] leaves;

}
Пример #19
0
void
avtMultiCurveFilter::Execute(void)
{
    //
    // Get the input data tree to obtain the data sets.
    //
    avtDataTree_p tree = GetInputDataTree();

    //
    // Get the data sets.
    //
    int nSets;
    vtkDataSet **dataSets = tree->GetAllLeaves(nSets);

    //
    // Get the domain ids.
    //
    std::vector<int> domains;
    tree->GetAllDomainIds(domains);

    //
    // If we have 1 data set then it is a rectilinear grid and this routine
    // will convert it to polydata, if we have more than one data set then
    // it is has already been converted to poly data and we will just pass
    // it along.
    //
    if (nSets < 1)
    {
        // Free the memory from the GetAllLeaves function call.
        delete [] dataSets;

        EXCEPTION1(ImproperUseException, "Expecting at least one dataset");
    }
    else if (nSets > 1)
    {
        for (int i = 0; i < nSets; i++)
        {
            if (dataSets[i]->GetDataObjectType() != VTK_POLY_DATA)
            {
                // Free the memory from the GetAllLeaves function call.
                delete [] dataSets;
                EXCEPTION1(ImproperUseException, "Expecting poly data");
            }
        }
        SetOutputDataTree(tree);
        setYAxisTickSpacing = false;

        // Free the memory from the GetAllLeaves function call.
        delete [] dataSets;
        return;
    }

    vtkDataSet *inDS = dataSets[0];
    // Free the memory from the GetAllLeaves function call.
    delete [] dataSets;

    int domain = domains[0];

    if (inDS->GetDataObjectType() != VTK_RECTILINEAR_GRID)
    {
        EXCEPTION1(ImproperUseException, "Expecting a rectilinear grid");
    }

    vtkRectilinearGrid *grid = vtkRectilinearGrid::SafeDownCast(inDS);
    if (grid->GetDataDimension() != 2)
    {
        EXCEPTION1(ImproperUseException, "Expecting a 2D grid");
    }

    int dims[3];
    grid->GetDimensions(dims);

    int nx = dims[0];
    int ny = dims[1];
    if (ny > 16)
    {
        avtCallback::IssueWarning("The MultiCurve plot only allows up to "
            "16 curves, displaying the first 16 curves.");
        ny = 16;
    }

    vtkDataArray *xpts = grid->GetXCoordinates();
    vtkDataArray *ypts = grid->GetYCoordinates();
    int ptype = VTK_FLOAT;
    if (xpts->GetDataType() == VTK_DOUBLE ||
        ypts->GetDataType() == VTK_DOUBLE)
        ptype = VTK_DOUBLE;

    vtkDataArray *var = inDS->GetPointData()->GetScalars();
    if (var == NULL)
    {
        EXCEPTION1(ImproperUseException, "No point data");
    }
    if (var->GetNumberOfComponents() != 1)
    {
        EXCEPTION1(ImproperUseException, "Expecting a scalar variable");
    }

    vtkDataArray *var2 = NULL;
    if (atts.GetMarkerVariable() != "default")
        var2 = inDS->GetPointData()->GetArray(atts.GetMarkerVariable().c_str());
    vtkDataArray *var3 = NULL;
    if (atts.GetIdVariable() != "default")
        var3 = inDS->GetPointData()->GetArray(atts.GetIdVariable().c_str());

    //
    // Create the data sets and labels for each of the curves.
    //
    vtkDataSet **out_ds = new vtkDataSet*[ny];
    std::vector<std::string> labels;

    //
    // Calculate the scale. If the user has specified the Y axis range use
    // that, otherwise use the range of the data.
    //
    double scale;
    double nTicks = floor(30./ny-1.);
    double tickSize = ny / 60.;
    if (atts.GetUseYAxisTickSpacing())
    {
        scale = tickSize / atts.GetYAxisTickSpacing();
        yAxisTickSpacing = atts.GetYAxisTickSpacing();
    }
    else
    {
        double yMin, yMax;
        if (var2 == NULL)
        {
            yMin = var->GetTuple1(0);
            yMax = var->GetTuple1(0);
            for (int i = 1; i < nx * ny; i++)
            {
                double v = var->GetTuple1(i);
                yMin = yMin < v ? yMin : v;
                yMax = yMax > v ? yMax : v;
            }
        }
        else
        {
            yMin = 1.;
            yMax = 1.;
            int i;
            for (i = 0; i < nx * ny && var2->GetTuple1(i) < 0.; i++)
                /* do nothing */;
            if (i < nx * ny)
            {
                yMin = var->GetTuple1(i);
                yMax = var->GetTuple1(i);
                for (; i < nx * ny; i++)
                {
                    if (var2->GetTuple1(i) >= 0.)
                    {
                        double v = var->GetTuple1(i);
                        yMin = yMin < v ? yMin : v;
                        yMax = yMax > v ? yMax : v;
                    }
                }
            }
        }
        double yAbsMax = fabs(yMin) > fabs(yMax) ? fabs(yMin) : fabs(yMax);
        scale = 1. / yAbsMax * nTicks * tickSize;
        yAxisTickSpacing = yAbsMax / nTicks;
    }
    setYAxisTickSpacing = true;

    stringVector inLabels;
    GetInput()->GetInfo().GetAttributes().GetLabels(inLabels);
    for (int i = 0; i < ny; i++)
    {
        //
        // Create the data set.
        //
        vtkPoints *points = vtkPoints::New(ptype);

        //
        // Create the array specifying the curve markers.
        //
        vtkIntArray *symbols = vtkIntArray::New();
        symbols->SetName("CurveSymbols");
        symbols->SetNumberOfComponents(1);
        symbols->SetNumberOfTuples(nx);
        int *sbuf = symbols->GetPointer(0);

        //
        // Create the array specifying the curve ids.
        //
        vtkIntArray *ids = vtkIntArray::New();
        ids->SetName("CurveIds");
        ids->SetNumberOfComponents(1);
        ids->SetNumberOfTuples(nx);
        int *ibuf = ids->GetPointer(0);

        double xLine[3];
        xLine[2] = 0.0;
        int npts = 0;
        for (int j = 0; j < nx; j++)
        {
            if (var2 == NULL || var2->GetTuple1(i*nx+j) >= 0.)
            {
                xLine[0] = xpts->GetTuple1(j);
                xLine[1] = (double)i + 0.5 + var->GetTuple1(i*nx+j) * scale;
                points->InsertNextPoint(xLine);

                // curve markers
                if (var2 == NULL)
                    sbuf[npts] = 0;
                else
                    sbuf[npts] = int(var2->GetTuple1(i*nx+j));

                // curve ids
                if (var3 == NULL)
                    ibuf[npts] = i*nx+j;
                else
                    ibuf[npts] = int(var3->GetTuple1(i*nx+j));

                npts++;
            }
        }

        vtkCellArray *lines = vtkCellArray::New();

        if (npts == 1)
        {
            vtkIdType vtkPointIDs[1];
            vtkPointIDs[0] = 0;
            lines->InsertNextCell(1, vtkPointIDs);
        }
        else if (npts > 1)
        {
            for (int j = 0; j < npts - 1; j++)
            {
                vtkIdType vtkPointIDs[2];
                vtkPointIDs[0] = j;
                vtkPointIDs[1] = j + 1;
                lines->InsertNextCell(2, vtkPointIDs);
            }
        }

        //
        // Create the data set.
        //
        vtkPolyData *polyData = vtkPolyData::New();

        polyData->SetLines(lines);
        polyData->SetPoints(points);
        polyData->GetPointData()->AddArray(symbols);
        polyData->GetPointData()->CopyFieldOn("CurveSymbols");
        polyData->GetPointData()->AddArray(ids);
        polyData->GetPointData()->CopyFieldOn("CurveIds");
        lines->Delete();
        points->Delete();
        symbols->Delete();
        ids->Delete();

        out_ds[i] = polyData;
    
        //
        // Create the label.
        //
        if(inLabels.size() != (size_t)ny)
        {
            char label[80];
        
            SNPRINTF(label, 80, atts.GetYAxisTitleFormat().c_str(), 
                     ypts->GetTuple1(i));
            labels.push_back(label);
        }
        else
            labels.push_back(inLabels[i]);
    }

    //
    // Turn the data sets into a data tree.
    //
    avtDataTree_p outDT = NULL;
    outDT = new avtDataTree(ny, out_ds, domain, labels);

    for (int i = 0; i < ny; i++)
    {
        out_ds[i]->Delete();
    }
    delete [] out_ds;

    //
    // Set the levels for the level mapper.
    //
    GetOutput()->GetInfo().GetAttributes().SetLabels(labels);

    SetOutputDataTree(outDT);
}
void
avtQueryOverTimeFilter::Execute(void)
{
    //
    // The real output will be created after all time steps have completed,
    // so create a dummy output to pass along for now.
    //
    avtDataTree_p dummy = new avtDataTree();

    //
    // Set up error conditions and return early if any processor had an
    // error upstream.
    //

    int hadError = 0;
    if (GetInput()->GetInfo().GetValidity().HasErrorOccurred())
    {
        errorMessage = GetInput()->GetInfo().GetValidity().GetErrorMessage();
        hadError = 1;
    }
    if (! ParallelizingOverTime())
        hadError = UnifyMaximumValue(hadError);
    if (hadError)
    {
        SetOutputDataTree(dummy);
        success = false;
        return;
    }

    //
    // Set up the query.
    //
    QueryAttributes qatts = atts.GetQueryAtts();
    qatts.SetTimeStep(currentTime);
    avtDataObjectQuery *query = avtQueryFactory::Instance()->
                                CreateQuery(&qatts);
    query->SetInput(GetInput());
    if (ParallelizingOverTime())
    {
        query->SetParallelizingOverTime(true);
    }

    if (strncmp(query->GetType(), "avtVariableByNodeQuery",22) == 0)
    {
        PickAttributes patts = atts.GetPickAtts();
        ((avtVariableByNodeQuery*)query)->SetPickAttsForTimeQuery(&patts);
    }
    else if (strncmp(query->GetType(), "avtVariableByZoneQuery",22) == 0)
    {
        PickAttributes patts = atts.GetPickAtts();
        ((avtVariableByZoneQuery*)query)->SetPickAttsForTimeQuery(&patts);
    }
    else if (strncmp(query->GetType(), "avtLocateAndPickZoneQuery",25) == 0)
    {
        PickAttributes patts = atts.GetPickAtts();
        ((avtLocateAndPickZoneQuery*)query)->SetPickAttsForTimeQuery(&patts);
    }
    else if (strncmp(query->GetType(), "avtLocateAndPickNodeQuery",25) == 0)
    {
        PickAttributes patts = atts.GetPickAtts();
        ((avtLocateAndPickNodeQuery*)query)->SetPickAttsForTimeQuery(&patts);
    }
    query->SetTimeVarying(true);
    query->SetSILRestriction(currentSILR);

    //
    // HokeyHack ... we want only 1 curve, so limit the
    // query to 1 variable to avoid unnecessary processing.
    //
    if (nResultsToStore==1)
    {
        stringVector useThisVar;
        useThisVar.push_back(qatts.GetVariables()[0]);
        qatts.SetVariables(useThisVar);
    }
    //
    // End HokeyHack.
    //

    TRY
    {
        query->PerformQuery(&qatts);
    }
    CATCHALL
    {
        SetOutputDataTree(dummy);
        success = false;
        delete query;
        RETHROW;
    }
    ENDTRY

    SetOutputDataTree(dummy);
    delete query;

    doubleVector results = qatts.GetResultsValue();
    if (results.size() == 0)
    {
        success = false;
        return;
    }
    else
    {
        success = true;
    }

    //
    // Store the necessary time value
    //
    if (useTimeForXAxis)
    {
        double tval;
        switch(atts.GetTimeType())
        {
        case QueryOverTimeAttributes::Cycle:
            tval = (double) GetInput()->GetInfo().GetAttributes().GetCycle();
            break;
        case QueryOverTimeAttributes::DTime:
            tval = GetInput()->GetInfo().GetAttributes().GetTime();
            break;
        case QueryOverTimeAttributes::Timestep:
        default: // timestep
            tval = (double)currentTime;
            break;
        }
        times.push_back(tval);
    }
    for (int i = 0; i < nResultsToStore; i++)
        qRes.push_back(results[i]);
}