void
avtTraceExpression::DoOperation(vtkDataArray *in, vtkDataArray *out,
                          int ncomponents, int ntuples)
{
    if (ncomponents == 9)
    {
        for (int i = 0 ; i < ntuples ; i++)
        {
            double val1 = in->GetComponent(i, 0);
            double val2 = in->GetComponent(i, 4);
            double val3 = in->GetComponent(i, 8);
            out->SetTuple1(i, val1+val2+val3);
        }
    }
    else
    {
        EXCEPTION2(ExpressionException, outputVariableName, "Cannot take trace of non-tensor.");
    }
}
void
avtArraySumExpression::ProcessArguments(ArgsExpr *args, 
                                          ExprPipelineState *state)
{
    // Check the number of arguments
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    int nargs = arguments->size();
    if (nargs != 1)
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
                        "this expression must be specified with exactly one "
                        "arguments.  Usage: array_sum(array)");
    }

    // Tell the first argument to create its filters.
    ArgExpr *firstarg = (*arguments)[0];
    avtExprNode *firstTree = dynamic_cast<avtExprNode*>(firstarg->GetExpr());
    firstTree->CreateFilters(state);
}
void
VisWinTools::SetToolEnabled(int i, bool val)
{
    if(i < 0 || i > numTools)
        EXCEPTION2(BadIndexException, 0, numTools);

    if(val)
        tools[i]->Enable();
    else
    {
        if (toolProxy.GetToolUpdateMode() == UPDATE_ONCLOSE)
            tools[i]->CallCallback();
        tools[i]->Disable();
    }

    UpdateHighlight();
    toolProxy.RecalculateRenderOrder();
    toolProxy.Render();
}
void
avtEigenvalueExpression::DoOperation(vtkDataArray *in, vtkDataArray *out,
                                     int ncomponents, int ntuples)
{
    if (ncomponents == 9)
    {
        for (int i = 0 ; i < ntuples ; i++)
        {
            double *vals = in->GetTuple9(i);
            double *input[3];
            double row1[3];
            double row2[3];
            double row3[3];
            input[0] = row1;
            input[1] = row2;
            input[2] = row3;
            input[0][0] = vals[0];
            input[0][1] = vals[1];
            input[0][2] = vals[2];
            input[1][0] = vals[3];
            input[1][1] = vals[4];
            input[1][2] = vals[5];
            input[2][0] = vals[6];
            input[2][1] = vals[7];
            input[2][2] = vals[8];
            double *eigenvecs[3];
            double outrow1[3];
            double outrow2[3];
            double outrow3[3];
            eigenvecs[0] = outrow1;
            eigenvecs[1] = outrow2;
            eigenvecs[2] = outrow3;
            double eigenvals[3];
            vtkMath::Jacobi(input, eigenvals, eigenvecs);
            out->SetTuple(i, eigenvals);
        }
    }
    else
    {
        EXCEPTION2(ExpressionException, outputVariableName, "Cannot determine tensor type");
    }
}
void
avtLogicalAndExpression::DoOperation(vtkDataArray *in1, vtkDataArray *in2,
                                 vtkDataArray *out, int ncomponents,
                                 int ntuples)
{
    int in1ncomps = in1->GetNumberOfComponents();
    int in2ncomps = in2->GetNumberOfComponents();
    if (in1ncomps != 1 || in2ncomps != 1)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "Cannot logically and vector variables.");
    }

    for (int i = 0 ; i < ntuples ; i++)
    {
        bool val1, val2;

        if (in1->GetDataType() == VTK_UNSIGNED_CHAR)
        {
            val1 = (unsigned char) in1->GetTuple1(i);
        }
        else
        {
            val1 = (in1->GetTuple1(i) != 0. ? true : false);
        }

        if (in2->GetDataType() == VTK_UNSIGNED_CHAR)
        {
            val2 = (unsigned char) in2->GetTuple1(i);
        }
        else
        {
            val2 = (in2->GetTuple1(i) != 0. ? true : false);
        }

        unsigned char outval = val1 && val2;
        out->SetTuple1(i, outval);
    }
}
avtContract_p
avtApplyDataBinningExpression::ModifyContract(avtContract_p spec)
{
    if (theDataBinning == NULL)
    {
        // We should have failed before getting to this point...
        EXCEPTION2(ExpressionException, outputVariableName, 
                   "Could not locate the data binning.");
    }

    avtDataRequest_p ds = spec->GetDataRequest();
    avtDataRequest_p new_ds = new avtDataRequest(ds);
    avtDataBinningFunctionInfo *info = theDataBinning->GetFunctionInfo();
    int nVars = info->GetDomainNumberOfTuples();
    for (int i = 0 ; i < nVars ; i++)
        new_ds->AddSecondaryVariable(info->GetDomainTupleName(i).c_str());
    new_ds->AddSecondaryVariable(info->GetCodomainName().c_str());

    avtContract_p rv = new avtContract(spec, new_ds);
    rv = avtSingleInputExpressionFilter::ModifyContract(rv);
    return rv;
}
void
avtMinMaxExpression::DoOperation(vtkDataArray *in1, vtkDataArray *in2,
                                vtkDataArray *out, int ncomponents,int ntuples)
{
    bool var1IsSingleton = (in1->GetNumberOfTuples() == 1);
    bool var2IsSingleton = (in2->GetNumberOfTuples() == 1);

    int in1ncomps = in1->GetNumberOfComponents();
    int in2ncomps = in2->GetNumberOfComponents();
    if (in1ncomps == in2ncomps)
    {
        for (int i = 0 ; i < ntuples ; i++)
        {
            for (int j = 0 ; j < in1ncomps ; j++)
            {
                int tup1 = (var1IsSingleton ? 0 : i);
                int tup2 = (var2IsSingleton ? 0 : i);
                double val1 = in1->GetComponent(tup1, j);
                double val2 = in2->GetComponent(tup2, j);
                bool val1Bigger = (val1 > val2);
                // Circumflex (^) is the exclusive or.
                // doMin == true  && val1Bigger == true  --> val2
                // doMin == false && val1Bigger == true  --> val1
                // doMin == true  && val1Bigger == false --> val1
                // doMin == false && val1Bigger == false --> val2
                //  --> values same, then val2, values different, then val1
                double outval = (doMin ^ val1Bigger ? val1 : val2);
                out->SetComponent(i, j, outval);
            }
        }
    }
    else
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
                         "Don't know how to take minimums or "
                         "maximums with data of differing dimensions.");
    }
}
void
avtRelativeDifferenceExpression::DoOperation(vtkDataArray *in1, 
    vtkDataArray *in2, vtkDataArray *out, int ncomponents,int ntuples)
{
    vtkIdType in1ncomps = in1->GetNumberOfComponents();
    vtkIdType in2ncomps = in2->GetNumberOfComponents();
    if (in1ncomps != 1 || in2ncomps != 1)
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
            "Can only take relative difference of scalars.");
    }

    vtkIdType ntups = out->GetNumberOfTuples();
    for (vtkIdType i = 0 ; i < ntups ; i++)
    {
        double val1 = in1->GetComponent(i, 0);
        double val2 = in2->GetComponent(i, 0);
        double outval = 0.;
        if (val1 != 0. || val2 != 0.)
            outval = (val1-val2) / (fabs(val1) + fabs(val2));
        out->SetComponent(i, 0, outval);
    }
}
void
avtTestGreaterThanOrEqualToExpression::DoOperation(vtkDataArray *in1, 
    vtkDataArray *in2, vtkDataArray *out, int ncomponents, int ntuples)
{
    bool var1IsSingleton = (in1->GetNumberOfTuples() == 1);
    bool var2IsSingleton = (in2->GetNumberOfTuples() == 1);
    int in1ncomps = in1->GetNumberOfComponents();
    int in2ncomps = in2->GetNumberOfComponents();
    if (in1ncomps != 1 || in2ncomps != 1)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "Cannot compare vector variables.");
    }

    for (int i = 0 ; i < ntuples ; i++)
    {
        int tup1 = (var1IsSingleton ? 0 : i);
        int tup2 = (var2IsSingleton ? 0 : i);
        unsigned char outval = (in1->GetTuple1(tup1) >= in2->GetTuple1(tup2)
                                ? '\1' : '\0');
        out->SetTuple1(i, outval);
    }
}
void
avtMultiCurveLabelMapper::GetLevelColor(const int levelNum, double col[4])
{
    int nc = cal.GetNumColors();
    if (nc == 1)  // constant color for all levels
    {
        col[0] = cal[0].Red()   * INV_255;
        col[1] = cal[0].Green() * INV_255;
        col[2] = cal[0].Blue()  * INV_255;
        col[3] = cal[0].Alpha() * INV_255;
        return;
    }

    if (levelNum < 0 || levelNum >= nc)
    {
        EXCEPTION2(BadIndexException, levelNum, nc);
    }

    col[0] = cal[levelNum].Red()   * INV_255;
    col[1] = cal[levelNum].Green() * INV_255;
    col[2] = cal[levelNum].Blue()  * INV_255;
    col[3] = cal[levelNum].Alpha() * INV_255;
}
void
avtTimeIteratorExpression::AddInputVariableName(const char *v)
{
    if (varnames.size() < NumberOfVariables())
        varnames.push_back(v);
    else
    {
        if (varnames.size() == NumberOfVariables() && cmfeType == POS_CMFE)
        {
            // Need to remove quotes around the variable (if any), since that 
            // won't be parsed well.
            std::string var_wo_quotes = std::string(v);
            for (int j = var_wo_quotes.size()-1 ; j >= 0 ; j--)
                if (var_wo_quotes[j] == '\'')
                    var_wo_quotes.replace(j,1,"");
            varnames.push_back(var_wo_quotes);
        }
        else
        {
            EXCEPTION2(ExpressionException, outputVariableName,
                   "An internal error occurred.");
        }
    }
}
void
avtVariableSkewExpression::DoOperation(vtkDataArray *in1, vtkDataArray *in2,
                                   vtkDataArray *out, int ncomponents, 
                                   int ntuples)
{
    vtkIdType in1ncomps = in1->GetNumberOfComponents();
    vtkIdType in2ncomps = in2->GetNumberOfComponents();
    if (in1ncomps == 1 && in2ncomps == 1)
    {
        double *r = in1->GetRange();
        for (int i = 0 ; i < ntuples ; i++)
        {
            double val1 = in1->GetComponent(i, 0);
            double val2 = in2->GetComponent(i, 0);
            double f = vtkSkewValue(val1, r[0], r[1], val2);
            out->SetComponent(i, 0, f);
        }
    }
    else
    {
        EXCEPTION2(ExpressionException, outputVariableName, "Skew can only be "
                   "used on scalar variables.");
    }
}
void
avtMultiCurveLabelMapper::SetDatasetInput(vtkDataSet *ds, int inNum)
{
    if (ds == NULL || ds->GetNumberOfPoints() == 0 ||
        ds->GetNumberOfCells() == 0)
    {
        return;
    }

    if (inNum < 0)
    {
        EXCEPTION2(BadIndexException, inNum, 10);
    }

    double col[4];
    GetLevelColor(inNum, col);

    vtkIntArray *intArray = vtkIntArray::SafeDownCast(
        ds->GetPointData()->GetArray("CurveSymbols"));
    int *buf = (intArray == NULL) ? NULL : intArray->GetPointer(0);

    vtkIntArray *intArray2 = vtkIntArray::SafeDownCast(
        ds->GetPointData()->GetArray("CurveIds"));
    int *buf2 = (intArray2 == NULL) ? NULL : intArray2->GetPointer(0);

    //
    // If the number of points is greater than 500, then don't create the
    // markers and ids since the performance is so slow when the number of
    // actors is too large.
    //
    if (ds->GetNumberOfPoints() > 500)
        return;

    double    pos[3];        
    for (vtkIdType i = 0; i < ds->GetNumberOfPoints(); i++)
    {
        // Add the marker.
        avtLabelActor_p la = new avtLabelActor;
        ds->GetPoint(i, pos);
        la->SetAttachmentPoint(pos);
        if (buf != NULL)
            la->SetMarker(buf[i]);
        else
            la->SetMarker(2);
        la->SetScaleFactor(scale);
        la->SetLineWidth(LineWidth2Int(markerLineWidth));
        la->SetForegroundColor(col[0], col[1], col[2], col[3]);
        actors.push_back(la);
        colors.push_back(inNum);

        // Add the id.
        la = new avtLabelActor;
        ds->GetPoint(i, pos);
        la->SetAttachmentPoint(pos);
        char label[16];
        if (buf2 != NULL)
            if (buf2[i] != INT_MIN)
                sprintf(label, "%d", buf2[i]);
            else
                strcpy(label, "");
        else
            sprintf(label, "%lld", i);
        la->SetDesignator(label);
        la->SetScaleFactor(scale);
        la->SetForegroundColor(col[0], col[1], col[2], col[3]);
        actors.push_back(la);
        colors.push_back(inNum);
    }
}
// ****************************************************************************
//  Method: avtRecenterExpression::ProcessArguments
//
//  Purpose:
//      Parses optional centering argument.
//
//  Arguments:
//      args      Expression arguments
//      state     Expression pipeline state
//
//  Programmer:   Sean Ahern
//  Creation:     Wed Sep 10 12:04:12 EDT 2008
//
// ****************************************************************************
void
avtRecenterExpression::ProcessArguments(ArgsExpr *args,
                                        ExprPipelineState *state)
{
    // Get the argument list and number of arguments.
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    int nargs = arguments->size();

    // Check for a call with no arguments.
    if (nargs == 0)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "recenter(): Incorrect syntax.\n"
                   " usage: recenter(varname, [centering])\n"
                   " The centering parameter is optional "
                   " and specifies nodal or zonal centering.\n"
                   " Valid values of centering: \"nodal\", \"zonal\", and \"toggle\".\n"
                   " The default centering is to toggle, that is, to convert "
                   " nodal to zonal or zonal to nodal.");
    }

    // Grab off the first argument.
    ArgExpr *firstArg = (*arguments)[0];
    avtExprNode *firstTree = dynamic_cast<avtExprNode*>(firstArg->GetExpr());
    firstTree->CreateFilters(state);

    // Check if we have a second optional argument that tells us how to
    // center.
    //
    // Options:
    //  nodal:  Recenter to nodes
    //  zonal:  Recenter to zones
    //  toggle: Toggle centering
    // Default: toggle

    if (nargs > 1)
    {
        ArgExpr *secondArg = (*arguments)[1];
        ExprParseTreeNode *secondTree = secondArg->GetExpr();
        std::string secondType = secondTree->GetTypeName();

        // Check for argument passed as string
        if (secondType == "StringConst")
        {
            std::string sval = dynamic_cast<StringConstExpr*>(secondTree)->GetValue();

            if (sval == "toggle")
                recenterMode = Toggle;
            else if (sval == "nodal")
                recenterMode = Nodal;
            else if (sval == "zonal")
                recenterMode = Zonal;
            else
            {
                EXCEPTION2(ExpressionException, outputVariableName,
                           "avtRecenterExpression: Invalid second argument.\n"
                           " Valid options are: \"nodal\", \"zonal\", or \"toggle\".");
            }
        }
        else    // Invalid argument type
        {
            EXCEPTION2(ExpressionException, outputVariableName,
                       "avtRecenterExpression: Invalid second argument type.\n"
                       "Must be a string with one of: \"nodal\", \"zonal\", \"toggle\".");
        }
    }
}
vtkDataArray *
avtUnaryMathExpression::DeriveVariable(vtkDataSet *in_ds, int currentDomainsIndex)
{
    int  i;

    vtkDataArray *cell_data = NULL;
    vtkDataArray *point_data = NULL;
    vtkDataArray *data = NULL;

    if (activeVariable == NULL)
    {
        //
        // This hack is getting more and more refined.  This situation comes up
        // when we don't know what the active variable is (mostly for the
        // constant creation filter).  We probably need more infrastructure
        // to handle this.
        // Iteration 1 of this hack said take any array.
        // Iteration 2 said take any array that isn't vtkGhostLevels, etc.
        // Iteration 3 says take the first scalar array if one is available,
        //             provided that array is not vtkGhostLevels, etc.
        //             This is because most constants we create are scalar.
        //
        // Note: this hack used to be quite important because we would use
        // the resulting array to determine the centering of the variable.
        // Now we use the IsPointVariable() method.  So this data array is
        // only used to get the type.
        //
        int ncellArray = in_ds->GetCellData()->GetNumberOfArrays();
        for (i = 0 ; i < ncellArray ; i++)
        {
            vtkDataArray *candidate = in_ds->GetCellData()->GetArray(i);
            if (strstr(candidate->GetName(), "vtk") != NULL)
                continue;
            if (strstr(candidate->GetName(), "avt") != NULL)
                continue;
            if (candidate->GetNumberOfComponents() == 1)
            {
                // Definite winner
                cell_data = candidate;
                break;
            }
            else
                // Potential winner -- keep looking
                cell_data = candidate;
        }
        int npointArray = in_ds->GetPointData()->GetNumberOfArrays();
        for (i = 0 ; i < npointArray ; i++)
        {
            vtkDataArray *candidate = in_ds->GetPointData()->GetArray(i);
            if (strstr(candidate->GetName(), "vtk") != NULL)
                continue;
            if (strstr(candidate->GetName(), "avt") != NULL)
                continue;
            if (candidate->GetNumberOfComponents() == 1)
            {
                // Definite winner
                point_data = candidate;
                break;
            }
            else
                // Potential winner -- keep looking
                point_data = candidate;
        }

        if (cell_data != NULL && cell_data->GetNumberOfComponents() == 1)
        {
            data = cell_data;
            centering = AVT_ZONECENT;
        }
        else if (point_data != NULL && point_data->GetNumberOfComponents()== 1)
        {
            data = point_data;
            centering = AVT_NODECENT;
        }
        else if (cell_data != NULL)
        {
            data = cell_data;
            centering = AVT_ZONECENT;
        }
        else
        {
            data = point_data;
            centering = AVT_NODECENT;
        }
    } 
    else
    {
        cell_data = in_ds->GetCellData()->GetArray(activeVariable);
        point_data = in_ds->GetPointData()->GetArray(activeVariable);

        if (cell_data != NULL)
        {
            data = cell_data;
            centering = AVT_ZONECENT;
        }
        else
        {
            data = point_data;
            centering = AVT_NODECENT;
        }
    }

    //
    // Set up a VTK variable reflecting the calculated variable
    //
    int ncomps = 0;
    int nvals = 0;
    if (FilterCreatesSingleton())
        nvals = 1;
    else if (activeVariable == NULL || data == NULL)
        nvals = (IsPointVariable() ? in_ds->GetNumberOfPoints() 
                                   : in_ds->GetNumberOfCells());
    else
        nvals = data->GetNumberOfTuples();

    vtkDataArray *dv = NULL;
    if (data == NULL)
    {
        //
        // We could not find a single array.  We must be doing something with
        // the mesh.
        //
        ncomps = 1;
        dv = CreateArrayFromMesh(in_ds);
    }
    else
    {
        ncomps = data->GetNumberOfComponents();
        dv = CreateArray(data);
    }

    if (data == NULL)
    {
        if (! NullInputIsExpected())
        {
            // One way to get here is to have vtkPolyData Curve plots.
            EXCEPTION2(ExpressionException, outputVariableName,
                 "An internal error occurred when "
                 "trying to calculate your expression.  Please contact a "
                 "VisIt developer.");
        }
    }

    int noutcomps = GetNumberOfComponentsInOutput(ncomps);
    dv->SetNumberOfComponents(noutcomps);
    dv->SetNumberOfTuples(nvals);

    //
    // Should we send in ncomps or noutcomps?  They are the same number 
    // unless the derived type re-defined GetNumberOfComponentsInOutput.
    // If it did, it probably doesn't matter.  If not, then it is the same
    // number.  So send in the input.  Really doesn't matter.
    //
    cur_mesh = in_ds;
    DoOperation(data, dv, ncomps, nvals);
    cur_mesh = NULL;

    return dv;
}
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());
}
// ****************************************************************************
//  Method: avtVectorComposeExpression::DeriveVariable
//
//  Purpose:
//      Creates a vector variable from components.
//
//  Arguments:
//      inDS      The input dataset.
//
//  Returns:      The derived variable.  The calling class must free this
//                memory.
//
//  Programmer:   Sean Ahern
//  Creation:     Thu Mar  6 19:40:32 America/Los_Angeles 2003
//
//  Modifications:
//
//    Hank Childs, Thu Aug 14 11:01:34 PDT 2003
//    Add better support for 2D vectors.
//
//    Hank Childs, Fri Sep 19 13:46:13 PDT 2003
//    Added support for tensors, symmetric tensors.
//
//    Hank Childs, Sun Jan 13 20:11:35 PST 2008
//    Add support for singleton constants.
//
// ****************************************************************************
vtkDataArray *
avtVectorComposeExpression::DeriveVariable(vtkDataSet *in_ds)
{
    size_t numinputs = varnames.size();

    bool twoDVector = 
            (GetInput()->GetInfo().GetAttributes().GetSpatialDimension() == 2);

    //
    // Our first operand is in the active variable.  We don't know if it's
    // point data or cell data, so check which one is non-NULL.
    //
    vtkDataArray *cell_data1 = in_ds->GetCellData()->GetArray(varnames[0]);
    vtkDataArray *point_data1 = in_ds->GetPointData()->GetArray(varnames[0]);
    vtkDataArray *data1 = NULL, *data2 = NULL, *data3 = NULL;

    avtCentering centering;
    if (cell_data1 != NULL)
    {
        data1 = cell_data1;
        centering = AVT_ZONECENT;
    }
    else
    {
        data1 = point_data1;
        centering = AVT_NODECENT;
    }

    // Get the second variable.
    if (centering == AVT_ZONECENT)
        data2 = in_ds->GetCellData()->GetArray(varnames[1]);
    else
        data2 = in_ds->GetPointData()->GetArray(varnames[1]);

    if (data2 == NULL)
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
                   "The first two variables have different centering.");
    }

    if (numinputs == 3)
    {
        // Get the third variable.
        if (centering == AVT_ZONECENT)
            data3 = in_ds->GetCellData()->GetArray(varnames[2]);
        else
            data3 = in_ds->GetPointData()->GetArray(varnames[2]);
    
        if (data3 == NULL)
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                   "The first and third variables have different centering.");
        }
    }

    // As we proceed to build the vector out of components,
    // we make a list of offsets for each component 
    // so that we can attach that list to the resulting vector dataset
    // In the future, we need a generic way to merge vtkInformationObjects here
    std::vector<avtVector> offsets(3);
    vtkInformation* data1Info = data1->GetInformation();
    if (data1Info->Has(avtVariableCache::OFFSET_3())) {
      double* vals = data1Info->Get(avtVariableCache::OFFSET_3());
      offsets[0].x = vals[0];
      offsets[0].y = vals[1];
      offsets[0].z = vals[2];
    }

    vtkInformation* data2Info =data2->GetInformation();
    if (data2Info->Has(avtVariableCache::OFFSET_3())) {
      double* vals = data2Info->Get(avtVariableCache::OFFSET_3());
      offsets[1].x = vals[0];
      offsets[1].y = vals[1];
      offsets[1].z = vals[2];
    }
  
    if (numinputs == 3) {
      vtkInformation* data3Info = data3->GetInformation();
      if (data3Info->Has(avtVariableCache::OFFSET_3())) {
        double* vals = data3Info->Get(avtVariableCache::OFFSET_3());
        offsets[2].x = vals[0];
        offsets[2].y = vals[1];
        offsets[2].z = vals[2];
      }
    }

    vtkIdType nvals1 = data1->GetNumberOfTuples();
    vtkIdType nvals2 = data2->GetNumberOfTuples();
    vtkIdType nvals3 = 1;
    if (numinputs == 3)
        nvals3 = data3->GetNumberOfTuples();
    
    vtkIdType nvals = nvals1;
    if (nvals == 1)
        nvals  = nvals2;
    if (nvals == 1 && numinputs == 3)
        nvals  = nvals3;

    vtkDataArray *dv = data1->NewInstance();
    if (twoDVector)
    {
        if (numinputs == 2)
        {
            if (data1->GetNumberOfComponents() == 1 &&
                data2->GetNumberOfComponents() == 1)
            {
                //
                // Standard vector case.
                //
                dv->SetNumberOfComponents(3);  // VTK doesn't like 2.
                dv->SetNumberOfTuples(nvals);

                for (vtkIdType i = 0 ; i < nvals ; i++)
                {
                    double val1 = data1->GetTuple1((nvals1>1 ? i : 0));
                    double val2 = data2->GetTuple1((nvals2>1 ? i : 0));
                    dv->SetTuple3(i, val1, val2, 0.);
                }
            }
            else if ((data1->GetNumberOfComponents() == 3) &&
                     (data2->GetNumberOfComponents() == 3))
            {
                //
                // 2D tensor.
                //
                dv->SetNumberOfComponents(9); 
                dv->SetNumberOfTuples(nvals);
                
                for (vtkIdType i = 0 ; i < nvals ; i++)
                {
                    double vals[9];
                    vals[0] = data1->GetComponent((nvals1>1 ? i : 0), 0);
                    vals[1] = data1->GetComponent((nvals2>1 ? i : 0), 1);
                    vals[2] = 0.;
                    vals[3] = data2->GetComponent((nvals1>1 ? i : 0), 0);
                    vals[4] = data2->GetComponent((nvals2>1 ? i : 0), 1);
                    vals[5] = 0.;
                    vals[6] = 0.;
                    vals[7] = 0.;
                    vals[8] = 0.;
                    dv->SetTuple(i, vals);
                }
            }
            else
            {
                char str[1024];
                sprintf(str, "Do not know how to assemble arrays of %d and "
                             "%d into a vector or tensor.", 
                              data1->GetNumberOfComponents(),
                              data2->GetNumberOfComponents());
                EXCEPTION2(ExpressionException, outputVariableName, str);
            }
        }
        else if (numinputs == 3)
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                       "I don't know how to compose "
                       "3 variables to make a field for a 2D dataset.");
        }
    }
    else
    {
        if (numinputs == 3)
        {
            if (data1->GetNumberOfComponents() == 1 && 
                data2->GetNumberOfComponents() == 1 && 
                data3->GetNumberOfComponents() == 1)
            {
                //
                // This is your everyday 3D vector combination.
                //
                dv->SetNumberOfComponents(3); 
                dv->SetNumberOfTuples(nvals);
                
                for (vtkIdType i = 0 ; i < nvals ; i++)
                {
                    double val1 = data1->GetTuple1((nvals1>1 ? i : 0));
                    double val2 = data2->GetTuple1((nvals2>1 ? i : 0));
                    double val3 = data3->GetTuple1((nvals3>1 ? i : 0));
                    dv->SetTuple3(i, val1, val2, val3);
                }
            }
            else if (data1->GetNumberOfComponents() == 3 &&
                     data2->GetNumberOfComponents() == 3 &&
                     data3->GetNumberOfComponents() == 3)
            {
                //
                // This is a 3D tensor.  Interpret it as:
                // Data1 = XX, XY, XZ
                // Data2 = YX, YY, YZ
                // Data3 = ZX, ZY, ZZ
                //
                dv->SetNumberOfComponents(9); 
                dv->SetNumberOfTuples(nvals);
                
                for (vtkIdType i = 0 ; i < nvals ; i++)
                {
                    double entry[9];
                    data1->GetTuple((nvals1>1 ? i : 0), entry);
                    data2->GetTuple((nvals2>1 ? i : 0), entry+3);
                    data3->GetTuple((nvals3>1 ? i : 0), entry+6);
                    dv->SetTuple(i, entry);
                }
            }
            else
            {
                EXCEPTION2(ExpressionException, outputVariableName, 
                           "The only interpretation "
                           "VisIt can make of 3 variables for a 3D dataset is "
                           "a vector or a tensor.  But these inputs don't have"
                           " the right number of components to make either.");
            }
        }
        else 
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                        "You must specify three vectors "
                        "to compose a field for a 3D dataset.");
        }
    }

    //If offset information existed on the input dataset, set it on the output
    if ((offsets[0].x != 0) || (offsets[0].y != 0) || (offsets[0].z != 0) ||
        (offsets[1].x != 0) || (offsets[1].y != 0) || (offsets[1].z != 0) ||
        (offsets[2].x != 0) || (offsets[2].y != 0) || (offsets[2].z != 0)) {
      vtkInformation* dvInfo = dv->GetInformation();
      dvInfo->Set(avtVariableCache::OFFSET_3_COMPONENT_0(), offsets[0].x, offsets[0].y, offsets[0].z);
      dvInfo->Set(avtVariableCache::OFFSET_3_COMPONENT_1(), offsets[1].x, offsets[1].y, offsets[1].z);
      dvInfo->Set(avtVariableCache::OFFSET_3_COMPONENT_2(), offsets[2].x, offsets[2].y, offsets[2].z);
    }

    return dv;
}
vtkDataArray *
avtVectorDecomposeExpression::DeriveVariable(vtkDataSet *in_ds)
{
    vtkDataArray *arr = NULL;

    //
    // The base class will set the variable of interest to be the 
    // 'activeVariable'.  This is a by-product of how the base class sets its
    // input.  If that method should change (SetActiveVariable), this
    // technique for inferring the variable name may stop working.
    //
    const char *varname = activeVariable;

    //
    // Get the array of interest.
    //
    if (in_ds->GetPointData()->GetArray(varname) != NULL)
    {
        arr = in_ds->GetPointData()->GetArray(varname);
    }
    else
    {
        arr = in_ds->GetCellData()->GetArray(varname);
    }
    if (arr == NULL)
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
                   "When creating an expression, VisIt "
                   "was not able to locate a necessary variable.");
    }

    //
    // The logic here can be pretty tricky.  We want to decompose this "vector"
    // variable.  But the "vector" can be an everyday vector, or it can be a
    // symmetric on non-symmetric tensor.  Based on the dimensionality of the
    // dataset, the output could be a scalar or it could be a vector.
    //
    vtkIdType ntuples = arr->GetNumberOfTuples();
    vtkDataArray *rv = arr->NewInstance();

    bool twoDVector =
            (GetInput()->GetInfo().GetAttributes().GetSpatialDimension() == 2);

    if (twoDVector)
    {
        if ((which_comp > 1) || (which_comp < 0))
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                       "The only valid indices for 2D vectors are 0 and 1.");
        }
        if (arr->GetNumberOfComponents() == 3)
        {
            rv->SetNumberOfComponents(1);
            rv->SetNumberOfTuples(ntuples);
            for (vtkIdType i = 0 ; i < ntuples ; i++)
            {
                double val = arr->GetComponent(i, which_comp);
                rv->SetTuple1(i, val);
            }
        }
        else if (arr->GetNumberOfComponents() == 9)
        {
            //
            // Give one row of the tensor back.  Since VTK dislikes vectors
            // of size 2, make sure that we have 3 components.
            //
            rv->SetNumberOfComponents(3);
            rv->SetNumberOfTuples(ntuples);
            for (vtkIdType i = 0 ; i < ntuples ; i++)
            {
                double val1 = arr->GetComponent(i, 3*which_comp);
                double val2 = arr->GetComponent(i, 3*which_comp+1);
                rv->SetTuple3(i, val1, val2, 0.);
            }
        }
        else
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                       "You can only decompose vectors and tensors.");
        }
    }
    else
    {
        if ((which_comp > 2) || (which_comp < 0))
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                      "The only valid indices for 3D vectors are 0, 1, and 2");
        }
        if (arr->GetNumberOfComponents() == 3)
        {
            //
            // Looks like an everyday 3D vector.
            //
            rv->SetNumberOfComponents(1);
            rv->SetNumberOfTuples(ntuples);
            for (vtkIdType i = 0 ; i < ntuples ; i++)
            {
                double val = arr->GetComponent(i, which_comp);
                rv->SetTuple1(i, val);
            }
        }
        else if (arr->GetNumberOfComponents() == 9)
        {
            //
            // Tensor data.  Return a row (*X, *Y, *Z).
            //
            rv->SetNumberOfComponents(3);
            rv->SetNumberOfTuples(ntuples);
            for (vtkIdType i = 0 ; i < ntuples ; i++)
            {
                double val1 = arr->GetComponent(i, 3*which_comp);
                double val2 = arr->GetComponent(i, 3*which_comp+1);
                double val3 = arr->GetComponent(i, 3*which_comp+2);
                rv->SetTuple3(i, val1, val2, val3);
            }
        }
        else
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                       "You can only decompose vectors and tensors.");
        }
    }

    return rv;
}
void
avtTimeIteratorExpression::ProcessArguments(ArgsExpr *args,
                                            ExprPipelineState *state)
{
    int  i;

    // get the argument list and # of arguments
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    int nargs = arguments->size();

    // check for call with no args
    if (nargs < NumberOfVariables())
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "Not enough arguments to time iterator expression");
    }

    // Each of these arguments should be variables.
    for (i = 0 ; i < NumberOfVariables() ; i++)
    {
        ArgExpr *arg = (*arguments)[i];
        avtExprNode *tree = dynamic_cast<avtExprNode*>(arg->GetExpr());
        tree->CreateFilters(state);
    }

    std::vector<int> timecontrols;
    for (i = NumberOfVariables() ; i < nargs ; i++)
    {
        ArgExpr *arg= (*arguments)[i];
        ExprParseTreeNode *tree= arg->GetExpr();
        std::string argtype = tree->GetTypeName();
        // check for arg passed as integer
        if (argtype == "IntegerConst")
        {
            int t = dynamic_cast<IntegerConstExpr*>(tree)->GetValue();
            timecontrols.push_back(t);
        }
        else if (argtype == "StringConst")
        {
            std::string s = dynamic_cast<StringConstExpr*>(tree)->GetValue();
            if (s == "pos_cmfe")
            {
                if (i == nargs-1)
                {
                    EXCEPTION2(ExpressionException, outputVariableName,
                               "If specify pos_cmfe, then you must follow that"
                               " immediately with a default variable.");
                }
                i++;
                ArgExpr *arg = (*arguments)[i];
                avtExprNode *tree = dynamic_cast<avtExprNode*>(arg->GetExpr());
                tree->CreateFilters(state);
                cmfeType = POS_CMFE;
            }
            else if (s != "conn_cmfe")
            {
                char msg[1024];
                SNPRINTF(msg, 1024, "Could not understand meaning of \"%s\"",
                                    s.c_str());
                EXCEPTION2(ExpressionException, outputVariableName,msg);
            }
        }
    }
    if (timecontrols.size() == 3)
    {
        firstTimeSlice = timecontrols[0];
        lastTimeSlice  = timecontrols[1];
        timeStride     = timecontrols[2];
    }
    else if (timecontrols.size() != 0)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "The specification of time must use integers.  "
                   "These integers are dump indices, 0-indexed."
                   "If you specify time controls, there must be three integers"
                   ", start, stop, stride");
    }
}
Exemple #20
0
/**
 *  @brief Linux-specific version of do_cpu_set_init().
 *
 *  @param cpu_set The CPU set.
 *
 *  @return 0 on success. Negative value on error.
 */
