avtHistogramFilter.C 38 KB
Newer Older
hrchilds's avatar
hrchilds committed
1
2
/*****************************************************************************
*
brugger's avatar
   
brugger committed
3
* Copyright (c) 2000 - 2008, Lawrence Livermore National Security, LLC
hrchilds's avatar
hrchilds committed
4
* Produced at the Lawrence Livermore National Laboratory
brugger's avatar
   
brugger committed
5
* LLNL-CODE-400142
hrchilds's avatar
hrchilds committed
6
7
* All rights reserved.
*
brugger's avatar
   
brugger committed
8
* This file is  part of VisIt. For  details, see https://visit.llnl.gov/.  The
hrchilds's avatar
hrchilds committed
9
10
11
12
13
14
15
16
17
18
* full copyright notice is contained in the file COPYRIGHT located at the root
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
*
* Redistribution  and  use  in  source  and  binary  forms,  with  or  without
* modification, are permitted provided that the following conditions are met:
*
*  - Redistributions of  source code must  retain the above  copyright notice,
*    this list of conditions and the disclaimer below.
*  - Redistributions in binary form must reproduce the above copyright notice,
*    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
brugger's avatar
   
brugger committed
19
20
21
*    documentation and/or other materials provided with the distribution.
*  - Neither the name of  the LLNS/LLNL nor the names of  its contributors may
*    be used to endorse or promote products derived from this software without
hrchilds's avatar
hrchilds committed
22
23
24
25
26
*    specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
brugger's avatar
   
brugger committed
27
28
29
* ARE  DISCLAIMED. IN  NO EVENT  SHALL LAWRENCE  LIVERMORE NATIONAL  SECURITY,
* LLC, THE  U.S.  DEPARTMENT OF  ENERGY  OR  CONTRIBUTORS BE  LIABLE  FOR  ANY
* DIRECT,  INDIRECT,   INCIDENTAL,   SPECIAL,   EXEMPLARY,  OR   CONSEQUENTIAL
hrchilds's avatar
hrchilds committed
30
31
32
33
34
35
36
37
38
* DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
* SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
* CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
* LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
* OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*****************************************************************************/

hrchilds's avatar
hrchilds committed
39
40
41
42
43
44
45
46
// ************************************************************************* //
//                           avtHistogramFilter.C                            //
// ************************************************************************* //

#include <avtHistogramFilter.h>

#include <float.h>

hrchilds's avatar
hrchilds committed
47
#include <vtkCellData.h>
48
49
#include <vtkCellDataToPointData.h>
#include <vtkDataArray.h>
hrchilds's avatar
hrchilds committed
50
#include <vtkPointData.h>
hrchilds's avatar
hrchilds committed
51
52
#include <vtkPointDataToCellData.h>
#include <vtkPolyData.h>
hrchilds's avatar
hrchilds committed
53
54
55
56
#include <vtkUnsignedIntArray.h>

#include <PickAttributes.h>
#include <PickVarInfo.h>
hrchilds's avatar
hrchilds committed
57
58
59
60

#include <avtDataAttributes.h>
#include <avtExtents.h>
#include <avtParallel.h>
hrchilds's avatar
hrchilds committed
61
#include <avtOriginatingSource.h>
hrchilds's avatar
hrchilds committed
62

hrchilds's avatar
hrchilds committed
63
#include <BadCellException.h>
hrchilds's avatar
hrchilds committed
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <ImproperUseException.h>


// ****************************************************************************
//  Method: avtHistogramFilter constructor
//
//  Programmer: childs -- generated by xml2info
//  Creation:   Thu Jun 26 09:04:54 PDT 2003
//
// ****************************************************************************

avtHistogramFilter::avtHistogramFilter()
{
    bins = NULL;
}


// ****************************************************************************
//  Method: avtHistogramFilter destructor
//
//  Programmer: childs -- generated by xml2info
//  Creation:   Thu Jun 26 09:04:54 PDT 2003
//
// ****************************************************************************

avtHistogramFilter::~avtHistogramFilter()
{
    if (bins != NULL)
        delete [] bins;
}


// ****************************************************************************
//  Method: avtHistogramFilter::SetAttributes
//
//  Purpose:
//      Sets the attributes for this filter.
//
//  Programmer: Hank Childs
//  Creation:   June 26, 2003
//
// ****************************************************************************

void
avtHistogramFilter::SetAttributes(const HistogramAttributes &h_atts)
{
    atts = h_atts;
}


// ****************************************************************************
//  Method: avtHistogramFilter::PreExecute
//
//  Purpose:
//      Initializes for our actual execute.  Sets up the bins, etc.
//
//  Programmer: Hank Childs
//  Creation:   June 26, 2003
//
hrchilds's avatar
hrchilds committed
123
124
125
126
//  Modifications:
//
//    Hank Childs, Wed May 24 10:18:09 PDT 2006
//    Add support for array variables.
127
128
129
//    
//    Dave Pugmire, Thu Nov 01 12:39:07 EDT 2007
//    Support for log, sqrt scaling.
hrchilds's avatar
hrchilds committed
130
//
131
132
133
//    Hank Childs, Wed Mar  5 09:54:20 PST 2008
//    Don't get the data range if the min and max are already specified.
//
hrchilds's avatar
hrchilds committed
134
135
136
137
138
// ****************************************************************************

void
avtHistogramFilter::PreExecute(void)
{
139
    avtDataTreeIterator::PreExecute();
hrchilds's avatar
hrchilds committed
140
141
142

    InputSetActiveVariable(pipelineVariable);

hrchilds's avatar
hrchilds committed
143
    if (atts.GetBasedOn() == HistogramAttributes::ManyZonesForSingleVar)
hrchilds's avatar
hrchilds committed
144
    {
hrchilds's avatar
hrchilds committed
145
        bool extentsSpecified = atts.GetSpecifyRange();
146
147
        if (extentsSpecified)
            GetDataExtents(dataValueRange, pipelineVariable);
148

149
150
151
152
        SetWorkingMin( (extentsSpecified ? atts.GetMin() : dataValueRange[0]) );
        SetWorkingMax( (extentsSpecified ? atts.GetMax() : dataValueRange[1]) );
        SetWorkingNumBins( atts.GetNumBins() );
        
hrchilds's avatar
hrchilds committed
153
154
155
156
157
        if (bins != NULL)
            delete [] bins;
        bins = new float[workingNumBins];
        for (int i = 0 ; i < workingNumBins ; i++)
            bins[i] = 0.;
hrchilds's avatar
hrchilds committed
158
159
    }
    else
hrchilds's avatar
hrchilds committed
160
        workingNumBins = 0;
hrchilds's avatar
hrchilds committed
161
162
163
164
165
166
167
168
169
170
171
172
}


