Esempio n. 1
0
void
avtTraceHistoryFilter::Execute(void)
{
    //
    // Write out the connectivity.  "-1" is the hint to do that.
    //
    OutputTime(GetTypedInput(), -1);

    //
    // Pull out just the points.
    //
    avtDataset_p ds = InitializeDataset();

    //
    // Put the fields from the current time step on the points and then
    // output those fields.
    //
    PerformIteration(0, ds, false);
    OutputTime(ds, 0);

    //
    // Now iterate through the time slices, displacing and evaluating.
    //
    for (int i = 0 ; i < atts.GetNumiter() ; i++)
    {
        ds->SetSource(GetInput()->GetSource());
        PerformIteration(i, ds, true);
        OutputTime(ds, i+1);
    }

    // The operator just passes the data through.
    GetDataTree() = GetInputDataTree();
}
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);
}
bool
avtResampleFilter::InputNeedsNoResampling(void)
{
    avtDataTree_p inDT = GetInputDataTree();

    //
    // permit VTK_POLY_DATA to pass through unchanged
    //
#if 0
    int n = 0;
    vtkDataSet **in_dss = inDT->GetAllLeaves(n);
    if (n && in_dss && in_dss[0] && in_dss[0]->GetDataObjectType() == VTK_POLY_DATA)
    {
        // Free the memory from the GetAllLeaves function call.
        delete [] in_dss;

        return true;
    }

    // Free the memory from the GetAllLeaves function call.
    delete [] in_dss;
#endif

    return false;
}
void
avtDatasetToDataObjectFilter::PreExecute(void)
{
    avtFilter::PreExecute();

    // Here we check if the filter we are about to execute can
    // understand rectilinear grids with implied transforms set
    // in the data attributes.  If the filter can't, then we need
    // to apply the transform to the rectilinear grid, converting
    // it into a curvilinear grid.
    avtDataAttributes &inatts = GetInput()->GetInfo().GetAttributes();
    if (inatts.GetRectilinearGridHasTransform() &&
        !FilterUnderstandsTransformedRectMesh())
    {
        debug3 << "avtDatasetToDataObjectFilter transforming rectilinear grid"
               << " to curvilinear grid." << endl;
        avtDataTree_p tree = GetInputDataTree();
        bool dummy;
        tree->Traverse(CApplyTransformToRectGrid,
                       (void*)inatts.GetRectilinearGridTransform(), dummy);

        // since we transformed the input, we need to change the input
        // data attributes
        inatts.SetRectilinearGridHasTransform(false);

        // ... and if we already copied the input data atts to the output,
        // we need to also update the output data attributes
        avtDataAttributes &outatts = GetOutput()->GetInfo().GetAttributes();
        outatts.SetRectilinearGridHasTransform(false);
    }
}
Esempio n. 5
0
void 
avtLCSFilter::CreateNativeMeshIterativeCalcOutput(std::vector<avtIntegralCurve*> &ics)
{
    //accumulate all of the points then do jacobian?
    //or do jacobian then accumulate?
    //picking the first.

    int    offset = 0;
    double minv   =  std::numeric_limits<double>::max();
    double maxv   = -std::numeric_limits<double>::max();
    int    count  = 0;

    CreateMultiBlockIterativeCalcOutput(GetInputDataTree(), GetDataTree(),
                                        ics, offset, minv, maxv, count);

    int nTuples = (int) ics.size();

    if( 1 || 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);
    }

    avtDataAttributes &dataatts = GetOutput()->GetInfo().GetAttributes();
    avtExtents* e = dataatts.GetThisProcsActualDataExtents();

    double range[2];
    range[0] = minv;
    range[1] = maxv;
    e->Set(range);

    e = dataatts.GetThisProcsOriginalDataExtents();
    e->Set(range);

    e = dataatts.GetThisProcsActualSpatialExtents();
    e->Set(global_bounds);
    e = dataatts.GetThisProcsOriginalSpatialExtents();
    e->Set(global_bounds);
}
void
avtTimeIteratorDataTreeIteratorExpression::FinalizeOutput(void)
{
    avtDataTree_p tree = GetInputDataTree();
    arrayIndex = 0;
    avtDataTree_p rv = ConstructOutput(tree);
    SetOutputDataTree(rv);
}
void
avtDataTreeIteratorPreprocessor::Preprocess(void)
{
    avtDataTree_p tree = GetInputDataTree();
    int totalNodes = tree->GetNumberOfLeaves();

    debug3 << "Preprocessing with " << totalNodes << " nodes." << endl;
    Initialize(totalNodes);

    debug3 << "Preprocessing the top level tree" << endl;
    PreprocessTree(tree);

    debug3 << "Allowing preprocessing module to finalize." << endl;
    Finalize();
}
void
avtDatasetQuery::PerformQuery(QueryAttributes *qA)
{
    queryAtts = *qA;

    Init(); 

    UpdateProgress(0, 0);
    //
    // Allow derived types to apply any necessary filters.
    //
    avtDataObject_p dob = ApplyFilters(GetInput());

    //
    // Reset the input so that we have access to the data tree. 
    //
    SetTypedInput(dob);

    avtDataTree_p tree = GetInputDataTree();
    int validInputTree = 0;
    
    if (*tree != NULL && !tree->IsEmpty())
    {
        validInputTree = 1;
        totalNodes = tree->GetNumberOfLeaves();
    }
    else 
    {
        validInputTree |= 0;
        totalNodes = 0;
        debug4 << "Query encountered EMPTY InputDataTree after ApplyFilters.  "
               << "This may be a valid state if running parallel and there "
               << "are more processors than domains." << endl;
    }

    bool hadError = false;
    PreExecute();
    TRY
    {
        Execute(tree);
    }
    CATCH2(VisItException, e)
    {
        debug1 << "Exception occurred in " << GetType() << endl;
        debug1 << "Going to keep going to prevent a parallel hang." << endl;
        queryAtts.SetResultsMessage(e.Message());
        hadError = true;
    }
Esempio n. 9
0
avtDataset_p
avtTraceHistoryFilter::InitializeDataset(void)
{
    int  i, j;

    avtDataTree_p inTree = GetInputDataTree();
    int nLeaves;
    vtkDataSet **ds = inTree->GetAllLeaves(nLeaves);
    vtkDataSet **ugrids = new vtkDataSet*[nLeaves];
    for (i = 0 ; i < nLeaves ; i++)
    {
        vtkPoints *pts = vtkVisItUtility::GetPoints(ds[i]);

        vtkUnstructuredGrid *ugrid = vtkUnstructuredGrid::New();
        ugrid->SetPoints(pts);
        int npts = pts->GetNumberOfPoints();
        ugrid->Allocate(2*npts);
        vtkIdType onevertex[1];
        for (j = 0 ; j < npts ; j++)
        {
             onevertex[0] = j;
             ugrid->InsertNextCell(VTK_VERTEX, 1, onevertex);
        }
        ugrids[i] = ugrid;

        pts->Delete();
    }

    avtDataTree_p newTree = new avtDataTree(nLeaves, ugrids, -1);
    for (i = 0 ; i < nLeaves ; i++)
        ugrids[i]->Delete();
    delete [] ugrids;

    avtDataset_p rv = new avtDataset(GetTypedInput(), newTree);
    avtDataAttributes &atts = rv->GetInfo().GetAttributes();
    int nVars = atts.GetNumberOfVariables();
    while (nVars > 0)
    {
        atts.RemoveVariable(atts.GetVariableName(0));
        nVars = atts.GetNumberOfVariables();
    }

    // Free the memory from the GetAllLeaves function call.
    delete [] ds;

    return rv;
}
void
avtDatasetToDataObjectFilter::InputSetActiveVariable(const char *varname)
{
    SetActiveVariableArgs args;
    args.varname = varname;
    avtDataTree_p tree = GetInputDataTree();
    bool success;
    tree->Traverse(CSetActiveVariable, (void *) &args, success);

    //
    // Set up our data members for derived types that need this information.
    //
    activeVariableIsPointData = args.activeIsPoint;
    hasPointVars              = args.hasPointVars;
    hasCellVars               = args.hasCellVars;

    GetInput()->GetInfo().GetAttributes().SetActiveVariable(varname);
}
Esempio n. 11
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
avtTimeIteratorDataTreeIteratorExpression::InitializeOutput(void)
{
    avtDataTree_p topTree = GetInputDataTree();
    std::vector<avtDataTree_p> treesToProcess;
    treesToProcess.push_back(topTree);
    size_t curIndex = 0;
    vars.clear();
    while (curIndex < treesToProcess.size())
    {
        avtDataTree_p tree = treesToProcess[curIndex];
        curIndex++;
        if (*tree == NULL)
            continue;

        int nc = tree->GetNChildren();
        if (nc <= 0 && !tree->HasData())
            continue;

        if (nc == 0)
        {
            vtkDataSet *in_ds = tree->GetDataRepresentation().GetDataVTK();
            vtkDoubleArray *arr = vtkDoubleArray::New();
            arr->SetNumberOfComponents(GetIntermediateSize());
            if (IsPointVariable())
                arr->SetNumberOfTuples(in_ds->GetNumberOfPoints());
            else
                arr->SetNumberOfTuples(in_ds->GetNumberOfCells());
            arr->SetName(outputVariableName);
            vars.push_back(arr);
        }
        else
        {
            for (int j = 0; j < nc; j++)
                if (tree->ChildIsPresent(j))
                    treesToProcess.push_back(tree->GetChild(j));
        }
    }
    
    // Set up this counter variable that we use during "ProcessDataTree".
    arrayIndex = 0;
}
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;
}
Esempio n. 14
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);
}
Esempio n. 15
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;
}
vtkDataSet *
avtDatasetOnDemandFilter::GetDataAroundPoint(double X, double Y, double Z,
                                             int timeStep)
{
    if (DebugStream::Level1()) 
    {
        debug1<<"avtDatasetOnDemandFilter::GetDataAroundPoint("<<X<<", "<<Y<<", "<<Z<<", "<<timeStep<<");"<<endl;
    }
    if ( ! OperatingOnDemand() )
    {
        EXCEPTION0(ImproperUseException);
    }

    int domainId = 0; //Need to hash XYZ to domainId ???
    // FIXME: For the moment we just use one domain ID (0) for all points. This choice will cause
    // the following for loop to test *all* cache entries whether they contain the point location.
    // This strategy is not very efficient, but better than a pipeline re-execute.

    if (DebugStream::Level5())
    {
        debug5<<"Look in cache: "<<domainId<<" sz= "<<domainQueue.size()<<endl;
    }
    //See if it's in the cache.
    std::list<DomainCacheEntry>::iterator it;
    int foundPos = 0;
    for ( it = domainQueue.begin(); it != domainQueue.end(); it++ )
    {
        // Found it. Move it to the front of the list.
        if (it->domainID == domainId &&
            it->timeStep == timeStep)
        {
            //Do a bbox check.
            double bbox[6];
            it->ds->GetBounds(bbox);
            if (DebugStream::Level5()) 
            {
                debug5<<"BBOX ["<<bbox[0]<<", "<<bbox[1]<<"]["<<bbox[2]<<", "<<bbox[3]<<"]["<<bbox[4]<<", "<<bbox[5]<<"]"<<endl;
            }
            if (! (X >= bbox[0] && X <= bbox[1] &&
                   Y >= bbox[2] && Y <= bbox[3] &&
                   Z >= bbox[4] && Z <= bbox[5]))
                continue;
            
            bool foundIt = false;
            
            // If rectilinear, we found the domain.
            if (it->ds->GetDataObjectType() == VTK_RECTILINEAR_GRID)
                foundIt = true;
            else
            {
                //Do a cell check....
                if (DebugStream::Level5())
                {
                    debug5<<"It's in the bbox. Check the cell.\n";
                }
                vtkVisItCellLocator *cellLocator = it->cl;
                if ( cellLocator == NULL )
                {
                    cellLocator = vtkVisItCellLocator::New();
                    cellLocator->SetDataSet(it->ds);
                    cellLocator->IgnoreGhostsOn();
                    cellLocator->BuildLocator();
                    it->cl = cellLocator;
                }
                
                double rad = 1e-6, dist=0.0;
                double p[3] = {X,Y,Z}, resPt[3]={0.0,0.0,0.0};
                vtkIdType foundCell = -1;
                int subId = 0;

                if (cellLocator->FindClosestPointWithinRadius(p, rad, resPt,
                                                              foundCell, subId, dist))
                {
                    foundIt = true;
                    if (DebugStream::Level5())
                    {
                        debug5<<"Cell locate: We found the domain!\n";
                    }
                }
            }

            if (foundIt)
            {
                if (DebugStream::Level5())
                {
                    debug5<<"Found data in cace, returning cache entry " << foundPos << std::endl;
                }
                DomainCacheEntry entry;
                entry = *it;

                //Remove, then move to front.
                domainQueue.erase( it );
                domainQueue.push_front( entry );
                return entry.ds;
            }
        }
    }

    if (DebugStream::Level5())
    {
        debug5<<"     Update->GetDataAroundPoint, time= "<<timeStep<<endl;
    }
    avtContract_p new_contract = new avtContract(firstContract);
    new_contract->GetDataRequest()->GetRestriction()->TurnOnAll();
    avtPointSelection *ptsel = new avtPointSelection;
    double p[3] = { X, Y, Z };
    ptsel->SetPoint(p);

    // data selection will be deleted by contract.
    new_contract->GetDataRequest()->AddDataSelection(ptsel);

    new_contract->GetDataRequest()->SetTimestep(timeStep);
    new_contract->SetOnDemandStreaming(true);

    GetInput()->Update(new_contract);
    vtkDataSet *rv = GetInputDataTree()->GetSingleLeaf();

    if( rv )
    {
        // Add it to the cache.
        DomainCacheEntry entry;
        entry.domainID = domainId;
        entry.timeStep = timeStep;
        entry.ds = rv;
        entry.cl = NULL;
        rv->Register(NULL);
        loadDSCount++;

        domainQueue.push_front(entry);
        if ( domainQueue.size() > (size_t)maxQueueLength )
        {
            DomainCacheEntry tmp = domainQueue.back();
            PurgeDomain( tmp.domainID, tmp.timeStep );
            domainQueue.pop_back();
            purgeDSCount++;
        }
    }

    return rv;
}
vtkDataSet *
avtDatasetOnDemandFilter::GetDomain(int domainId,
                                    int timeStep)
{
    if (DebugStream::Level5())
    {
        debug5<<"avtDatasetOnDemandFilter::GetDomain("<<domainId<<", "<<timeStep<<");"<<endl;
    }
    if ( ! OperatingOnDemand() )
        EXCEPTION0(ImproperUseException);

    if ( domainId < 0 )
        return NULL;

    // See if it is already in the cache.  If so, just return it.
    std::list<DomainCacheEntry>::iterator it;
    for ( it = domainQueue.begin(); it != domainQueue.end(); it++ )
    {
        // Found it. Move it to the front of the list.
        if (it->domainID == domainId &&
            it->timeStep == timeStep)
        {
            DomainCacheEntry entry;
            entry = *it;
            //Remove, then move to front.
            domainQueue.erase( it );
            domainQueue.push_front( entry );
            return entry.ds;
        }
    }

    avtSILRestriction_p silr;
    if (timeStep == firstContract->GetDataRequest()->GetTimestep())
    {
        silr = firstContract->GetDataRequest()->GetRestriction();
    }
    else if ((*lastUsedContract != NULL) && 
             (timeStep == lastUsedContract->GetDataRequest()->GetTimestep()))
    {
        silr = lastUsedContract->GetDataRequest()->GetRestriction();
    }
    else
    {
        // The SIL restriction associated with the contract may be for the wrong
        // time step.  Go get the correct one.
        std::string db = GetInput()->GetInfo().GetAttributes().GetFullDBName();
        ref_ptr<avtDatabase> dbp = avtCallback::GetDatabase(db, 0, NULL);
        if (*dbp == NULL)
            EXCEPTION1(InvalidFilesException, db.c_str());

        std::string mesh = GetInput()->GetInfo().GetAttributes().GetMeshname();
        avtDataObject_p dob = dbp->GetOutput(mesh.c_str(), timeStep);
        lastUsedContract = dob->GetOriginatingSource()->GetGeneralContract();
        silr = lastUsedContract->GetDataRequest()->GetRestriction();
   }

    avtDataRequest_p new_dr = new avtDataRequest(firstContract->GetDataRequest(), silr);
    avtContract_p new_contract = new avtContract(firstContract, new_dr);

    if (DebugStream::Level5())
    {
        debug5<<"     Update->GetDomain "<<domainId<<" time= "<<timeStep<<endl;
    }
    std::vector<int> domains;
    domains.push_back(domainId);
    new_contract->GetDataRequest()->GetRestriction()->TurnOnAll();
    new_contract->GetDataRequest()->GetRestriction()->RestrictDomains(domains);
    new_contract->GetDataRequest()->SetTimestep(timeStep);
    new_contract->SetOnDemandStreaming(true);

    GetInput()->Update(new_contract);
    vtkDataSet *rv = GetInputDataTree()->GetSingleLeaf();
    if (rv == NULL)
    {
        // This issue has been known to occur when: 
        //  -- the SIL is time varying
        //  -- the domain requested doesn't exist for the initial time step
        //     (which is the one where the SIL is created from).
        EXCEPTION1(VisItException, "Failure retrieving a data set while "
                     "advecting particles.  Please report this to a VisIt "
                     "developer.");
    }

    // Add it to the cache.
    DomainCacheEntry entry;
    entry.domainID = domainId;
    entry.timeStep = timeStep;
    entry.ds = rv;
    rv->Register(NULL);
    loadDSCount++;

    //Update the domainLoadCount.
    //Turn two ints into a long. Put timeStep in upper, domain in lower.
    unsigned long long A =  (((unsigned long long)timeStep)<<32);
    unsigned long long B =  ((unsigned long long)domainId);
    unsigned long long idx = A | B;

    if (domainLoadCount.find(idx) == domainLoadCount.end())
    {
        domainLoadCount[idx] = 1;
    }
    else
    {
        domainLoadCount[idx] ++;
    }

    domainQueue.push_front(entry);
    if ( domainQueue.size() > (size_t)maxQueueLength )
    {
        DomainCacheEntry tmp = domainQueue.back();
        PurgeDomain( tmp.domainID, tmp.timeStep );
        domainQueue.pop_back();
        purgeDSCount++;
    }

    return rv;
}
Esempio n. 18
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
avtDatasetToVTKDatasetFilter::Execute(avtDomainList *dl)
{
    int   i;

    //
    // We previously set the dataset that was naturally the output of the
    // append filter as the output of the bridge.  Because VTK does not want
    // to have two objects share that output, it has code under the covers
    // that removes the dataset as output from the append filter.  Restore
    // that now.
    //
    appendFilter->SetOutput(bridge->GetOutput());

    //
    // Remove all of the inputs from the appender.  Count down so there are
    // no issues with the array being squeezed and indices changing.
    //
    int numInputs = appendFilter->GetNumberOfInputs();
    for (i = numInputs-1 ; i >= 0 ; i--)
    {
        vtkDataSet *ds = appendFilter->GetInput(i);
        if (ds != NULL)
        {
            appendFilter->RemoveInput(ds);
        }
    }

    //
    // Set the input to the appender to fit with the domain list.
    //
    
    avtDataTree_p tree = GetInputDataTree();
    int nc = tree->GetNChildren();
    int nd = dl->NumDomains();
    if (nd != nc)
    {
        EXCEPTION2(IncompatibleDomainListsException, nd, nc);
    }

    for (i = 0 ; i < dl->NumDomains() ; i++)
    {
        if (dl->Domain(i) && tree->ChildIsPresent(i))
        {
            bool dummy;
            tree->GetChild(i)->Traverse(CAddInputToAppendFilter, 
                                        appendFilter, dummy);
        }
    }

    //
    // Force an execution of the append filter.  We set all of the input to its
    // inputs as NULL, so we don't have to worry about it trying to go back up
    // the (most certainly defunct) pipeline.
    //
    appendFilter->Update();

    //
    // The output of the bridge and the append filter is shared.  Give it back
    // to the bridge, so our pipeline will work properly.
    //
    bridge->SetOutput(appendFilter->GetOutput());
}
void
avtTimeLoopCollectorFilter::Execute()
{
    trees.push_back(GetInputDataTree());
}
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;

}
vtkDataSet *
avtDatasetOnDemandFilter::GetDomain(int domainId,
                                    int timeStep)
{
    debug5<<"avtDatasetOnDemandFilter::GetDomain("<<domainId<<", "<<timeStep<<");"<<endl;
    if ( ! OperatingOnDemand() )
        EXCEPTION0(ImproperUseException);

    if ( domainId < 0 )
        return NULL;

    // See if it is already in the cache.  If so, just return it.
    std::list<DomainCacheEntry>::iterator it;
    for ( it = domainQueue.begin(); it != domainQueue.end(); it++ )
        // Found it. Move it to the front of the list.
        if (it->domainID == domainId &&
            it->timeStep == timeStep)
        {
            DomainCacheEntry entry;
            entry = *it;
            //Remove, then move to front.
            domainQueue.erase( it );
            domainQueue.push_front( entry );
            return entry.ds;
        }


    debug5<<"     Update->GetDomain "<<domainId<<" time= "<<timeStep<<endl;
    avtContract_p new_contract = new avtContract(firstContract);
    vector<int> domains;
    domains.push_back(domainId);
    new_contract->GetDataRequest()->GetRestriction()->TurnOnAll();
    new_contract->GetDataRequest()->GetRestriction()->RestrictDomains(domains);
    if (timeStep >= 0)
        new_contract->GetDataRequest()->SetTimestep(timeStep);
    new_contract->SetOnDemandStreaming(true);

    GetInput()->Update(new_contract);
    vtkDataSet *rv = GetInputDataTree()->GetSingleLeaf();

    // Add it to the cache.
    DomainCacheEntry entry;
    entry.domainID = domainId;
    entry.timeStep = timeStep;
    entry.ds = rv;
    rv->Register(NULL);
    loadDSCount++;

    //Update the domainLoadCount.
    //Turn two ints into a long. Put timeStep in upper, domain in lower.
    unsigned long long A =  (((unsigned long long)timeStep)<<32);
    unsigned long long B =  ((unsigned long long)domainId);
    unsigned long long idx = A | B;

    if (domainLoadCount.find(idx) == domainLoadCount.end())
        domainLoadCount[idx] = 0;
    domainLoadCount[idx] ++;

    domainQueue.push_front(entry);
    if ( domainQueue.size() > maxQueueLength )
    {
        domainQueue.pop_back();
        purgeDSCount++;
    }

    return rv;
}
void
avtActualExtentsFilter::Execute(void)
{
    UpdateExtents();
    SetOutputDataTree(GetInputDataTree());
}
void
avtResampleFilter::BypassResample(void)
{
    SetOutputDataTree(GetInputDataTree());
}