//---------------------------------------- double CBratAlgoFilterLoess2D::Run(CVectorBratAlgorithmParam& args) { int32_t iRecord = m_callerProduct->GetCurrentRecordNumber(); if (iRecord == m_callerProductRecordPrev) { // Do nothing: data have been already computed return m_loess; } m_varValueArray = NULL; setDefaultValue(m_loess); OpenProductFile(); SetParamValues(args); if (GetDataWindowSize() < 1) { PrepareReturn(); return m_loess; } if (GetDataWindowSize() == 1) { m_loess = m_varValue; PrepareReturn(); return m_loess; } if ( m_varValueArray == NULL) { ComputeSingle(); } else { ComputeMean(); } PrepareReturn(); return m_loess; }
//---------------------------------------- double CBratAlgoFilterLoess2D::ApplyFilter() { ComputeInitialWeights(); uint32_t windowSize = GetDataWindowSize(); // Sum weight (exclude 'default value') double sumWeight = 0.0; uint32_t nbMissingValue = 0; // Apply filter - calculate weighted mean double sum = 0.0; for (uint32_t i = 0; i < windowSize; i++) { if (isDefaultValue(m_rawDataWindow.at(i))) { nbMissingValue++; continue; } sumWeight += m_initialWeights[i]; sum += m_initialWeights.at(i) * m_rawDataWindow.at(i); #if _DEBUG_BRAT_ALGO CTrace::Tracer(CTools::Format("ApplyFilter sum = %f m_initialWeights = %f value = %f" , sum, m_initialWeights.at(i), m_rawDataWindow.at(i))); #endif } uint32_t nbValidPts = windowSize - nbMissingValue; if (nbValidPts < m_validPts) { setDefaultValue(sum); return sum; } if (sumWeight == 0.0) { return sum; } return sum / sumWeight; }
//---------------------------------------- void CBratAlgoFilterLanczos::SetParamValues(CVectorBratAlgorithmParam& args) { CheckInputParams(args); // Set variable m_varValue = args.at(CBratAlgoFilterLanczos::m_VAR_PARAM_INDEX).GetValueAsDouble(); int32_t valueInt32; // Set data window size (once) if (CTools::IsDefaultValue(m_dataWindowLength)) { this->CheckConstantParam(CBratAlgoFilterLanczos::m_WINDOW_PARAM_INDEX); valueInt32 = args.at(CBratAlgoFilterLanczos::m_WINDOW_PARAM_INDEX).GetValueAsInt(); if (valueInt32 <= 0) { throw CAlgorithmException(CTools::Format("'%s' algorithm can't be applied because the window size parameter (%d) is not greater than 0. " "You have to adjust the '%s' parameter.", this->GetName().c_str(), valueInt32, this->GetParamName(CBratAlgoFilterLanczos::m_WINDOW_PARAM_INDEX).c_str()), this->GetName(), BRATHL_LOGIC_ERROR); } m_dataWindowLength = valueInt32; if (CTools::IsDefaultValue(valueInt32)) { m_dataWindowLength = 3; } if (CTools::IsEven(m_dataWindowLength)) { throw CAlgorithmException(CTools::Format("'%s' algorithm can't be applied because the window size parameter (%d) is not an odd number." "You have to adjust the '%s' parameter.", this->GetName().c_str(), m_dataWindowLength, this->GetParamName(CBratAlgoFilterLanczos::m_WINDOW_PARAM_INDEX).c_str()), this->GetName(), BRATHL_LOGIC_ERROR); } m_dataWindowWidth = m_dataWindowLength; m_dataWindowHeight = m_dataWindowLength; } // Set valid points limit (once) if (CTools::IsDefaultValue(m_validPts)) { this->CheckConstantParam(CBratAlgoFilterLanczos::m_VALID_PARAM_INDEX); valueInt32 = args.at(CBratAlgoFilterLanczos::m_VALID_PARAM_INDEX).GetValueAsInt(); if (valueInt32 <= 0) { throw CAlgorithmException(CTools::Format("'%s' algorithm can't be applied because the '%s' parameter (%d) is less than or equal to 0. " "You have to adjust the '%s' parameter.", this->GetName().c_str(), this->GetParamName(CBratAlgoFilterLanczos::m_VALID_PARAM_INDEX).c_str(), valueInt32, this->GetParamName(CBratAlgoFilterLanczos::m_VALID_PARAM_INDEX).c_str()), this->GetName(), BRATHL_LOGIC_ERROR); } m_validPts = valueInt32; if (CTools::IsDefaultValue(valueInt32)) { m_validPts = GetDataWindowSize()/2; } if (GetDataWindowSize() < m_validPts) { throw CAlgorithmException(CTools::Format("'%s' algorithm can't be applied because the window size %d (%dx%d) is less than the minimum number of valid points parameter (%d). " "You have to adjust either the '%s' parameter or the '%s' parameter.", this->GetName().c_str(), GetDataWindowSize(), m_dataWindowLength, m_dataWindowLength, m_validPts, this->GetParamName(CBratAlgoFilterLanczos::m_WINDOW_PARAM_INDEX).c_str(), this->GetParamName(CBratAlgoFilterLanczos::m_VALID_PARAM_INDEX).c_str()), this->GetName(), BRATHL_LOGIC_ERROR); } } // Set cut-off period (once) if (CTools::IsDefaultValue(m_cutOffPeriod)) { this->CheckConstantParam(CBratAlgoFilterLanczos::m_CUTOFF_PERIOD_PARAM_INDEX); valueInt32 = args.at(CBratAlgoFilterLanczos::m_CUTOFF_PERIOD_PARAM_INDEX).GetValueAsInt(); if (valueInt32 < 0) { throw CAlgorithmException(CTools::Format("'%s' algorithm can't be applied because the '%s' parameter (%d) is strictly less than 0. " "You have to adjust the '%s' parameter.", this->GetName().c_str(), this->GetParamName(CBratAlgoFilterLanczos::m_CUTOFF_PERIOD_PARAM_INDEX).c_str(), valueInt32, this->GetParamName(CBratAlgoFilterLanczos::m_CUTOFF_PERIOD_PARAM_INDEX).c_str()), this->GetName(), BRATHL_LOGIC_ERROR); } m_cutOffPeriod = valueInt32; if (CTools::IsDefaultValue(valueInt32)) { this->GetParamDefValue(CBratAlgoFilterLanczos::m_CUTOFF_PERIOD_PARAM_INDEX, m_cutOffPeriod); } m_cutOffFrequency = 1.0/static_cast<double>(m_cutOffPeriod); } // Set extrapolate flag (once) if (CTools::IsDefaultValue(m_extrapolate)) { SetParamValueExtrapolate(args, CBratAlgoFilterLanczos::m_EXTRAPOLATE_PARAM_INDEX); } }
//---------------------------------------- void CBratAlgoFilterLoess2D::SetParamValues(CVectorBratAlgorithmParam& args) { CheckInputParams(args); // Set variable m_varValue = args.at(CBratAlgoFilterLoess2D::m_VAR_PARAM_INDEX).GetValueAsDouble(); int32_t valueInt32; // Set data window width (once) if (isDefaultValue(m_dataWindowWidth)) { this->CheckConstantParam(CBratAlgoFilterLoess2D::m_WINDOW_WIDTH_PARAM_INDEX); valueInt32 = args.at(CBratAlgoFilterLoess2D::m_WINDOW_WIDTH_PARAM_INDEX).GetValueAsInt(); if (valueInt32 <= 0) { throw CAlgorithmException(CTools::Format("'%s' algorithm can't be applied because the window width parameter (%d) is not greater than 0. " "You have to adjust the '%s' parameter.", this->GetName().c_str(), valueInt32, this->GetParamName(CBratAlgoFilterLoess2D::m_WINDOW_WIDTH_PARAM_INDEX).c_str()), this->GetName(), BRATHL_LOGIC_ERROR); } m_dataWindowWidth = valueInt32; if (isDefaultValue(valueInt32)) { m_dataWindowWidth = 3; } if (CTools::IsEven(m_dataWindowWidth)) { throw CAlgorithmException(CTools::Format("'%s' algorithm can't be applied because the window width parameter (%d) is not an odd number." "You have to adjust the '%s' parameter.", this->GetName().c_str(), m_dataWindowWidth, this->GetParamName(CBratAlgoFilterLoess2D::m_WINDOW_WIDTH_PARAM_INDEX).c_str()), this->GetName(), BRATHL_LOGIC_ERROR); } } // Set data window height (once) if (isDefaultValue(m_dataWindowHeight)) { this->CheckConstantParam(CBratAlgoFilterLoess2D::m_WINDOW_HEIGHT_PARAM_INDEX); valueInt32 = args.at(CBratAlgoFilterLoess2D::m_WINDOW_HEIGHT_PARAM_INDEX).GetValueAsInt(); if (valueInt32 <= 0) { throw CAlgorithmException(CTools::Format("'%s' algorithm can't be applied because the window height parameter (%d) is not greater than 0. " "You have to adjust the '%s' parameter.", this->GetName().c_str(), valueInt32, this->GetParamName(CBratAlgoFilterLoess2D::m_WINDOW_HEIGHT_PARAM_INDEX).c_str()), this->GetName(), BRATHL_LOGIC_ERROR); } m_dataWindowHeight = valueInt32; if (isDefaultValue(valueInt32)) { m_dataWindowHeight = 3; } if (CTools::IsEven(m_dataWindowHeight)) { throw CAlgorithmException(CTools::Format("'%s' algorithm can't be applied because the window height parameter (%d) is not an odd number." "You have to adjust the '%s' parameter.", this->GetName().c_str(), m_dataWindowHeight, this->GetParamName(CBratAlgoFilterLoess2D::m_WINDOW_HEIGHT_PARAM_INDEX).c_str()), this->GetName(), BRATHL_LOGIC_ERROR); } } // Set valid points limit (once) if (isDefaultValue(m_validPts)) { this->CheckConstantParam(CBratAlgoFilterLoess2D::m_VALID_PARAM_INDEX); valueInt32 = args.at(CBratAlgoFilterLoess2D::m_VALID_PARAM_INDEX).GetValueAsInt(); if (valueInt32 <= 0) { throw CAlgorithmException(CTools::Format("'%s' algorithm can't be applied because the '%s' parameter (%d) is less than or equal to 0. " "You have to adjust the '%s' parameter.", this->GetName().c_str(), this->GetParamName(CBratAlgoFilterLoess2D::m_VALID_PARAM_INDEX).c_str(), valueInt32, this->GetParamName(CBratAlgoFilterLoess2D::m_VALID_PARAM_INDEX).c_str()), this->GetName(), BRATHL_LOGIC_ERROR); } m_validPts = valueInt32; if (isDefaultValue(valueInt32)) { m_validPts = GetDataWindowSize()/2; } if (GetDataWindowSize() < m_validPts) { throw CAlgorithmException(CTools::Format("'%s' algorithm can't be applied because the window size parameter (%dx%d=%d ) is less than the minimum number of valid points parameter (%d). " "You have to adjust either the '%s' or '%s' parameters or the '%s' parameter.", this->GetName().c_str(), m_dataWindowWidth, m_dataWindowHeight, GetDataWindowSize(), m_validPts, this->GetParamName(CBratAlgoFilterLoess2D::m_WINDOW_WIDTH_PARAM_INDEX).c_str(), this->GetParamName(CBratAlgoFilterLoess2D::m_WINDOW_HEIGHT_PARAM_INDEX).c_str(), this->GetParamName(CBratAlgoFilterLoess2D::m_VALID_PARAM_INDEX).c_str()), this->GetName(), BRATHL_LOGIC_ERROR); } } // Set extrapolate flag (once) if (isDefaultValue(m_extrapolate)) { SetParamValueExtrapolate(args, CBratAlgoFilterLoess2D::m_EXTRAPOLATE_PARAM_INDEX); } }
//---------------------------------------- void CBratAlgoFilterLoess2D::ComputeInitialWeights() { // Compute just once if (m_initialWeights.size() > 0) { // Already computed return; } int32_t windowSize = GetDataWindowSize(); int32_t halfWindowWidth = m_dataWindowWidth / 2; int32_t halfWindowHeight = m_dataWindowHeight / 2; m_initialWeights.resize(windowSize); double distance = 0.0; int32_t indexWeight = 0; for (int32_t x = 0 ; x < static_cast<int32_t>(m_dataWindowWidth) ; x++) { double sqrNormDistX = static_cast<double>(x - halfWindowWidth) / static_cast<double>(halfWindowWidth); #if _DEBUG_BRAT_ALGO double normDistX = sqrNormDistX; #endif sqrNormDistX *= sqrNormDistX; for (int32_t y = 0 ; y < static_cast<int32_t>(m_dataWindowHeight) ; y++) { double normDistY = static_cast<double>(y - halfWindowHeight) / static_cast<double>(halfWindowHeight); distance = sqrt( sqrNormDistX + (normDistY * normDistY) ); double valueLocal = m_rawDataWindow[0]; if (valueLocal == 1.0) { std::string msg = ""; } double weight = (distance <= 1.0 ? pow((1.0 - pow(distance, 3.0)),3.0) : 0.0); #if _DEBUG_BRAT_ALGO CTrace::Tracer(CTools::Format("xx = %d yy = %d value = %f normDistX = %f normDistY = %f dist = %f wij = %f" , x, y, valueLocal, normDistX, normDistY, distance, weight)); #endif m_initialWeights[indexWeight] = weight; indexWeight++; } } #if _DEBUG_BRAT_ALGO std::string str; str.append("initial weights are "); str.append(CTools::Format("(%ld elements): ", static_cast<long>(m_initialWeights.size()))); for (uint32_t i = 0; i < m_initialWeights.size(); i++) { str.append(CTools::Format("%f ", m_initialWeights[i])); } str.append("\n"); CTrace::Tracer(str); #endif }
//---------------------------------------- void CBratAlgoFilterKernel::PrepareDataWindow2DSymmetrically(double* dataValue, uint32_t nbValues, uint32_t shiftSymmetry /* = 0 */) { UNUSED(nbValues); // Fill data window with data values m_rawDataWindow.RemoveAll(); m_rawDataWindow.resize(GetDataWindowSize()); std::fill(m_rawDataWindow.begin(), m_rawDataWindow.end(), CTools::m_defaultValueDOUBLE); int32_t start = (m_addWidthLeft * m_dataWindowHeight) + m_addHeightTop; // Copy each width (x) for (int32_t i = 0 ; i < m_countX ; i++) { int32_t offsetCopy = start + (i * m_dataWindowHeight); // Copy all height (y) for this width std::copy(dataValue + (m_countY * i), dataValue + (m_countY * (i + 1)), m_rawDataWindow.begin() + offsetCopy); //m_rawDataWindow.Dump(*CTrace::GetDumpContext()); // Treating top height edge // Data are extended symmetrically. for (int32_t h = 0 ; h < m_addHeightTop ; h++) { m_rawDataWindow[offsetCopy - h - 1] = m_rawDataWindow[offsetCopy + h + shiftSymmetry - m_gapHeight]; } // Treating bottom height edge // Data are extended symmetrically. for (int32_t h = 0 ; h < m_addHeightBottom ; h++) { m_rawDataWindow[offsetCopy + m_countY + h] = m_rawDataWindow[offsetCopy + m_countY - 1 - shiftSymmetry - h + m_gapHeight]; } //m_rawDataWindow.Dump(*CTrace::GetDumpContext()); } // Treating left width edge // Data are extended symmetrically. uint32_t offset = m_addWidthLeft * m_dataWindowHeight; for (int32_t w = 0 ; w < m_addWidthLeft ; w++) { std::copy(m_rawDataWindow.begin() + offset + (m_dataWindowHeight * (w + shiftSymmetry - m_gapWidth)), m_rawDataWindow.begin() + offset + (m_dataWindowHeight * (w + 1 + shiftSymmetry - m_gapWidth)), m_rawDataWindow.begin() + offset - (m_dataWindowHeight * (w + 1))); } // Treating right width edge // Data are extended symmetrically. offset = (m_addWidthRight * m_dataWindowHeight); for (int32_t w = 0 ; w < m_addWidthRight ; w++) { std::copy(m_rawDataWindow.end() - offset - (m_dataWindowHeight * (w + 1 + shiftSymmetry - m_gapWidth)), m_rawDataWindow.end() - offset - (m_dataWindowHeight * (w + shiftSymmetry - m_gapWidth)), m_rawDataWindow.end() - offset + (m_dataWindowHeight * w)); } //m_rawDataWindow.Dump(*CTrace::GetDumpContext()); CTrace::Tracer(3, CTools::Format("===> m_varValue is %f", m_varValue)); CTrace::Tracer(3, "===> WINDOW IS:"); for (uint32_t i = 0 ; i < m_dataWindowWidth ; i++) { std::string str; for (uint32_t j = 0 ; j < m_dataWindowHeight ; j++) { double value = m_rawDataWindow[(i * m_dataWindowHeight) + j]; if (isDefaultValue(value)) { str.append("DV "); } else { str.append(CTools::Format("%f ", value)); } } CTrace::Tracer(3, str); } CTrace::Tracer(3, "===> END WINDOW <======="); }