// ****************************************************************************
//  Method: avtHistogramFilter::PostExecute
//
//  Purpose:
//      Sets up the final curve based on the bins.
//
//  Programmer: Hank Childs
//  Creation:   June 26, 2003
//
hrchilds's avatar
hrchilds committed
173
174
175
176
177
178
179
180
//  Modifications:
//
//    Hank Childs, Sat Oct 18 11:14:06 PDT 2003
//    Make sure the limits of the histogram plot always have y=0.
//
//    Hank Childs, Sat Oct 18 11:45:13 PDT 2003
//    Make sure that the bins are of a uniform size.
//
hrchilds's avatar
hrchilds committed
181
182
183
184
//    Brad Whitlock, Thu Jul 22 17:02:11 PST 2004
//    Changed the xlabel and xunits in the output data attributes so the
//    histogram plot would have the units along the axes.
//
hrchilds's avatar
hrchilds committed
185
186
187
//    Kathleen Bonnell, Thu Jan  6 10:34:57 PST 2005 
//    Remove TRY-CATCH block in favor of testing for ValidActiveVariable.
//
hrchilds's avatar
hrchilds committed
188
189
190
//    Kathleen Bonnell, Fri May 13 11:10:35 PDT 2005 
//    Fix memory leak. 
//
hrchilds's avatar
hrchilds committed
191
192
193
//    Hank Childs, Wed May 24 11:27:24 PDT 2006
//    Add support for array variables.
//
hrchilds's avatar
hrchilds committed
194
195
196
//    Hank Childs, Thu Sep 14 09:16:23 PDT 2006
//    Fix indexing bug pointed out by Matt Wheeler.
//
hrchilds's avatar
hrchilds committed
197
198
199
//    Hank Childs, Fri Jan  5 11:49:31 PST 2007
//    Reverse indexing for bins that have negative values.
//
hrchilds's avatar
hrchilds committed
200
201
202
//    Hank Childs, Fri Jan 12 15:27:01 PST 2007
//    Use bin spacing if possible.
//
hrchilds's avatar
hrchilds committed
203
204
205
//    Cyrus Harrison, Wed Mar  7 15:46:29 PST 2007
//    Added support for point histograms and true "Frequency" histograms
//
hrchilds's avatar
hrchilds committed
206
//    Jeremy Meredith, Wed Mar 14 11:14:56 EDT 2007
207
//    Call avtDataTreeIterator::PostExecute instead of PreExecute.
hrchilds's avatar
hrchilds committed
208
//
209
210
211
//    Dave Pugmire, Thu Nov 01 12:39:07 EDT 2007
//    Support for log, sqrt scaling.    
//
212
213
214
//    Hank Childs, Wed Dec 12 21:59:49 PST 2007
//    Add support for weighting by a variable.
//
hrchilds's avatar
hrchilds committed
215
216
217
218
219
// ****************************************************************************