static void cpu_set_init_Linux(cpu_set_p cpu_set)
{

  int i;
  os_cpu_set_t original_affinity_set;
  int num_cpus = sysconf(_SC_NPROCESSORS_CONF);

  
  
  /* get current affinity set so we can restore it when we're done */
  if ( sched_getaffinity( 0, sizeof(os_cpu_set_t), &original_affinity_set ) )
      throw EXCEPTION2(ThreadException,
                       "sched_getaffinity() failed with %s",
                       errno_to_str().data());

  /* test restoration */
  if ( sched_setaffinity( 0, sizeof(os_cpu_set_t), &original_affinity_set ) )
      throw EXCEPTION2(ThreadException,
                       "sched_setaffinity() failed with %s",
                       errno_to_str().data());


  /* allocate cpus */
  cpu_t cpus = 
    (cpu_t)malloc( num_cpus * sizeof(struct cpu_s) );
  if ( cpus == NULL )
    throw EXCEPTION1(BadAlloc, "cpu array");

  for (i = 0; i < num_cpus; i++)
    /* initialize fields */
    CPU_ZERO( &cpus[i].cpu_set );



  /* find the CPUs on the system */
  int num_found = 0;
  int cpu_num;
  for (cpu_num = 0; ; cpu_num++)
  {
    os_cpu_set_t test_set;
    CPU_ZERO( &test_set );
    CPU_SET ( cpu_num, &test_set );

    if ( !sched_setaffinity( 0, sizeof(os_cpu_set_t), &test_set ) )
    {
      /* found a new CPU */
      cpus[num_found].cpu_unique_id = cpu_num;
      cpu_set_copy( &cpus[num_found].cpu_set, &test_set );
      num_found++;
      if ( num_found == num_cpus )
        break;
    }
  }  

  

  /* restore original affinity set */
  if ( sched_setaffinity( 0, sizeof(os_cpu_set_t), &original_affinity_set ) )
      throw EXCEPTION2(ThreadException,
                       "sched_setaffinity() failed with %s",
                       errno_to_str().data());
  
  
  /* return parameters */
  cpu_set->cpuset_num_cpus = num_cpus;
  cpu_set->cpuset_cpus     = cpus;
}
// ****************************************************************************
//  Method: avtCylindricalRadiusExpression::ProcessArguments
//
//  Purpose:
//      Parses optional arguments. 
//      Allows the user to pass a string constaint specifying the cylinder
//      axis (default = z ) or a vector that defines the cylinder axis.
// 
//
//  Programmer:   Cyrus Harrison 
//  Creation:     March 31, 2008
//
//  Modifications:
//
// ****************************************************************************
void
avtCylindricalRadiusExpression::ProcessArguments(
    ArgsExpr *args, ExprPipelineState *state)
{
    axisVector[0] = 0;
    axisVector[1] = 0;
    axisVector[2] = 1;
    
    // Check the number of arguments
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    size_t nargs = arguments->size();
    if (nargs == 0)
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
                  "avtCylindricalRadiusExpression: No arguments given.");
    }

    // First arg should be a mesh name, let it gen is filters. 
    ArgExpr *first_arg = (*arguments)[0];
    avtExprNode *first_tree = dynamic_cast<avtExprNode*>(first_arg->GetExpr());
    first_tree->CreateFilters(state);

    // If we only have two arguments, we expect a string const or vector const 
    if (nargs == 2)
    {
        ArgExpr *second_arg = (*arguments)[1];
        ExprParseTreeNode *second_tree = second_arg->GetExpr();
        std::string arg_type = second_tree->GetTypeName();
        
        std::string error_msg = "avtCylindricalRadiusExpression: "
                           "Invalid second argument."
                           "Expected \"x\", \"y\", or \"z\"";

        if (arg_type != "StringConst" && arg_type != "Vector" )
        {
            debug5 << error_msg << endl;
            EXCEPTION2(ExpressionException, outputVariableName, 
                       error_msg.c_str());
        }
        
        if (arg_type == "StringConst")
        {
            // string case
            std::string val = dynamic_cast<StringConstExpr*>(second_tree)->GetValue();

            if ( ! ( val == "x" || val == "y"  || val == "z"))
            {
                error_msg += "\nPassed value \"" + val + "\"";
                debug5 << error_msg << endl;
                EXCEPTION2(ExpressionException, outputVariableName, 
                           error_msg.c_str());
            }
        
            debug5 << "avtCylindricalCoordinatesExpression:" 
                   << "Using " << val << " as Cylinder Axis." << endl;
            if(val == "x")
            {
                axisVector[0] = 1;
                axisVector[1] = 0;
                axisVector[2] = 0;
            }
            else if(val == "y")
            {
                axisVector[0] = 0;
                axisVector[1] = 1;
                axisVector[2] = 0;
            }
            else if(val == "z")
            {
                axisVector[0] = 0;
                axisVector[1] = 0;
                axisVector[2] = 1;
            }
        }
        else if(arg_type == "Vector")
        {
            VectorExpr *vec = dynamic_cast<VectorExpr*>(second_tree);
            
            if(!vec->Z())
            {
                error_msg += "\nVector missing z-component.";
                debug5 << error_msg << endl;
                EXCEPTION2(ExpressionException, outputVariableName, 
                           error_msg.c_str());
            }
            
            // get the vector 
            double val = 0;
            
            if(GetNumericVal(vec->X(),val))
            {
                axisVector[0] = val;
            }
            else
            {                
                error_msg += "\nVector x-component is not a floating point number.";
                debug5 << error_msg << endl;
                EXCEPTION2(ExpressionException, outputVariableName, 
                           error_msg.c_str());
            }
            
            if(GetNumericVal(vec->Y(),val))
            {
                axisVector[1] = val;
            }
            else
            {                
                error_msg += "\nVector z-component is not a floating point number.";
                debug5 << error_msg << endl;
                EXCEPTION2(ExpressionException, outputVariableName, 
                           error_msg.c_str());
            }
            
            if(GetNumericVal(vec->Z(),val))
            {
                axisVector[2] = val;
            }
            else
            {                
                error_msg += "\nVector z-component is not a floating point number.";
                debug5 << error_msg << endl;
                EXCEPTION2(ExpressionException, outputVariableName, 
                           error_msg.c_str());
            }

            if ( axisVector[0] == 0 && axisVector[1] == 0 && axisVector[2] == 0 )
            {
                error_msg += "\nDegenerate vector {0,0,0}.";
                debug5 << error_msg << endl;
                EXCEPTION2(ExpressionException, outputVariableName, 
                           error_msg.c_str());
            }
        }
        
    }
}
void
avtCurlExpression::GetMacro(std::vector<std::string> &args, std::string &ne, 
                        Expression::ExprType &type)
{
    bool do3D = true;
    if (*(GetInput()) != NULL)
    {
        avtDataAttributes &atts = GetInput()->GetInfo().GetAttributes();
        if (atts.GetTopologicalDimension() < 3)
        {
            do3D = false;
        }
    }

    int nargs = args.size();

    char new_expr[2048];
    if (do3D)
    {
        if(nargs == 1)
        {
            SNPRINTF(new_expr,2048, 
                    "{gradient(%s[2])[1]-gradient(%s[1])[2],"
                    "gradient(%s[0])[2]-gradient(%s[2])[0],"
                    "gradient(%s[1])[0]-gradient(%s[0])[1]}",
                    args[0].c_str(), args[0].c_str(), args[0].c_str(),
                    args[0].c_str(), args[0].c_str(), args[0].c_str());
        }
        else if(nargs > 1)
        {
            SNPRINTF(new_expr,2048, 
                    "{gradient(%s[2],%s)[1]-gradient(%s[1],%s)[2],"
                    "gradient(%s[0],%s)[2]-gradient(%s[2],%s)[0],"
                    "gradient(%s[1],%s)[0]-gradient(%s[0],%s)[1]}",
                    args[0].c_str(), args[1].c_str(),
                    args[0].c_str(), args[1].c_str(),
                    args[0].c_str(), args[1].c_str(),
                    args[0].c_str(), args[1].c_str(),
                    args[0].c_str(), args[1].c_str(),
                    args[0].c_str(), args[1].c_str());
        }
        else
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                        " invalid curl syntax. "
                        "Expected arguments: "
                        "vector_var, gradient_algorithm\n"
                        "[gradient_algorithm is optional]");
        }

        type = Expression::VectorMeshVar;
    }
    else
    {
        if(nargs == 1)
        {
            SNPRINTF(new_expr,2048,
                    "gradient(%s[1])[0]-gradient(%s[0])[1]",
                    args[0].c_str(), args[0].c_str());
        }
        else if(nargs > 1)
        {
            SNPRINTF(new_expr,2048,
                    "gradient(%s[1],%s)[0]-gradient(%s[0],%s)[1]",
                    args[0].c_str(), args[1].c_str(), 
                    args[0].c_str(), args[1].c_str());
        }
        else
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                        " invalid curl syntax. "
                        "Expected arguments: "
                        "vector_var, gradient_algorithm\n"
                        "[gradient_algorithm is optional]");
        }

        type = Expression::ScalarMeshVar;
    }
    ne = new_expr;
}
void
avtTimeIteratorDataTreeIteratorExpression::PrepareAndExecuteDataset(
                                                        vtkDataSet *ds, int ts)
{
    std::vector<vtkDataArray *> ds_vars;
    std::vector<vtkDataArray *> delete_vars;

    bool haveZonal = false;

    size_t nvars = varnames.size();
    if (cmfeType == POS_CMFE)
        nvars--;
    for (size_t i = 0 ; i < nvars ; i++)
    {
        std::string vname = GetInternalVarname(i);
        vtkDataArray *cell_data1 = ds->GetCellData()->GetArray(vname.c_str());
        vtkDataArray *point_data1 = ds->GetPointData()->GetArray(vname.c_str());
        if (cell_data1 == NULL && point_data1 == NULL)
        {
            EXCEPTION2(ExpressionException, outputVariableName,
                       "An internal error occurred when calculating an expression."
                       "  Please contact a VisIt developer.");
        }
        haveZonal = (cell_data1 != NULL);
    }

    bool doZonal = false;
    if (haveZonal)
        doZonal = true;  // mixed centering -> zonal

    for (size_t i = 0 ; i < nvars ; i++)
    {
        std::string vname = GetInternalVarname(i);
        vtkDataArray *cell_data1 = ds->GetCellData()->GetArray(vname.c_str());
        vtkDataArray *point_data1 = ds->GetPointData()->GetArray(vname.c_str());

        if (doZonal)
        { 
            if (cell_data1 != NULL)
                ds_vars.push_back(cell_data1);
            else
            {
                vtkDataArray *tmp = Recenter(ds, point_data1, AVT_NODECENT, 
                                             varnames[i], AVT_ZONECENT);
                ds_vars.push_back(tmp);
                delete_vars.push_back(tmp);
            }
        }
        else
        {
            if (point_data1 != NULL)
                ds_vars.push_back(point_data1);
            else
            {
                vtkDataArray *tmp = Recenter(ds, cell_data1, AVT_ZONECENT, 
                                             varnames[i], AVT_NODECENT);
                ds_vars.push_back(tmp);
                delete_vars.push_back(tmp);
            }
        }
    }

    vtkDataArray *out_arr = vars[arrayIndex++];
    ExecuteDataset(ds_vars, out_arr, ts);

    for (size_t i = 0 ; i < delete_vars.size() ; i++)
        delete_vars[i]->Delete();
}
void
avtRAWFileFormat::ReadFile(const char *name)
{
    const char *mName = "avtRAWFileFormat::ReadFile: ";
    int total = visitTimer->StartTimer();
    debug4 << mName << endl;

    // Open the file.
    ifstream ifile(name);
    if (ifile.fail())
    {
        EXCEPTION1(InvalidFilesException, name);
    }

    debug4 << "Opened the file: " << name << endl;

    bool trianglesAdded = false;
#ifndef MDSERVER
    // Make a guess about the number of cells and points based on
    // the size of the file.    
    int nCells = 100;
    VisItStat_t statbuf;
    VisItStat(name, &statbuf);
    VisItOff_t fileSize = statbuf.st_size;
    nCells  = fileSize / (VisItOff_t) 80;

    debug4 << mName << "Guessing there are about " << nCells << " cells" << endl;

    vtkPolyData *currentPD = NewPD(nCells);
    VertexManager *vertexMgr = new VertexManager(currentPD->GetPoints());
#else
    vtkPolyData *currentPD = 0;
#endif

    int domain = 0;
    char   line[1024];
    double pts[9] = {0.,0.,0.,0.,0.,0.,0.,0.,0.};
    int nc = 0;
    for(int lineIndex = 0; ifile.good(); ++lineIndex)
    {
        // Get the line
        ifile.getline(line, 1024);
        if (lineIndex<100 && !StringHelpers::IsPureASCII(line, 1024))
            EXCEPTION2(InvalidFilesException, name, "Not ASCII.");

        // Skip leading spaces.
        char *cptr = line;
        while((*cptr == ' ' || *cptr == '\t') &&
              (cptr < (line + 1024)))
           ++cptr;

        if((cptr[0] >= '0' && cptr[0] <= '9') || (cptr[0] == '-')) 
        {
#ifndef MDSERVER
            // We found a line with points. Read the line and add a triangle cell.
            int n = sscanf(cptr, "%lg %lg %lg %lg %lg %lg %lg %lg %lg",
                           &pts[0], &pts[1], &pts[2],
                           &pts[3], &pts[4], &pts[5],
                           &pts[6], &pts[7], &pts[8]);
            if (GetStrictMode() && n != 9)
            {
                EXCEPTION2(InvalidFilesException, GetFilename(),
                           "Bad line in file; less than nine values");
            }
            vtkIdType ids[3];
            ids[0] = vertexMgr->GetVertexId(pts);
            ids[1] = vertexMgr->GetVertexId(pts + 3);
            ids[2] = vertexMgr->GetVertexId(pts + 6);
            currentPD->InsertNextCell(VTK_TRIANGLE, 3, ids);
#endif
            trianglesAdded = true;
        }
        else
        {
            // If we're hitting a new object name and we've added some triangles
            // then we need to add the currentPD to the meshes vector.
            if(trianglesAdded)
            {
                if(meshes.size() == 0)
                {
                    // We get here when we've created some polydata but have not
                    // seen an object id for it yet. In that case, we add an object
                    // to the list.
                    debug4 << mName << "Adding Object mesh" << endl;
                    domain_data dom;
                    dom.domainName = "Object";
                    dom.mesh = currentPD;
                    meshes.push_back(dom);
                    ++domain;
                }
#ifndef MDSERVER
                else
                {
                    // We get here when we've created some polydata for a tag that
                    // we've seen and we're encountering a new tag.
                    debug4 << mName << "Setting mesh for mesh["
                           << (domain-1) << "]\n";
                    meshes[domain-1].mesh = currentPD;
                }
                currentPD->Squeeze();

                // Reset for a new polydata.
                currentPD = NewPD(nCells);
                delete vertexMgr;
                vertexMgr = new VertexManager(currentPD->GetPoints());
#endif
                trianglesAdded = false;
            }

            // We have the name of a new object.
            domain_data dom;
            int len = strlen(cptr);
            if(len > 0)
            {
                // If the new name is valid then add a mesh entry for it.
                if(cptr[len-1] == '\n')
                    cptr[len-1] = '\0'; // Remove the end of line.
                dom.domainName = std::string(cptr);
                dom.mesh = 0;
                meshes.push_back(dom);
                ++domain;
                debug4 << mName << "Domain " << domain << " is called: " << cptr << endl;
            }
            else
            {
                debug4 << mName << "Empty domain name" << endl;
                if (GetStrictMode() && !ifile.eof())
                {
                    EXCEPTION2(InvalidFilesException, GetFilename(),
                               "Empty domain name.");
                }
            }
        }
    }

    // Print out the meshes list
    debug4 << "MESHES\n===========================\n";
    for(int i = 0; i < meshes.size(); ++i)
    {
        debug4 << mName << "Mesh " << i << ": " << meshes[i].domainName.c_str()
               << ", ptr=" << (void*)meshes[i].mesh << endl;
    }

#ifndef MDSERVER
    // Delete the vertex manager if it exists.
    if(vertexMgr != 0)
        delete vertexMgr;
#endif

    debug4 << mName << "end" << endl;

    visitTimer->StopTimer(total, "Loading RAW file");
}
vtkDataArray *
avtConditionalExpression::DeriveVariable(vtkDataSet *in_ds, int currentDomainsIndex)
{
    // Our first operand is in the active variable.  We don't know if it's
    // point data or cell data, so check which one is non-NULL.
    vtkDataArray *cell_data1 = in_ds->GetCellData()->GetArray(varnames[0]);
    vtkDataArray *point_data1 = in_ds->GetPointData()->GetArray(varnames[0]);
    vtkDataArray *data1 = NULL, *data2 = NULL, *data3 = NULL;

    avtCentering centering;
    if (cell_data1 != NULL)
    {
        data1 = cell_data1;
        centering = AVT_ZONECENT;
    }
    else
    {
        data1 = point_data1;
        centering = AVT_NODECENT;
    }

    if (data1 == NULL)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "Could not identify centering of first variable");
    }
    if (data1->GetNumberOfComponents() != 1)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "Cannot interpret conditional with vector dimensionality");
    }

    // Get the second variable.
    if (centering == AVT_ZONECENT)
        data2 = in_ds->GetCellData()->GetArray(varnames[1]);
    else
        data2 = in_ds->GetPointData()->GetArray(varnames[1]);

    if (data2 == NULL)
    {
        char msg[1024];
        SNPRINTF(msg, 1024, 
                   "the first two arguments to \"if\" (%s and %s) have "
                   " different centerings.", varnames[0], varnames[1]);
        EXCEPTION2(ExpressionException, outputVariableName, msg);
    }

    // Get the third variable.
    if (centering == AVT_ZONECENT)
        data3 = in_ds->GetCellData()->GetArray(varnames[2]);
    else
        data3 = in_ds->GetPointData()->GetArray(varnames[2]);
    
    if (data3 == NULL)
    {
        char msg[1024];
        SNPRINTF(msg, 1024, 
                   "the first and third arguments to \"if\" (%s and %s) have "
                   " different centerings.", varnames[0], varnames[2]);
        EXCEPTION2(ExpressionException, outputVariableName, msg);
    }

    // sanity check: make sure the input arrays have the same # of tuples
    int d1_nvals = data1->GetNumberOfTuples();
    int d2_nvals = data2->GetNumberOfTuples();
    int d3_nvals = data2->GetNumberOfTuples();
    
    if ( d1_nvals != d2_nvals || d2_nvals != d3_nvals )
    {
        std::string msg = " the input datasets for the \"if\" expression "
                          " do not have the same number of tuples!";
        EXCEPTION2(ExpressionException, outputVariableName, msg.c_str());
    }
    
    //
    // Set up a VTK variable reflecting the calculated variable
    //
    int nvals  = data2->GetNumberOfTuples();
    vtkDataArray *dv = data2->NewInstance();
    dv->SetNumberOfComponents(data2->GetNumberOfComponents());
    dv->SetNumberOfTuples(nvals);

    if (data1->GetDataType() == VTK_UNSIGNED_CHAR)
    {
        vtkUnsignedCharArray *uca = (vtkUnsignedCharArray *) data1;
        for (int i = 0 ; i < nvals ; i++)
        {
            unsigned char val = uca->GetValue(i);
            if (val != '\0')
            {
                dv->SetTuple(i, data2->GetTuple(i));
            }
            else
            {
                dv->SetTuple(i, data3->GetTuple(i));
            }
        }
    }
    else  
    {
        for (int i = 0 ; i < nvals ; i++)
        {
            double val = data1->GetTuple1(i);
            if (val != 0.)
            {
                dv->SetTuple(i, data2->GetTuple(i));
            }
            else
            {
                dv->SetTuple(i, data3->GetTuple(i));
            }
        }
    }
      
    return dv;
}
// ****************************************************************************
//  Function:  DetectBoundaryGhostLayers 
//
//  Purpose: Detects number of ghost layers in each dimension given
//     knowledge of the dimension, non-ghosted size of the patch in each
//     dimension and the pre-existing avtGhostZones data
//
//     To perform the detection, basically we try all reasonable combinations
//     of ghost numbers of layers and probe the ghostData array around the
//     extreme high and low ijk corners of the patch to see if we get something
//     thats consistent. The loop looks daunting but it completes very quickly.
//
//  Programmer:  Mark C. Miller 
//  Creation:    January 8, 2004
//
// ****************************************************************************
void
DetectBoundaryGhostLayers(int numDims, unsigned char *ghostData, int numCells,
    vector<int> extents, int *ghostLayers)
{
    int Ni = 0, Nj = 0, Nk = 0;

    // compute size of NON-ghosted patch
    switch (numDims) // note: exploits fall-through
    {
        case 3: Nk = extents[5] - extents[2] + 1;
        case 2: Nj = extents[4] - extents[1] + 1;
        case 1: Ni = extents[3] - extents[0] + 1;
    }

    // vector to populate with valid ghost cases
    vector<int> ghostCases;

    // loop over all possible combinations of ghost layer widths
    int gi, gj, gk;
    for (gi = 0; gi <= (Ni==0 ? 0 : MAX_GHOST_LAYERS); gi++)
    {
        for (gj = 0; gj <= (Nj==0 ? 0 : MAX_GHOST_LAYERS); gj++)
        {
            for (gk = 0; gk <= (Nk==0 ? 0 : MAX_GHOST_LAYERS); gk++)
            {
                // we always skip the all 0 case
                if ((gi == 0) && (gj == 0) && (gk == 0))
                    continue;

                // compute size of ghosted patch given this layering 
                int Mk = Nk + 2 * gk;
                int Mj = Nj + 2 * gj;
                int Mi = Ni + 2 * gi;

                // can ignore this case immediately if the number of
                // cells it presumes doesn't equate to the number of
                // cells we know we have 
                int ncells = 0;
                switch (numDims)
                {
                    case 3: ncells = Mk * Mj * Mi; break;
                    case 2: ncells =      Mj * Mi; break;
                    case 1: ncells =           Mi; break;
                }
                if (ncells != numCells)
                    continue;

                // probe ghost data array round 2 extreme corners
                int mult;
                bool impossibleGhostCase = false;
                for (mult = -1; (mult <= 1) && !impossibleGhostCase; mult += 2)
                {
                    int i0, j0, k0;

                    // set which corner to examine ghost values around 
                    // -1 --> Lower, Left, Front
                    // +1 --> Upper, Right, Back
                    if (mult == -1)
                    {
                        // the extreme lowest corner 
                        // in the 
                        i0 = 0 + gi;
                        j0 = 0 + gj;
                        k0 = 0 + gk;
                    }
                    else
                    {
                        // the extreme highest corner 
                        i0 = Ni - 1 + gi;
                        j0 = Nj - 1 + gj;
                        k0 = Nk - 1 + gk;
                    }

                    // examine all cells around the corner for ghost values
                    int i,j,k;
                    for (i = 0; (i <= gi) && !impossibleGhostCase; i++)
                    {
                        for (j = 0; (j <= gj) && !impossibleGhostCase; j++)
                        {
                            for (k = 0; (k <= gk) && !impossibleGhostCase; k++)
                            {
                                // we always skip the all 0 case
                                if ((i == 0) && (j == 0) && (k == 0))
                                    continue;

                                // compute index within ghosted patch
                                int a = i0 + i * mult;
                                int b = j0 + j * mult;
                                int c = k0 + k * mult;
                                int idx;

                                // compute offset into ghost array assuming
                                // a zone really exists at the logical index [a,b,c]
                                switch (numDims)
                                {
                                    case 3: idx = c*Mi*Mj + b*Mi + a; break;
                                    case 2: idx =           b*Mi + a; break;
                                    case 1: idx =                  a; break;
                                }

                                // if the computed index is either out of
                                // range or the ghost value indicates it
                                // is NOT really a ghost, its invalid
                                if ((idx < 0) || (idx >= numCells) ||
                                    (ghostData[idx] == 0))
                                {
                                    impossibleGhostCase = true;
                                }
                            }
                        }
                    }
                }

                if (!impossibleGhostCase)
                {
                    ghostCases.push_back(gi);
                    ghostCases.push_back(gj);
                    ghostCases.push_back(gk);
                }

            }
        }
    }

    if (ghostCases.size() != 3)
    {
        EXCEPTION2(UnexpectedValueException, 3, ghostCases.size());
    }

    ghostLayers[0] = ghostCases[0];
    ghostLayers[1] = ghostCases[1];
    ghostLayers[2] = ghostCases[2];

}
vtkDataArray *
avtColorComposeExpression::DeriveVariable(vtkDataSet *in_ds, int currentDomainsIndex)
{
    size_t numinputs = varnames.size();

    //
    // Our first operand is in the active variable. We don't know if it's
    // point data or cell data, so check which one is non-NULL.
    //
    vtkDataArray *cell_data1 = in_ds->GetCellData()->GetArray(varnames[0]);
    vtkDataArray *point_data1 = in_ds->GetPointData()->GetArray(varnames[0]);
    vtkDataArray *data1 = NULL, *data2 = NULL, *data3 = NULL, *data4 = NULL;

    avtCentering centering;
    if (cell_data1 != NULL)
    {
        data1 = cell_data1;
        centering = AVT_ZONECENT;
    }
    else
    {
        data1 = point_data1;
        centering = AVT_NODECENT;
    }
    if (data1 != NULL && data1->GetNumberOfComponents() != 1)
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
                   "The first variable is not a scalar.");
    }

    // Get the second variable.
    if (centering == AVT_ZONECENT)
        data2 = in_ds->GetCellData()->GetArray(varnames[1]);
    else
        data2 = in_ds->GetPointData()->GetArray(varnames[1]);

    if (data2 == NULL)
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
                   "The first two variables have different centering.");
    }
    if (data2->GetNumberOfComponents() != 1)
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
                   "The second variable is not a scalar.");
    }

    if (numinputs >= 3)
    {
        // Get the third variable.
        if (centering == AVT_ZONECENT)
            data3 = in_ds->GetCellData()->GetArray(varnames[2]);
        else
            data3 = in_ds->GetPointData()->GetArray(varnames[2]);
    
        if (data3 == NULL)
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                   "The first and third variables have different centering.");
        }
        if (data3->GetNumberOfComponents() != 1)
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                       "The third variable is not a scalar.");
        }
    }

    if (numinputs == 4)
    {
        // Get the fourth variable.
        if (centering == AVT_ZONECENT)
            data4 = in_ds->GetCellData()->GetArray(varnames[3]);
        else
            data4 = in_ds->GetPointData()->GetArray(varnames[3]);
    
        if (data4 == NULL)
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                   "The first and fourth variables have different centering.");
        }
        if (data4->GetNumberOfComponents() != 1)
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                       "The fourth variable is not a scalar.");
        }
    }

    vtkIdType nvals = data1->GetNumberOfTuples();
    vtkDataArray *dv = data1->NewInstance();
    dv->SetNumberOfComponents(4);
    dv->SetNumberOfTuples(data1->GetNumberOfTuples());
    if(numinputs == 1)
    {
        for(vtkIdType id = 0; id < nvals; ++id)
        {
            double val1 = ClampColor(data1->GetTuple1(id));
            dv->SetTuple4(id, val1, 0., 0., 255.);
        }
    }
    else if(numinputs == 2)
    {
        for(vtkIdType id = 0; id < nvals; ++id)
        {
            double val1 = ClampColor(data1->GetTuple1(id));
            double val2 = ClampColor(data2->GetTuple1(id));
            dv->SetTuple4(id, val1, val2, 0., 255.);
        }
    }
    else if(numinputs == 3)
    {
        for(vtkIdType id = 0; id < nvals; ++id)
        {
            double val1 = ClampColor(data1->GetTuple1(id));
            double val2 = ClampColor(data2->GetTuple1(id));
            double val3 = ClampColor(data3->GetTuple1(id));
            dv->SetTuple4(id, val1, val2, val3, 255.);
        }
    }
    else if(numinputs == 4)
    {
        for(vtkIdType id = 0; id < nvals; ++id)
        {
            double val1 = ClampColor(data1->GetTuple1(id));
            double val2 = ClampColor(data2->GetTuple1(id));
            double val3 = ClampColor(data3->GetTuple1(id));
            double val4 = ClampColor(data4->GetTuple1(id));
            dv->SetTuple4(id, val1, val2, val3, val4);
        }
    }

    return dv;
}
void
avtShapeletDecompositionQuery::Execute(vtkDataSet *ds, const int dom)
{
    // clear any prev result
    if(decompResult)
    {
        delete decompResult;
        decompResult = NULL;
    }
    
    // make sure set is rectilinear
    if (ds->GetDataObjectType() != VTK_RECTILINEAR_GRID)
    {
        EXCEPTION1(VisItException, 
                   "The Shapelet Decomposition Query only operates on 2D"
                   " rectilinear grids.");
    }
    
    vtkRectilinearGrid *rgrid = (vtkRectilinearGrid *) ds;
    int dims[3];
    rgrid->GetDimensions(dims);
    
    if (dims[2] > 1)
    {
        EXCEPTION2(InvalidDimensionsException, "Shapelet Decomposition",
                                               "2-dimensional");
    }
    
    // make sure this is a zonal varaible
    std::string var = queryAtts.GetVariables()[0];
    
    
    vtkDataArray *vals = rgrid->GetCellData()->GetArray(var.c_str());
    if(!vals)
    {   
        EXCEPTION1(InvalidVariableException, var.c_str());
    }
    
    
    // get width & height
    int width  = dims[0]-1;
    int height = dims[1]-1;
   
    recompError = 1.0; // set error to 1.0 (max)
    // create basis set
    avtShapeletBasisSet basis_set(beta,nmax,width,height);
   
    avtShapeletDecompose   decomp;
    avtShapeletReconstruct recomp;
    // do decomp  

    decompResult = decomp.Execute(rgrid,var,&basis_set);
    
    if(decompResult)
    {
        // do recomp
        vtkRectilinearGrid *recomp_res = recomp.Execute(decompResult,var,&basis_set);
        // calc error
       
        recompError = ComputeError(rgrid,recomp_res,var);
        
        if(recompOutputFileName != "")
        {
            // save output 
            vtkVisItUtility::WriteDataSet(recomp_res, 
                                          recompOutputFileName.c_str());
        }
        // delete recomp image
        recomp_res->Delete();
    }
    
}
void
avtArrayComposeWithBinsExpression::ProcessArguments(ArgsExpr *args,
                                        ExprPipelineState *state)
{
    // Check the number of arguments
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    nvars = (int)arguments->size()-1;

    int idx_of_list = arguments->size()-1;
    ArgExpr *listarg = (*arguments)[idx_of_list];
    ExprParseTreeNode *listTree = listarg->GetExpr();
    if (listTree->GetTypeName() != "List")
    {
        debug1 << "avtArrayComposeWithBinsExpression: second arg is not a "
               << "list: " << listTree->GetTypeName() << endl;
        EXCEPTION2(ExpressionException, outputVariableName, 
                   "the last argument to array_compose_"
                   "with_bins must be a list");
    }

    ListExpr *list = dynamic_cast<ListExpr*>(listTree);
    std::vector<ListElemExpr*> *elems = list->GetElems();
    binRanges.resize(elems->size());
    if ((int)elems->size() != nvars+1)
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
                   "the list for array_compose_with_bins"
                   " must have one more number than there are variables. "
                   " For two variables (V1 and V2), there should be a list of"
                   " size 3: [L0, L1, L2].  V1's bin goes from L0 to L1, "
                   "and V2's bin goes from L1 to L2.");
    }
    for (size_t i = 0 ; i < elems->size() ; i++)
    {
        if ((*elems)[i]->GetEnd())
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                       "the list for array_compose_with"
                       "_bins expression cannot contain ranges.");
        }

        ExprNode *item = (*elems)[i]->GetItem();
        if (item->GetTypeName() == "FloatConst")
        {
            ConstExpr *c = dynamic_cast<ConstExpr*>(item);
            binRanges[i] = dynamic_cast<FloatConstExpr*>(c)->GetValue();
        }
        else if (item->GetTypeName() == "IntegerConst")
        {
            ConstExpr *c = dynamic_cast<ConstExpr*>(item);
            binRanges[i] = dynamic_cast<IntegerConstExpr*>(c)->GetValue();
        }
        else 
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                       "the list for the array_compose"
                       "_with_bins expression may contain only numbers.");
        }
    }

    // Let the base class do this processing.  We only had to over-ride this
    // function to determine the number of arguments.
    avtMultipleInputExpressionFilter::ProcessArguments(args, state);
}
vtkDataArray *
avtMagnitudeExpression::DeriveVariable(vtkDataSet *in_ds, int currentDomainsIndex)
{
    //
    // The base class will set the variable of interest to be the
    // 'activeVariable'.  This is a by-product of how the base class sets its
    // input.  If that method should change (SetActiveVariable), this
    // technique for inferring the variable name may stop working.
    //
    const char *varname = activeVariable;

    vtkDataArray *vectorValues = in_ds->GetPointData()->GetArray(varname);

    if (vectorValues == NULL)
    {
        vectorValues = in_ds->GetCellData()->GetArray(varname);
    }
    if (vectorValues == NULL)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "Unable to locate variable for magnitude expression");
    }

    if (vectorValues->GetNumberOfComponents() != 3)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "Can only take magnitude of vectors.");
    }
    vtkIdType ntuples = vectorValues->GetNumberOfTuples();

    vtkDataArray *results = vectorValues->NewInstance();
    results->SetNumberOfComponents(1);
    results->SetNumberOfTuples(ntuples);

#define COMPUTE_MAG(dtype) \
{ \
    dtype *x   = (dtype*)vectorValues->GetVoidPointer(0); \
    dtype *r   = (dtype*)results->GetVoidPointer(0); \
    for (vtkIdType i = 0, idx = 0 ; i < ntuples ; i++, idx += 3) \
    { \
        r[i] = sqrt((double)x[idx+0]*(double)x[idx+0]+\
                    (double)x[idx+1]*(double)x[idx+1]+\
                    (double)x[idx+2]*(double)x[idx+2]); \
    } \
}

    if(vectorValues->HasStandardMemoryLayout())
    {
        switch(vectorValues->GetDataType())
        {
            vtkTemplateMacro(COMPUTE_MAG(VTK_TT));
        }
    }
    else
    {
        for(vtkIdType i = 0; i < ntuples ; i++)
        {
            const double *x = vectorValues->GetTuple(i);
            results->SetTuple1(i, sqrt(x[0]*x[0]+ x[1]*x[1]+ x[2]*x[2]));
        }
    }

    return results;
}