Merge topic 'add_log_values_filter'

0374b957d add log values filter

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Li-Ta Lo <ollie@lanl.gov>
Merge-request: !2852
This commit is contained in:
Zhe Wang 2022-08-31 12:56:45 +00:00 committed by Kitware Robot
commit cc72fd1c7a
7 changed files with 301 additions and 0 deletions

@ -16,6 +16,7 @@ set(field_transform_headers
SphericalCoordinateTransform.h
WarpScalar.h
WarpVector.h
LogValues.h
)
set(field_transform_sources
@ -27,6 +28,7 @@ set(field_transform_sources
SphericalCoordinateTransform.cxx
WarpScalar.cxx
WarpVector.cxx
LogValues.cxx
)
vtkm_library(

@ -0,0 +1,61 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/ErrorFilterExecution.h>
#include <vtkm/filter/field_transform/LogValues.h>
#include <vtkm/filter/field_transform/worklet/LogValues.h>
namespace vtkm
{
namespace filter
{
namespace field_transform
{
VTKM_CONT vtkm::cont::DataSet LogValues::DoExecute(const vtkm::cont::DataSet& inDataSet)
{
vtkm::cont::ArrayHandle<vtkm::FloatDefault> logField;
auto resolveType = [&](const auto& concrete) {
switch (this->BaseValue)
{
case LogBase::E:
{
this->Invoke(vtkm::worklet::detail::LogFunWorklet<vtkm::Log>{ this->GetMinValue() },
concrete,
logField);
break;
}
case LogBase::TWO:
{
this->Invoke(vtkm::worklet::detail::LogFunWorklet<vtkm::Log2>{ this->GetMinValue() },
concrete,
logField);
break;
}
case LogBase::TEN:
{
this->Invoke(vtkm::worklet::detail::LogFunWorklet<vtkm::Log10>{ this->GetMinValue() },
concrete,
logField);
break;
}
default:
{
throw vtkm::cont::ErrorFilterExecution("Unsupported base value.");
}
}
};
const auto& inField = this->GetFieldFromDataSet(inDataSet);
this->CastAndCallScalarField(inField, resolveType);
return this->CreateResultField(
inDataSet, this->GetOutputFieldName(), inField.GetAssociation(), logField);
}
} // namespace field_transform
} // namespace vtkm::filter
} // namespace vtkm

@ -0,0 +1,60 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_filter_field_transform_LogValues_h
#define vtk_m_filter_field_transform_LogValues_h
#include <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/field_transform/vtkm_filter_field_transform_export.h>
namespace vtkm
{
namespace filter
{
namespace field_transform
{
/// \brief Adds field to a `DataSet` that gives the log values for the user specified field.
///
/// This filter use the ActiveField defined in the NewFilterField to store the log values.
///
class VTKM_FILTER_FIELD_TRANSFORM_EXPORT LogValues : public vtkm::filter::NewFilterField
{
public:
enum struct LogBase
{
E,
TWO,
TEN
};
/// \{
/// \brief The base value given to the log filter.
///
const LogBase& GetBaseValue() const { return this->BaseValue; }
void SetBaseValue(const LogBase& base) { this->BaseValue = base; }
/// \}
/// \{
/// \brief The min value for executing the log filter.
///
vtkm::FloatDefault GetMinValue() const { return this->MinValue; }
void SetMinValue(const vtkm::FloatDefault& value) { this->MinValue = value; }
/// \}
private:
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
LogBase BaseValue = LogBase::E;
vtkm::FloatDefault MinValue = std::numeric_limits<FloatDefault>::min();
};
} // namespace field_transform
} // namespace vtkm::filter
} // namespace vtkm
#endif //vtk_m_filter_field_transform_LogValues_h

@ -16,6 +16,7 @@ set(unit_tests
UnitTestPointTransform.cxx
UnitTestWarpScalarFilter.cxx
UnitTestWarpVectorFilter.cxx
UnitTestLogValues.cxx
)
set(libraries

@ -0,0 +1,126 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/field_transform/LogValues.h>
namespace
{
const vtkm::Id dim = 10;
using BaseType = vtkm::filter::field_transform::LogValues::LogBase;
template <typename T>
vtkm::cont::DataSet MakeLogValuesTestDataSet()
{
vtkm::cont::DataSet dataSet;
std::vector<T> pointarray;
std::vector<T> cellarray;
for (vtkm::Id j = 0; j < dim; ++j)
{
for (vtkm::Id i = 0; i < dim; ++i)
{
pointarray.push_back(static_cast<T>((j * dim + i) * 0.1));
cellarray.push_back(static_cast<T>((i * dim + j) * 0.1));
}
}
dataSet.AddPointField("pointScalarField", pointarray);
dataSet.AddCellField("cellScalarField", cellarray);
return dataSet;
}
void TestLogGeneral(
BaseType base,
std::string ActiveFieldName,
vtkm::cont::Field::Association association = vtkm::cont::Field::Association::Any)
{
vtkm::cont::DataSet input = MakeLogValuesTestDataSet<vtkm::FloatDefault>();
vtkm::filter::field_transform::LogValues filter;
std::string LogFieldName = ActiveFieldName + "LogValues";
filter.SetActiveField(ActiveFieldName, association);
filter.SetOutputFieldName(LogFieldName);
filter.SetBaseValue(base);
vtkm::cont::DataSet output = filter.Execute(input);
vtkm::cont::ArrayHandle<vtkm::FloatDefault> rawArrayHandle;
vtkm::cont::ArrayHandle<vtkm::FloatDefault> logArrayHandle;
input.GetField(ActiveFieldName, association).GetData().AsArrayHandle(rawArrayHandle);
output.GetField(LogFieldName, association).GetData().AsArrayHandle(logArrayHandle);
auto rawPortal = rawArrayHandle.ReadPortal();
auto logPortal = logArrayHandle.ReadPortal();
typedef vtkm::FloatDefault (*LogFuncPtr)(vtkm::FloatDefault);
LogFuncPtr LogFunc = nullptr;
switch (base)
{
case BaseType::E:
{
LogFunc = &vtkm::Log;
break;
}
case BaseType::TWO:
{
LogFunc = &vtkm::Log2;
break;
}
case BaseType::TEN:
{
LogFunc = &vtkm::Log10;
break;
}
default:
{
VTKM_TEST_ASSERT("unsupported base value");
}
}
for (vtkm::Id i = 0; i < rawArrayHandle.GetNumberOfValues(); ++i)
{
auto raw = rawPortal.Get(i);
auto logv = logPortal.Get(i);
if (raw == 0)
{
VTKM_TEST_ASSERT(test_equal(logv, LogFunc(filter.GetMinValue())),
"log value was wrong for min value");
continue;
}
VTKM_TEST_ASSERT(test_equal(logv, LogFunc(raw)), "log value was wrong for test");
}
}
void TestLogValues()
{
std::string pointScalarField = "pointScalarField";
using AsscoType = vtkm::cont::Field::Association;
TestLogGeneral(BaseType::TEN, pointScalarField, AsscoType::Points);
TestLogGeneral(BaseType::TWO, pointScalarField, AsscoType::Points);
TestLogGeneral(BaseType::E, pointScalarField, AsscoType::Points);
std::string cellScalarField = "cellScalarField";
TestLogGeneral(BaseType::TEN, cellScalarField, AsscoType::Cells);
TestLogGeneral(BaseType::TWO, cellScalarField, AsscoType::Cells);
TestLogGeneral(BaseType::E, cellScalarField, AsscoType::Cells);
}
} // anonymous namespace
int UnitTestLogValues(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestLogValues, argc, argv);
}

@ -14,6 +14,7 @@ set(headers
PointTransform.h
WarpScalar.h
WarpVector.h
LogValues.h
)
vtkm_declare_headers(${headers})

@ -0,0 +1,50 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_worklet_LogValues_h
#define vtk_m_worklet_LogValues_h
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
namespace vtkm
{
namespace worklet
{
namespace detail
{
template <vtkm::FloatDefault LogFunc(vtkm::FloatDefault)>
class LogFunWorklet : public vtkm::worklet::WorkletMapField
{
const vtkm::FloatDefault MinValue;
public:
VTKM_CONT
LogFunWorklet(const vtkm::FloatDefault minValue)
: MinValue(minValue)
{
}
typedef void ControlSignature(FieldIn, FieldOut);
typedef void ExecutionSignature(_1, _2);
template <typename T>
VTKM_EXEC void operator()(const T& value, vtkm::FloatDefault& log_value) const
{
vtkm::FloatDefault f_value = static_cast<vtkm::FloatDefault>(value);
f_value = vtkm::Max(MinValue, f_value);
log_value = LogFunc(f_value);
}
}; //class LogFunWorklet
}
}
} // namespace vtkm::worklet
#endif // vtk_m_worklet_LogValues_h