void
avtHistogramFilter::PostExecute(void)
{
hrchilds's avatar
hrchilds committed
220
221
    int  i;

222
    avtDataTreeIterator::PostExecute();
hrchilds's avatar
hrchilds committed
223

hrchilds's avatar
hrchilds committed
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
    if (atts.GetBasedOn() == HistogramAttributes::ManyVarsForSingleZone)
    {
        //
        // Initialize for all the processors that got no data.
        //
        workingNumBins = UnifyMaximumValue(workingNumBins);
        if (workingNumBins == 0)
        {
            EXCEPTION1(VisItException, "The histogram could not be generated."
                             "  The most likely source of error is that the "
                             "zone id or domain number is invalid.  If this"
                             " is not the case, please contact a VisIt"
                             " developer.");
        }
        if (bins == NULL)
        {
            bins = new float[workingNumBins];
            for (i = 0 ; i < workingNumBins ; i++)
                bins[i] = 0.;
        }
244
245
        workingRange[0] = 0.;
        workingRange[1] = (float)workingNumBins;
hrchilds's avatar
hrchilds committed
246
    }
hrchilds's avatar
hrchilds committed
247
248
249
250
251
252

    float *newBins = new float[workingNumBins];
    SumFloatArrayAcrossAllProcessors(bins, newBins, workingNumBins);
    for (i = 0 ; i < workingNumBins ; i++)
        bins[i] = newBins[i];

253
254
    ScaleBins();

hrchilds's avatar
hrchilds committed
255
256
    delete [] newBins;

hrchilds's avatar
hrchilds committed
257
258
259
260
261
262
263
264
    if (PAR_Rank() != 0)
    {
        SetOutputDataTree(new avtDataTree());
        return;
    }

    vtkPolyData *output = vtkPolyData::New();

hrchilds's avatar
hrchilds committed
265
266
267
268
269
270
271
272
273
274
275
    bool spaceBins = false;
    vector<double> ranges;
    if (atts.GetBasedOn() == atts.ManyVarsForSingleZone)
        if (atts.GetUseBinWidths() == true)
        {
            ranges = 
                 GetInput()->GetInfo().GetAttributes().GetVariableBinRanges();
            if (ranges.size() == workingNumBins+1)
                spaceBins = true;
        }

hrchilds's avatar
hrchilds committed
276
277
278
279
    if (atts.GetOutputType() == HistogramAttributes::Curve)
    {
        vtkPoints *pts = vtkPoints::New();
        pts->SetNumberOfPoints(workingNumBins);
280
        float jump = (GetWorkingMax() - GetWorkingMin()) / (workingNumBins);
hrchilds's avatar
hrchilds committed
281
282
283
        for (i = 0 ; i < workingNumBins ; i++)
        {
            float pt[3];
hrchilds's avatar
hrchilds committed
284
285
286
            if (spaceBins)
                pt[0] = (ranges[i]+ranges[i+1])/2.;
            else
287
                pt[0] = GetWorkingMin() + (i+0.5)*jump;
hrchilds's avatar
hrchilds committed
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
            pt[1] = bins[i];
            pt[2] = 0.;
            pts->SetPoint(i, pt);
        }
    
        output->SetPoints(pts);
        pts->Delete();
    
        int nSegments = workingNumBins-1;
        output->Allocate(nSegments);
        vtkIdType line[2];
        for (int i = 0 ; i < nSegments ; i++)
        {
            line[0] = i;
            line[1] = i+1;
            output->InsertNextCell(VTK_LINE, 2, line);
        }
    }
    else
    {
        vtkPoints *pts = vtkPoints::New();
        pts->SetNumberOfPoints(4*workingNumBins);
310
        float jump = (GetWorkingMax() - GetWorkingMin()) / (workingNumBins);
hrchilds's avatar
hrchilds committed
311
312

        int ptIndex = 0;
hrchilds's avatar
hrchilds committed
313
        float pt[3] = { 0., 0., 0. };
hrchilds's avatar
hrchilds committed
314

hrchilds's avatar
hrchilds committed
315
        for (i = 0 ; i < workingNumBins ; i++)
hrchilds's avatar
hrchilds committed
316
317
318
319
        {
            //
            // Do the last two points for bin i.
            //
hrchilds's avatar
hrchilds committed
320
321
322
            if (spaceBins)
                pt[0] = ranges[i];
            else
323
                pt[0] = jump*i + GetWorkingMin();
hrchilds's avatar
hrchilds committed
324
325
326
327
328
329
330
331
332
            pt[1] = 0.;
            pts->SetPoint(ptIndex++, pt);

            pt[1] = bins[i];
            pts->SetPoint(ptIndex++, pt);
 
            //
            // Now do the first two points for bin i+1.
            //
hrchilds's avatar
hrchilds committed
333
334
335
            if (spaceBins)
                pt[0] = ranges[i+1];
            else
336
                pt[0] = jump*(i+1) + GetWorkingMin();
hrchilds's avatar
hrchilds committed
337
338
339
            pt[1] = 0.;
            pts->SetPoint(ptIndex++, pt);

hrchilds's avatar
hrchilds committed
340
            pt[1] = bins[i];
hrchilds's avatar
hrchilds committed
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
            pts->SetPoint(ptIndex++, pt);
        }
    
        output->SetPoints(pts);
        pts->Delete();
    
        int ncells = 5*workingNumBins;
        output->Allocate(ncells);

        //
        // Add the line segments for each bin.
        //
        vtkIdType line[2];
        for (i = 0 ; i < workingNumBins ; i++)
        {
            line[0] = 4*i;
            line[1] = 4*i+1;
            output->InsertNextCell(VTK_LINE, 2, line);
            line[0] = 4*i+2;
            line[1] = 4*i+3;
            output->InsertNextCell(VTK_LINE, 2, line);
            line[0] = 4*i;
            line[1] = 4*i+2;
            output->InsertNextCell(VTK_LINE, 2, line);
            line[0] = 4*i+1;
            line[1] = 4*i+3;
            output->InsertNextCell(VTK_LINE, 2, line);
        }

        //
        // Now add the polygons in the middle.
        //
hrchilds's avatar
hrchilds committed
373
        vtkIdType quad[4];
hrchilds's avatar
hrchilds committed
374
375
        for (int i = 0 ; i < workingNumBins ; i++)
        {
hrchilds's avatar
hrchilds committed
376
377
378
379
380
381
382
383
384
385
386
387
388
389
            if (bins[i] >= 0.)
            {
                quad[0] = 4*i;
                quad[1] = 4*i+2;
                quad[2] = 4*i+3;
                quad[3] = 4*i+1;
            }
            else
            {
                quad[0] = 4*i;
                quad[1] = 4*i+1;
                quad[2] = 4*i+3;
                quad[3] = 4*i+2;
            }
hrchilds's avatar
hrchilds committed
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
            output->InsertNextCell(VTK_QUAD, 4, quad);
        }
    }

    SetOutputDataTree(new avtDataTree(output, -1));
    output->Delete();

    //
    // Set up the extents of the output.
    //
    float low = +FLT_MAX;
    float hi  = -FLT_MAX;
    for (i = 0 ; i < workingNumBins ; i++)
    {
        low = (low < bins[i] ? low : bins[i]);
        hi  = (hi  > bins[i] ? hi  : bins[i]);
    }
    double extents[6];
hrchilds's avatar
hrchilds committed
408
409
410
411
412
413
414
    if (spaceBins)
    {
        extents[0] = ranges[0];
        extents[1] = ranges[workingNumBins];
    }
    else
    {
415
416
        extents[0] = GetWorkingMin();
        extents[1] = GetWorkingMax();
hrchilds's avatar
hrchilds committed
417
    }
hrchilds's avatar
hrchilds committed
418
419
420
421
    if (atts.GetBasedOn() == HistogramAttributes::ManyZonesForSingleVar)
        extents[2] = 0.;  // We always start from 0.  lo is misleading.
    else
        extents[2] = (low < 0. ? low : 0.);
hrchilds's avatar
hrchilds committed
422
423
424
    extents[3] = hi;
    extents[4] = extents[5] = 0.;

hrchilds's avatar
hrchilds committed
425
426
427
    // Try to do something reasonable if we have constant data.
    if (extents[0] == extents[1])
    {
428
429
        extents[0] = GetWorkingMin() - hi/2.;
        extents[1] = GetWorkingMax() + hi/2.;
hrchilds's avatar
hrchilds committed
430
431
    }

hrchilds's avatar
hrchilds committed
432
433
434
435
436
437
    avtDataAttributes &outAtts = GetOutput()->GetInfo().GetAttributes();
    outAtts.GetTrueSpatialExtents()->Set(extents);
    outAtts.GetCumulativeTrueSpatialExtents()->Set(extents);
    outAtts.GetEffectiveSpatialExtents()->Set(extents);
    outAtts.GetCurrentSpatialExtents()->Set(extents);
    outAtts.GetCumulativeCurrentSpatialExtents()->Set(extents);
hrchilds's avatar
hrchilds committed
438

hrchilds's avatar
hrchilds committed
439
440
441
    //
    // Set the X-axis's units to match the variable units.
    // 
hrchilds's avatar
hrchilds committed
442
    if (GetInput()->GetInfo().GetAttributes().ValidActiveVariable())
hrchilds's avatar
hrchilds committed
443
444
445
    {
        if(GetInput()->GetInfo().GetAttributes().GetVariableUnits() != "")
        {
446
447
448
449
450
451
452
453
            string xlabel = "";
            if ( atts.GetDataScale() == HistogramAttributes::Linear )
                xlabel = string( "Variable " ) + pipelineVariable;
            else if ( atts.GetDataScale() == HistogramAttributes::Log )
                xlabel = string( "Variable log10(" ) + pipelineVariable + string(") ");
            if ( atts.GetDataScale() == HistogramAttributes::SquareRoot )
                xlabel = string( "Variable sqrt(" ) + pipelineVariable + string(") ");
            
454
            outAtts.SetXLabel( xlabel );
hrchilds's avatar
hrchilds committed
455
456
457
            outAtts.SetXUnits(GetInput()->GetInfo().GetAttributes().GetVariableUnits());
        }
        else
458
459
460
461
462
463
464
465
        {
            string str = "";
            if ( atts.GetDataScale() == HistogramAttributes::Linear )
                str = pipelineVariable;
            else if ( atts.GetDataScale() == HistogramAttributes::Log )
                str = string( "log10(" ) + pipelineVariable + string(") ");
            if ( atts.GetDataScale() == HistogramAttributes::SquareRoot )
                str = string( "sqrt(" ) + pipelineVariable + string(") ");            
466
            outAtts.SetXUnits(str );
467
        }
hrchilds's avatar
hrchilds committed
468
469
    }

hrchilds's avatar
hrchilds committed
470
    if (atts.GetBasedOn() == HistogramAttributes::ManyVarsForSingleZone)
hrchilds's avatar
hrchilds committed
471
    {
hrchilds's avatar
hrchilds committed
472
473
        outAtts.SetYLabel("Value");
        outAtts.SetYUnits("");
hrchilds's avatar
hrchilds committed
474
475
476
    }
    else
    {
hrchilds's avatar
hrchilds committed
477
        int topo = GetInput()->GetInfo().GetAttributes().GetTopologicalDimension();
hrchilds's avatar
hrchilds committed
478
        string yunits = "";
479
        if (atts.GetHistogramType() == HistogramAttributes::Frequency)
hrchilds's avatar
hrchilds committed
480
        {
481
            if (topo == 0)
hrchilds's avatar
hrchilds committed
482
                yunits = "# of Points";
hrchilds's avatar
hrchilds committed
483
            else
hrchilds's avatar
hrchilds committed
484
485
                yunits = "# of Cells";
        }
486
        else if (atts.GetHistogramType() == HistogramAttributes::Weighted)
hrchilds's avatar
hrchilds committed
487
        {
488
489
490
491
492
493
            // For particles, pretend we have frequency.
            if (topo == 0)
            {
                yunits = "# of Points";
            }
            else if (topo==3)
hrchilds's avatar
hrchilds committed
494
495
496
497
498
            {
                yunits = "Volume";
            }
            else // topo = 2 
            {
499
                if (GetInput()->GetInfo().GetAttributes().GetMeshCoordType() == AVT_XY)
hrchilds's avatar
hrchilds committed
500
501
502
503
                    yunits = "Area";
                else
                    yunits = "Revolved Volume";
            }
hrchilds's avatar
hrchilds committed
504
        }
505
506
507
508
509
510
511
        else
        {
            if (atts.GetWeightVariable() == "default")
                yunits = pipelineVariable;
            else
                yunits = atts.GetWeightVariable();
        }
512
513
514
515
516
        string str = yunits;
        if ( atts.GetBinScale() == HistogramAttributes::Log )
            str = "log10(" + yunits + ") ";
        else if ( atts.GetBinScale() == HistogramAttributes::SquareRoot )
            str = "sqrt(" + yunits + ") ";
517
518

        outAtts.SetYUnits(str);
hrchilds's avatar
hrchilds committed
519
    }
hrchilds's avatar
hrchilds committed
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
}


