Allow fields of any type in NDHistogram

Use the ability to extract array components to compute bins of
dimensions.
This commit is contained in:
Kenneth Moreland 2023-02-02 14:26:32 -05:00
parent 763389bd4e
commit d38efa87f2
3 changed files with 31 additions and 84 deletions

@ -19,3 +19,4 @@ updated.
* `Contour`
* `MIRFilter`
* `PointAverage`
* `NDHistogram`

@ -41,29 +41,6 @@ public:
vtkm::cont::ArrayCopy(constant0Array, Bin1DIndex);
}
// Add a field and the bin number for this field
// Return: rangeOfRange is min max value of this array
// binDelta is delta of a bin
template <typename HandleType>
void AddField(const HandleType& fieldArray,
vtkm::Id numberOfBins,
vtkm::Range& rangeOfValues,
vtkm::Float64& binDelta)
{
NumberOfBins.push_back(numberOfBins);
if (fieldArray.GetNumberOfValues() != NumDataPoints)
{
throw vtkm::cont::ErrorBadValue("Array lengths does not match");
}
else
{
vtkm::cont::CastAndCall(
fieldArray.ResetTypes(vtkm::TypeListScalarAll{}, VTKM_DEFAULT_STORAGE_LIST{}),
vtkm::worklet::histogram::ComputeBins(Bin1DIndex, numberOfBins, rangeOfValues, binDelta));
}
}
// Add a field and the bin number for this field along with specific range of the data
// Return: binDelta is delta of a bin
template <typename HandleType>
@ -71,7 +48,7 @@ public:
vtkm::Id numberOfBins,
vtkm::Range& rangeOfValues,
vtkm::Float64& binDelta,
bool rangeProvided)
bool rangeProvided = false)
{
NumberOfBins.push_back(numberOfBins);
@ -81,9 +58,35 @@ public:
}
else
{
CastAndCall(fieldArray.ResetTypes(vtkm::TypeListScalarAll()),
vtkm::worklet::histogram::ComputeBins(
Bin1DIndex, numberOfBins, rangeOfValues, binDelta, rangeProvided));
auto computeBins = [&](auto resolvedField) {
// CastAndCallWithExtractedArray should give us an ArrayHandleRecombineVec
using T = typename std::decay_t<decltype(resolvedField)>::ValueType::ComponentType;
vtkm::cont::ArrayHandleRecombineVec<T> recombineField{ resolvedField };
if (recombineField.GetNumberOfComponents() != 1)
{
VTKM_LOG_S(vtkm::cont::LogLevel::Warn,
"NDHistogram expects scalar fields, but was given field with "
<< recombineField.GetNumberOfComponents()
<< " components. Extracting first component.");
}
vtkm::cont::ArrayHandleStride<T> field =
vtkm::cont::ArrayExtractComponent(recombineField, 0);
if (!rangeProvided)
{
const vtkm::Vec<T, 2> initValue(vtkm::cont::ArrayGetValue(0, field));
vtkm::Vec<T, 2> minMax =
vtkm::cont::Algorithm::Reduce(field, initValue, vtkm::MinAndMax<T>());
rangeOfValues.Min = static_cast<vtkm::Float64>(minMax[0]);
rangeOfValues.Max = static_cast<vtkm::Float64>(minMax[1]);
}
binDelta = vtkm::worklet::histogram::compute_delta(
rangeOfValues.Min, rangeOfValues.Max, numberOfBins);
vtkm::worklet::histogram::SetHistogramBin<T> binWorklet(
numberOfBins, rangeOfValues.Min, binDelta);
vtkm::cont::Invoker{}(binWorklet, field, this->Bin1DIndex, this->Bin1DIndex);
};
fieldArray.CastAndCallWithExtractedArray(computeBins);
}
}

@ -78,63 +78,6 @@ public:
}
};
class ComputeBins
{
public:
VTKM_CONT
ComputeBins(vtkm::cont::ArrayHandle<vtkm::Id>& _bin1DIdx,
vtkm::Id& _numOfBins,
vtkm::Range& _minMax,
vtkm::Float64& _binDelta)
: Bin1DIdx(_bin1DIdx)
, NumOfBins(_numOfBins)
, MinMax(_minMax)
, BinDelta(_binDelta)
, RangeProvided(false)
{
}
VTKM_CONT
ComputeBins(vtkm::cont::ArrayHandle<vtkm::Id>& _bin1DIdx,
vtkm::Id& _numOfBins,
vtkm::Range& _minMax,
vtkm::Float64& _binDelta,
bool _rangeProvided)
: Bin1DIdx(_bin1DIdx)
, NumOfBins(_numOfBins)
, MinMax(_minMax)
, BinDelta(_binDelta)
, RangeProvided(_rangeProvided)
{
}
template <typename T, typename Storage>
VTKM_CONT void operator()(const vtkm::cont::ArrayHandle<T, Storage>& field) const
{
if (!RangeProvided)
{
const vtkm::Vec<T, 2> initValue(vtkm::cont::ArrayGetValue(0, field));
vtkm::Vec<T, 2> minMax =
vtkm::cont::Algorithm::Reduce(field, initValue, vtkm::MinAndMax<T>());
MinMax.Min = static_cast<vtkm::Float64>(minMax[0]);
MinMax.Max = static_cast<vtkm::Float64>(minMax[1]);
}
BinDelta = compute_delta(MinMax.Min, MinMax.Max, NumOfBins);
SetHistogramBin<T> binWorklet(NumOfBins, MinMax.Min, BinDelta);
vtkm::worklet::DispatcherMapField<vtkm::worklet::histogram::SetHistogramBin<T>>
setHistogramBinDispatcher(binWorklet);
setHistogramBinDispatcher.Invoke(field, Bin1DIdx, Bin1DIdx);
}
private:
vtkm::cont::ArrayHandle<vtkm::Id>& Bin1DIdx;
vtkm::Id& NumOfBins;
vtkm::Range& MinMax;
vtkm::Float64& BinDelta;
bool RangeProvided;
};
// Convert N-dims bin index into 1D index
class ConvertHistBinToND : public vtkm::worklet::WorkletMapField
{