// ****************************************************************************
//  Method: avtHistogramFilter::ExecuteData
//
//  Purpose:
//      Does the actual VTK code to modify the dataset.
//
//  Arguments:
//      inDS      The input dataset.
//      <unused>  The domain number.
//      <unused>  The label.
//
//  Returns:      The output dataset.
//
//  Programmer: childs -- generated by xml2info
//  Creation:   Thu Jun 26 09:04:54 PDT 2003
//
hrchilds's avatar
hrchilds committed
539
540
541
542
543
//  Modifications:
//
//    Hank Childs, Sat Oct 18 11:41:13 PDT 2003
//    Make the bins be uniform in size.
//
hrchilds's avatar
hrchilds committed
544
545
//    Hank Childs, Wed May 24 09:57:40 PDT 2006
//    Add support for taking a histogram based on an array variable.
hrchilds's avatar
hrchilds committed
546
547
548
//  
//    Cyrus Harrison, Thu Mar  8 08:08:38 PST 2007
//    Add support for point histograms and frequency histograms
hrchilds's avatar
hrchilds committed
549
//
550
551
552
//    Hank Childs, Tue Dec 11 20:25:22 PST 2007
//    Add support for variable weighting.
//
hrchilds's avatar
hrchilds committed
553
554
555
// ****************************************************************************

vtkDataSet *
hrchilds's avatar
hrchilds committed
556
557
avtHistogramFilter::ExecuteData(vtkDataSet *inDS, int chunk, std::string)
{
hrchilds's avatar
hrchilds committed
558
    if (atts.GetBasedOn() == HistogramAttributes::ManyVarsForSingleZone)
hrchilds's avatar
hrchilds committed
559
    {
hrchilds's avatar
hrchilds committed
560
        ArrayVarExecute(inDS,chunk);
hrchilds's avatar
hrchilds committed
561
    }
562
563
564
565
566
    else if (atts.GetHistogramType() == HistogramAttributes::Frequency)
    {
        FreqzExecute(inDS);
    }
    else if (atts.GetHistogramType() == HistogramAttributes::Weighted)
hrchilds's avatar
hrchilds committed
567
    {
568
        if (GetInput()->GetInfo().GetAttributes().GetTopologicalDimension() == 0)
hrchilds's avatar
hrchilds committed
569
570
571
572
            FreqzExecute(inDS);
        else
            WeightedExecute(inDS);
    }
573
    else if (atts.GetHistogramType() == HistogramAttributes::Variable)
hrchilds's avatar
hrchilds committed
574
    {
575
        VariableExecute(inDS);
hrchilds's avatar
hrchilds committed
576
577
578
579
580
    }
    return NULL;
}

// ****************************************************************************
hrchilds's avatar
hrchilds committed
581
//  Method: avtHistogramFilter::FreqzExecute
hrchilds's avatar
hrchilds committed
582
583
//
//  Purpose:
hrchilds's avatar
hrchilds committed
584
//      Standard Frequency Histogram (bins accumlate cell or point counts)
hrchilds's avatar
hrchilds committed
585
//
hrchilds's avatar
hrchilds committed
586
587
588
589
//  Notes: Based on Hank's old StandardExecute method
//
//  Programmer: Cyrus Harrison
//  Creation:   March 7, 2007
hrchilds's avatar
hrchilds committed
590
//
hrchilds's avatar
hrchilds committed
591
592
593
594
595
//  Modifications:
//
//    Hank Childs, Mon Oct 22 15:58:59 PDT 2007
//    Ignore ghost data.
//
596
597
598
//    Dave Pugmire, Thu Nov 01 12:39:07 EDT 2007
//    Support for log, sqrt scaling.    
//
599
600
601
//    Hank Childs, Wed Mar  5 10:17:00 PST 2008
//    Don't recenter nodal data to be zonal.
//
hrchilds's avatar
hrchilds committed
602
// ****************************************************************************
hrchilds's avatar
hrchilds committed
603

hrchilds's avatar
hrchilds committed
604
void
hrchilds's avatar
hrchilds committed
605
avtHistogramFilter::FreqzExecute(vtkDataSet *inDS)
hrchilds's avatar
hrchilds committed
606
607
{
    //
hrchilds's avatar
hrchilds committed
608
609
610
    // Get the variable that we are binning by.
    //
    const char *var = pipelineVariable;
611
612
    vtkDataArray *bin_arr = inDS->GetPointData()->GetArray(var);
    if (bin_arr == NULL)
hrchilds's avatar
hrchilds committed
613
614
615
616
        bin_arr = inDS->GetCellData()->GetArray(var);
    if (bin_arr == NULL)
        EXCEPTION0(ImproperUseException);

hrchilds's avatar
hrchilds committed
617
618
619
620
621
622
623
624
625
    unsigned char *ghosts = NULL;
    if (inDS->GetCellData()->GetArray("avtGhostZones") != NULL)
    {
        vtkUnsignedCharArray *g = (vtkUnsignedCharArray *)
                            inDS->GetCellData()->GetArray("avtGhostZones");
        if (g->GetNumberOfTuples() == bin_arr->GetNumberOfTuples())
            ghosts = g->GetPointer(0);
    }

hrchilds's avatar
hrchilds committed
626
627
628
629
630
631
    //
    // Now we will walk through each value and sort them into bins.
    //
    int nvals = bin_arr->GetNumberOfTuples();
    for (int i = 0 ; i < nvals ; i++)
    {
hrchilds's avatar
hrchilds committed
632
633
        if (ghosts != NULL && ghosts[i] != '\0')
            continue;
hrchilds's avatar
hrchilds committed
634
        float val = bin_arr->GetTuple1(i);
635
636
637
        int index = ComputeBinIndex( val );
        if ( index < 0 )
            continue;
638

hrchilds's avatar
hrchilds committed
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
        if (index >= workingNumBins)
            index = workingNumBins-1;
        bins[index] += 1;
    }
}


// ****************************************************************************
//  Method: avtHistogramFilter::WeightedExecute
//
//  Purpose:
//      Weighted Histogram (bins accumlate area of volume of cells)
//
//  Notes: Based on Hank's old StandardExecute method
//
//  Programmer: Cyrus Harrison
//  Creation:   March 7, 2007
//
hrchilds's avatar
hrchilds committed
657
658
659
660
661
//  Modifications:
//
//    Hank Childs, Mon Oct 22 15:58:59 PDT 2007
//    Ignore ghost data.
//
662
663
//    Dave Pugmire, Thu Nov 01 12:39:07 EDT 2007
//    Support for log, sqrt scaling.    
664
//
hrchilds's avatar
hrchilds committed
665
// ****************************************************************************
hrchilds's avatar
hrchilds committed
666

hrchilds's avatar
hrchilds committed
667
668
669
void
avtHistogramFilter::WeightedExecute(vtkDataSet *inDS)
{
hrchilds's avatar
hrchilds committed
670
671
672
673
674
675
676
677
678
679
680
681
    // Get the "_amounts".  This is the area or volume that each cell
    // takes up.
    //
    vtkDataArray *amount_arr = inDS->GetCellData()->GetArray("_amounts");
    if (amount_arr == NULL)
        EXCEPTION0(ImproperUseException);
    //
    // Get the variable that we are binning by.
    //
    const char *var = pipelineVariable;
    vtkDataArray *bin_arr = NULL;
    bool ownBinArr = false;
hrchilds's avatar
hrchilds committed
682
683
684
685
686
687
688

    if(GetInput()->GetInfo().GetAttributes().GetTopologicalDimension() == 0)
    {
        // weighted case does not make sense for point data
        EXCEPTION0(ImproperUseException);
    }
    
hrchilds's avatar
hrchilds committed
689
    if (inDS->GetPointData()->GetArray(var) != NULL)
hrchilds's avatar
hrchilds committed
690
    {
hrchilds's avatar
hrchilds committed
691
        // in the 2d or 3d case make sure to get zone centered data
hrchilds's avatar
hrchilds committed
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
        //
        // The input is point-centered, but we would prefer zone-centered.
        //
        vtkDataSet *new_in_ds = (vtkDataSet *) inDS->NewInstance();
        new_in_ds->CopyStructure(inDS);
        new_in_ds->GetPointData()->AddArray(
                                          inDS->GetPointData()->GetArray(var));
        vtkPointDataToCellData *pd2cd = vtkPointDataToCellData::New();
        pd2cd->SetInput(new_in_ds);
        pd2cd->Update();

        bin_arr = pd2cd->GetOutput()->GetCellData()->GetArray(var);
        bin_arr->Register(NULL);
        ownBinArr = true;

        new_in_ds->Delete();
        pd2cd->Delete();
    }
    else
    {
        bin_arr = inDS->GetCellData()->GetArray(var);
    }
    if (bin_arr == NULL)
        EXCEPTION0(ImproperUseException);

hrchilds's avatar
hrchilds committed
717
718
719
720
721
722
723
724
725
    unsigned char *ghosts = NULL;
    if (inDS->GetCellData()->GetArray("avtGhostZones") != NULL)
    {
        vtkUnsignedCharArray *g = (vtkUnsignedCharArray *)
                            inDS->GetCellData()->GetArray("avtGhostZones");
        if (g->GetNumberOfTuples() == bin_arr->GetNumberOfTuples())
            ghosts = g->GetPointer(0);
    }

hrchilds's avatar
hrchilds committed
726
727
728
729
    //
    // Now we will walk through each value and sort them into bins.
    //
    int nvals = bin_arr->GetNumberOfTuples();
730
    
hrchilds's avatar
hrchilds committed
731
732
    for (int i = 0 ; i < nvals ; i++)
    {
hrchilds's avatar
hrchilds committed
733
734
        if (ghosts != NULL && ghosts[i] != '\0')
            continue;
735
736
737
738
        float val = bin_arr->GetTuple1(i);
        int index = ComputeBinIndex( val );
        if ( index < 0 )
            continue;
hrchilds's avatar
hrchilds committed
739
740
        if (index >= workingNumBins)
            index = workingNumBins-1;
hrchilds's avatar
hrchilds committed
741
742
743
744
745
746
        float amount = amount_arr->GetTuple1(i);
        bins[index] += amount;
    }

    if (ownBinArr)
        bin_arr->Delete();
hrchilds's avatar
hrchilds committed
747
}
hrchilds's avatar
hrchilds committed
748

hrchilds's avatar
hrchilds committed
749

750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
// ****************************************************************************
//  Method: avtHistogramFilter::VariableExecute
//
//  Purpose:
//      Histogram weighted by a variable
//
//  Programmer: Hank Childs
//  Creation:   December 11, 2007
//
// ****************************************************************************

void
avtHistogramFilter::VariableExecute(vtkDataSet *inDS)
{
    const char *histIndexVarName = pipelineVariable;
    const char *weightVarName    = atts.GetWeightVariable().c_str();
    if (strcmp(weightVarName, "default") == 0)
        weightVarName = histIndexVarName;

    bool histIndexVarIsZonal = false;
    bool weightVarIsZonal    = false;

    if (inDS->GetCellData()->GetArray(histIndexVarName) != NULL)
        histIndexVarIsZonal = true;
    else if (inDS->GetPointData()->GetArray(histIndexVarName) == NULL)
    {
        EXCEPTION0(ImproperUseException);
    }
    if (inDS->GetCellData()->GetArray(weightVarName) != NULL)
        weightVarIsZonal = true;
    else if (inDS->GetPointData()->GetArray(weightVarName) == NULL)
    {
        EXCEPTION0(ImproperUseException);
    }

    int           nvals        = 0;
    vtkDataArray *histIndexVar = NULL;
    vtkDataArray *weightVar    = NULL;
    bool          ownWeightVar = false;
    if (histIndexVarIsZonal == weightVarIsZonal)
    {
        if (histIndexVarIsZonal)
        {
            nvals        = inDS->GetNumberOfCells();
            histIndexVar = inDS->GetCellData()->GetArray(histIndexVarName);
            weightVar    = inDS->GetCellData()->GetArray(weightVarName);
        }
        else
        {
            nvals        = inDS->GetNumberOfPoints();
            histIndexVar = inDS->GetPointData()->GetArray(histIndexVarName);
            weightVar    = inDS->GetPointData()->GetArray(weightVarName);
        }
    }
    else
    {
        // Recenter to the the same centering as the histogram index variable.
        vtkDataSet *new_in_ds = (vtkDataSet *) inDS->NewInstance();
        new_in_ds->CopyStructure(inDS);

        if (histIndexVarIsZonal)
        {
            nvals        = inDS->GetNumberOfCells();
            histIndexVar = inDS->GetCellData()->GetArray(histIndexVarName);
            new_in_ds->GetPointData()->AddArray(
                                inDS->GetPointData()->GetArray(weightVarName));
            vtkPointDataToCellData *pd2cd = vtkPointDataToCellData::New();
            pd2cd->SetInput(new_in_ds);
            pd2cd->Update();
            weightVar = pd2cd->GetOutput()->GetCellData()->GetArray(weightVarName);
            weightVar->Register(NULL);
            pd2cd->Delete();
        }
        else
        {
            nvals        = inDS->GetNumberOfPoints();
            histIndexVar = inDS->GetPointData()->GetArray(histIndexVarName);
            new_in_ds->GetCellData()->AddArray(
                                inDS->GetCellData()->GetArray(weightVarName));
            vtkCellDataToPointData *cd2pd = vtkCellDataToPointData::New();
            cd2pd->SetInput(new_in_ds);
            cd2pd->Update();
            weightVar = cd2pd->GetOutput()->GetPointData()->GetArray(weightVarName);
            weightVar->Register(NULL);
            cd2pd->Delete();
        }

        new_in_ds->Delete();
        ownWeightVar = true;
    }

    unsigned char *ghosts = NULL;
    if (inDS->GetCellData()->GetArray("avtGhostZones") != NULL)
    {
        vtkUnsignedCharArray *g = (vtkUnsignedCharArray *)
                            inDS->GetCellData()->GetArray("avtGhostZones");
        if (g->GetNumberOfTuples() == nvals)
            ghosts = g->GetPointer(0);
    }

    //
    // Now we will walk through each value and sort them into bins.
    //
    for (int i = 0 ; i < nvals ; i++)
    {
        if (ghosts != NULL && ghosts[i] != '\0')
            continue;
857
858
859
860
        float val = histIndexVar->GetTuple1(i);
        int index = ComputeBinIndex( val );
        if ( index < 0 )
            continue;
861
862
863
864
865
866
867
868
869
870
871
        if (index >= workingNumBins)
            index = workingNumBins-1;
        float amount = weightVar->GetTuple1(i);
        bins[index] += amount;
    }

    if (ownWeightVar)
        weightVar->Delete();
}


hrchilds's avatar
hrchilds committed
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
// ****************************************************************************
//  Method: avtHistogramFilter::ArrayVarExecute
//
//  Purpose:
//      Take a histogram by finding the right zone and creating a histogram
//      from its array variables.
//
//  Programmer: Hank Childs
//  Creation:   May 24, 2006
//
// ****************************************************************************

void
avtHistogramFilter::ArrayVarExecute(vtkDataSet *inDS, int chunk)
{
    int domain = atts.GetDomain();
    int blockOrigin = GetInput()->GetInfo().GetAttributes().GetBlockOrigin();
    domain -= blockOrigin;
    if (chunk != domain)
        return;

    vtkDataArray *arr = inDS->GetCellData()->GetArray(pipelineVariable);
    if (arr == NULL)
    {
        // "Cell" data is stored as point data for point meshes.
        arr = inDS->GetPointData()->GetArray(pipelineVariable);
        if (arr == NULL)
            EXCEPTION0(ImproperUseException);
    }

    vtkUnsignedIntArray *cid = (vtkUnsignedIntArray *) 
                       inDS->GetCellData()->GetArray("avtOriginalCellNumbers");
    if (cid == NULL)
    {
        // This should come down because we requested it in the data
        // specification.
        EXCEPTION0(ImproperUseException);
    }
    int ncomps = cid->GetNumberOfComponents();
    int compOffset = ncomps-1; // 0 if 1 comp, 1 if 2 comps
    unsigned int *ptr = cid->GetPointer(0);

    // Pick returns with cell origin, but avtOriginalCellNumbers does not
    // have a cell origin.  So subtract it off here.
    int zone = atts.GetZone();
    int cellOrigin  = GetInput()->GetInfo().GetAttributes().GetCellOrigin();
    zone -= cellOrigin;
    int ncells = inDS->GetNumberOfCells();
    for (int i = 0 ; i < ncells ; i++)
    {
        if (ptr[ncomps*i + compOffset] == zone)
        {
            workingNumBins = arr->GetNumberOfComponents();
            double *vals = new double[workingNumBins];

            arr->GetTuple(i, vals);

            if (bins != NULL)
                delete [] bins;

            bins = new float[workingNumBins];
            for (int i = 0 ; i < workingNumBins ; i++)
            {
                bins[i] = vals[i];
            }
            delete [] vals;
        }
    }
hrchilds's avatar
hrchilds committed
940
941
942
943
}


// ****************************************************************************
hrchilds's avatar
hrchilds committed
944
//  Method: avtHistogramFilter::UpdateDataObjectInfo
hrchilds's avatar
hrchilds committed
945
946
947
948
949
950
951
952
//
//  Purpose:
//      Allows the filter to change its output's data object information, which
//      is a description of the data object.
//
//  Programmer: childs -- generated by xml2info
//  Creation:   Thu Jun 26 09:04:54 PDT 2003
//
hrchilds's avatar
hrchilds committed
953
//  Modifications:
hrchilds's avatar
hrchilds committed
954
955
//    Kathleen Bonnell, Thu Aug 12 08:44:36 PDT 2004
//    Allow this plot to be queryable.
hrchilds's avatar
hrchilds committed
956
//
hrchilds's avatar
hrchilds committed
957
958
959
// ****************************************************************************

void
hrchilds's avatar
hrchilds committed
960
avtHistogramFilter::UpdateDataObjectInfo(void)
hrchilds's avatar
hrchilds committed
961
962
963
964
965
966
967
968
969
970
971
972
973
{
    avtDataAttributes &outAtts     = GetOutput()->GetInfo().GetAttributes();
    avtDataValidity   &outValidity = GetOutput()->GetInfo().GetValidity();
 
    outAtts.SetTopologicalDimension(1);
    outAtts.SetSpatialDimension(2);
    outValidity.InvalidateZones();
    outValidity.SetNormalsAreInappropriate(true);
    outValidity.InvalidateSpatialMetaData();
    outValidity.SetPointsWereTransformed(true);
}


hrchilds's avatar
hrchilds committed
974
// ****************************************************************************
hrchilds's avatar
hrchilds committed
975
//  Method: avtHistogramFilter::ModifyContract
hrchilds's avatar
hrchilds committed
976
977
978
979
980
981
982
983
984
//
//  Purpose:
//      Tells the input that we don't want ghost zones.  They cost time to
//      calculate (in some cases) and skew results towards the domain
//      boundaries.
//
//  Programmer: Hank Childs
//  Creation:   October 18, 2003
//
hrchilds's avatar
hrchilds committed
985
986
987
988
989
990
991
//  Modifications:
//
//    Hank Childs, Wed Aug 11 09:01:27 PDT 2004
//    Allow the input to have ghost zones, so that we can play better with 
//    other filters.  The histogram filter will now remove ghost zones before
//    executing.
//
hrchilds's avatar
hrchilds committed
992
993
994
//    Hank Childs, Wed May 24 09:44:51 PDT 2006
//    Better support for array variables.
//
995
996
997
//    Hank Childs, Tue Dec 11 20:25:22 PST 2007
//    Add support for weighting by a variable.
//
998
999
1000
1001
1002
//    Hank Childs, Tue Feb 19 19:45:43 PST 2008
//    Rename "dynamic" to "streaming", since we really care about whether we
//    are streaming, not about whether we are doing dynamic load balancing.
//    And the two are no longer synonymous.
//
hrchilds's avatar
hrchilds committed
1003
1004
// ****************************************************************************

hrchilds's avatar
hrchilds committed
1005
1006
avtContract_p
avtHistogramFilter::ModifyContract(avtContract_p spec)
hrchilds's avatar
hrchilds committed
1007
{
hrchilds's avatar
hrchilds committed
1008
    avtContract_p newspec = new avtContract(spec);
hrchilds's avatar
hrchilds committed
1009
1010
    if (atts.GetBasedOn() == HistogramAttributes::ManyZonesForSingleVar)
    {
1011
        newspec->NoStreaming();
1012
1013
1014
1015

        if (atts.GetHistogramType() == HistogramAttributes::Variable)
        {
            if (atts.GetWeightVariable() != "default")
hrchilds's avatar
hrchilds committed
1016
                newspec->GetDataRequest()->AddSecondaryVariable(
1017
1018
                                             atts.GetWeightVariable().c_str());
        }
hrchilds's avatar
hrchilds committed
1019
1020
1021
    }
    else
    {
hrchilds's avatar
hrchilds committed
1022
        newspec->GetDataRequest()->TurnZoneNumbersOn();
hrchilds's avatar
hrchilds committed
1023
        avtSILRestriction_p silr = 
hrchilds's avatar
hrchilds committed
1024
                             newspec->GetDataRequest()->GetRestriction();
hrchilds's avatar
hrchilds committed
1025
1026
1027
1028
1029
1030
1031
1032
1033
        int domain = atts.GetDomain();
        int blockOrigin = GetInput()->GetInfo().GetAttributes().GetBlockOrigin();
        domain -= blockOrigin;

        vector<int> domain_list;
        domain_list.push_back(domain);
        silr->TurnOnAll();
        silr->RestrictDomains(domain_list);
    }
hrchilds's avatar
hrchilds committed
1034
1035
1036
1037
1038

    return newspec;
}


1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
// ****************************************************************************
//  Method: avtHistogramFilter::ComputeBinIndex
//
//  Purpose:
//      Compute the bin index for the given input value.
//
//  Programmer: Dave Pugmire
//  Creation:   November 01, 2007
//
// ****************************************************************************

int
avtHistogramFilter::ComputeBinIndex( const float &value ) const
{
    // Value out of bounds, just return.
    if ( value < workingRange[0] || value > workingRange[1] )
1055
        return -1;
1056
1057
1058

    // If we have a zero range, return 0
    if ( workingRange[0] == workingRange[1] )
1059
        return 0;
1060
1061
1062
1063
    
    int index = 0;
    if ( atts.GetDataScale() == HistogramAttributes::Linear )
    {
1064
        index = (int)((value - workingRange[0]) / binStep);
1065
1066
1067
    }
    else if ( atts.GetDataScale() == HistogramAttributes::SquareRoot )
    {
1068
1069
1070
        float sign = (value < 0 ? -1.0 : 1.0);
        float x = sign * sqrt( fabs(value) );
        index = (int)((x - sqrtWorkingRange[0]) / sqrtBinStep);        
1071
1072
1073
    }
    else if ( atts.GetDataScale() == HistogramAttributes::Log )
    {
1074
1075
1076
        float sign = (value < 0 ? -1.0 : 1.0);
        float x = sign * log10( fabs( value ) + 1.0 );
        index = (int)((x - logWorkingRange[0]) / logBinStep);
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
    }

    return index;
}

// ****************************************************************************
//  Method: avtHistogramFilter::ScaleBins
//
//  Purpose:
//      Scale the bins based on the attributes.
//
//  Programmer: Dave Pugmire
//  Creation:   November 01, 2007
//
// ****************************************************************************

void
avtHistogramFilter::ScaleBins()
{
    if ( atts.GetBinScale() == HistogramAttributes::Linear )
1097
        return;
1098
1099
    else if ( atts.GetBinScale() == HistogramAttributes::Log )
    {
1100
1101
1102
1103
1104
1105
1106
        for ( int i = 0; i < workingNumBins; i++ )
        {
            float x = bins[i];
            if ( x > 0.0 )
                x = log10(x);
            bins[i] = x;
        }
1107
1108
1109
    }
    else if ( atts.GetBinScale() == HistogramAttributes::SquareRoot )
    {
1110
1111
        for ( int i = 0; i < workingNumBins; i++ )
            bins[i] = sqrt( bins[i] );
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
    }    
}

// ****************************************************************************
//  Method: avtHistogramFilter::SetWorkingMin
//
//  Purpose:
//      Set the working mins.
//
//  Programmer: Dave Pugmire
//  Creation:   November 01, 2007
//
// ****************************************************************************

void
avtHistogramFilter::SetWorkingMin( double dataMin )
{
    workingRange[0] = dataMin;
    double abs_dataMin = fabs( dataMin );
    float sign = (dataMin < 0 ? -1.0 : 1.0);
    logWorkingRange[0] = sign * log10( abs_dataMin + 1.0 );
    sqrtWorkingRange[0] = sign * sqrt( abs_dataMin );
}

// ****************************************************************************
//  Method: avtHistogramFilter::GetWorkingMin
//
//  Purpose:
//      Get the working min based on the type of data scaling.
//
//  Programmer: Dave Pugmire
//  Creation:   November 01, 2007
//
1145
1146
1147
1148
//  Modifications:
//    Kathleen Bonnell, Tue Jan  8 17:49:47 PST 2008
//    Added default return.
//
1149
1150
1151
1152
1153
1154
1155
1156
// ****************************************************************************

double
avtHistogramFilter::GetWorkingMin() const
{
    switch ( atts.GetDataScale() )
    {
    case  HistogramAttributes::Linear:
1157
        return workingRange[0];
1158
    case  HistogramAttributes::Log:
1159
        return logWorkingRange[0];
1160
    case HistogramAttributes::SquareRoot:
1161
        return sqrtWorkingRange[0];        
1162
1163
    default:
        return workingRange[0];
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
    }
}

// ****************************************************************************
//  Method: avtHistogramFilter::SetWorkingMax
//
//  Purpose:
//      Set the working maxs.
//
//  Programmer: Dave Pugmire
//  Creation:   November 01, 2007
//
// ****************************************************************************

void
avtHistogramFilter::SetWorkingMax( double dataMax )
{
    workingRange[1] = dataMax;
    double abs_dataMax = fabs( dataMax );

    float sign = (dataMax < 0 ? -1.0 : 1.0);
    logWorkingRange[1] = sign * log10( abs_dataMax + 1.0 );
    sqrtWorkingRange[1] = sign * sqrt( abs_dataMax );
}

// ****************************************************************************
//  Method: avtHistogramFilter::GetWorkingMax
//
//  Purpose:
//      Get the working max based on the type of data scaling.
//
//  Programmer: Dave Pugmire
//  Creation:   November 01, 2007
//
1198
1199
1200
1201
//  Modifications:
//    Kathleen Bonnell, Tue Jan  8 17:49:47 PST 2008
//    Added default return.
//
1202
1203
1204
1205
1206
1207
1208
1209
// ****************************************************************************

double
avtHistogramFilter::GetWorkingMax() const
{
    switch ( atts.GetDataScale() )
    {
    case  HistogramAttributes::Linear:
1210
        return workingRange[1];
1211
    case  HistogramAttributes::Log:
1212
1213
1214
        return logWorkingRange[1];
    case HistogramAttributes::SquareRoot:        
        return sqrtWorkingRange[1];        
1215
1216
    default :
        return workingRange[1];
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
    }
}

// ****************************************************************************
//  Method: avtHistogramFilter::SetWorkingNumBins
//
//  Purpose:
//      Set the number of working bins and the bin step sizes.
//
//  Programmer: Dave Pugmire
//  Creation:   November 01, 2007
//
// ****************************************************************************

void
avtHistogramFilter::SetWorkingNumBins( int n )
{
    workingNumBins = n;
    binStep = (workingRange[1] - workingRange[0]) / workingNumBins;
    logBinStep = (logWorkingRange[1] - logWorkingRange[0] ) / workingNumBins;
    sqrtBinStep = (sqrtWorkingRange[1] - sqrtWorkingRange[0] ) / workingNumBins;
}