void HumanAxeIdleLoop::execute(EntityHuman* human) { if(human->getBodyAnimator()->isQueueEmpty()) { human->getBodyAnimator()->pushAnimationFrames(&AnimHumanAxeIdleLoop::getInstance()); } int inputMask = human->getInputMask(); Vec2 moving = human->getMoving(); if ( isMasked(inputMask, (int)JoystickMessageTypes::RUN) ) { human->getFSM()->changeState(&HumanAxeMoveLoop::getInstance()); } else if( isMasked(inputMask, (int)JoystickMessageTypes::MOVE) ) { human->setVelocity( moving * human->getWalkSpeed() ); } else { human->setVelocity( Vec2::ZERO ); } if ( isMasked(inputMask, (int)JoystickMessageTypes::ATTACK_BEGAN) ) { human->getFSM()->changeState(&HumanAxeAttack::getInstance()); } }
void HumanAxeMoveLoop::execute(EntityHuman* human) { int inputMask = human->getInputMask(); Vec2 moving = human->getMoving(); if( moving != Vec2::ZERO ) { human->setTargetHeading(moving); } int currFrame = human->getBodyAnimator()->getFrameIndex(); if ( isMasked(inputMask, (int)JoystickMessageTypes::RUN) ) { human->setVelocity( moving * human->getRunSpeed() ); if ( currFrame == 5 ) { human->getBodyAnimator()->pushFramesAtoB(&AnimHumanAxeMoveLoop::getInstance(), 6, 11); } else if( currFrame == 11 ) { human->getBodyAnimator()->pushFramesAtoB(&AnimHumanAxeMoveLoop::getInstance(), 0, 5); } } else { if ( currFrame == 5 || currFrame == 11 ) { human->setVelocity( Vec2::ZERO ); human->getFSM()->changeState(&HumanAxeIdleLoop::getInstance()); } } }
void HumanAxeAttack::execute(EntityHuman* human) { int inputMask = human->getInputMask(); Vec2 moving = human->getMoving(); int currFrame = human->getBodyAnimator()->getFrameIndex(); if( isMasked(inputMask, (int)JoystickMessageTypes::MOVE) ) { human->setVelocity( moving * human->getWalkSpeed() ); } else { human->setVelocity( Vec2::ZERO ); } if ( currFrame == 10) { if ( isMasked(inputMask, (int)JoystickMessageTypes::ATTACK_BEGAN) ) { human->getBodyAnimator()->pushOneFrame(std::make_pair("HumanAxeAttack10.png", 10)); } else if ( isMasked(inputMask, (int)JoystickMessageTypes::ATTACK_ENDED) ) { human->removeInputMask((int)JoystickMessageTypes::ATTACK_ENDED); human->getBodyAnimator()->pushFramesAtoB(&AnimHumanAxeAttack::getInstance(), 11, 17); // attack. human->getEquipedWeapon()->attack(); } } else if ( currFrame < 10 ) { if ( isMasked(inputMask, (int)JoystickMessageTypes::ATTACK_ENDED) ) { human->removeInputMask((int)JoystickMessageTypes::ATTACK_ENDED); human->getBodyAnimator()->pushFramesAtoB(&AnimHumanAxeAttack::getInstance(), currFrame - 1, 0); } } if ( human->getBodyAnimator()->isQueueEmpty() ) { human->getFSM()->changeState(&HumanAxeIdleLoop::getInstance()); } }
void AccountWindow::StringOption::onActivate(Button& /*activator*/) { CppConsUI::InputDialog *dialog = new CppConsUI::InputDialog(getText(), getValue()); dialog->setMasked(isMasked()); dialog->signal_response.connect(sigc::mem_fun(this, &StringOption::responseHandler)); dialog->show(); }
void InstrumentRenderer::resetColors() { auto sharedWorkspace = m_actor.getWorkspace(); const double vmin(m_actor.minValue()), vmax(m_actor.maxValue()); // Reset all colors to 0 and resize m_colors to the appropriate size const auto zero = m_colorMap.rgb(vmin, vmax, 0); const auto &compInfo = m_actor.componentInfo(); m_colors.assign(compInfo.size(), GLColor(qRed(zero), qGreen(zero), qBlue(zero), 1)); // No data/masked colors static const auto invalidColor = GLColor(80, 80, 80, 1); static const auto maskedColor = GLColor(100, 100, 100, 1); // Compute required colors for the detectors in a single shot to avoid // repeated calls to python and back in the matplotlib-based implementation const auto &detInfo = m_actor.detectorInfo(); std::vector<double> counts(detInfo.size()); for (size_t det = 0; det < detInfo.size(); ++det) { counts[det] = m_actor.getIntegratedCounts(det); } auto rgba = m_colorMap.rgb(vmin, vmax, counts); // Now apply colors taking into account detectors with bad counts and detector // masking Mantid::API::IMaskWorkspace_sptr maskWS = m_actor.getMaskWorkspaceIfExists(); const auto &detectorIDs = detInfo.detectorIDs(); // Defines a mask checker lambda dependent on if we have a mask workspace or // not. Done once outside the loop to avoid repeated if branches in the loop std::function<bool(size_t)> isMasked; if (maskWS) { isMasked = [&detInfo, &detectorIDs, &maskWS](size_t index) { return maskWS->isMasked(detectorIDs[index]) || detInfo.isMasked(index); }; } else { isMasked = [&detInfo](size_t index) { return detInfo.isMasked(index); }; } for (size_t det = 0; det < counts.size(); ++det) { if (!isMasked(det)) { const double integratedValue(counts[det]); if (integratedValue > -1) { const auto &color = rgba[det]; m_colors[det] = GLColor(qRed(color), qGreen(color), qBlue(color), static_cast<int>(255 * (integratedValue / vmax))); } else m_colors[det] = invalidColor; } else { m_colors[det] = maskedColor; } } // finish off rest of the components with the mask color for (const auto comp : m_actor.components()) m_colors[comp] = maskedColor; }
/** * Sum counts from the input workspace in lambda along lines of constant Q by * projecting to "virtual lambda" at a reference angle. * * @param detectorWS [in] :: the input workspace in wavelength * @param indices [in] :: an index set defining the foreground histograms * @return :: the single histogram output workspace in wavelength */ API::MatrixWorkspace_sptr ReflectometrySumInQ::sumInQ(const API::MatrixWorkspace &detectorWS, const Indexing::SpectrumIndexSet &indices) { const auto spectrumInfo = detectorWS.spectrumInfo(); const auto refAngles = referenceAngles(spectrumInfo); // Construct the output workspace in virtual lambda API::MatrixWorkspace_sptr IvsLam = constructIvsLamWS(detectorWS, indices, refAngles); auto &outputE = IvsLam->dataE(0); // Loop through each spectrum in the detector group for (auto spIdx : indices) { if (spectrumInfo.isMasked(spIdx) || spectrumInfo.isMonitor(spIdx)) { continue; } // Get the size of this detector in twoTheta const auto twoThetaRange = twoThetaWidth(spIdx, spectrumInfo); // Check X length is Y length + 1 const auto inputBinEdges = detectorWS.binEdges(spIdx); const auto inputCounts = detectorWS.counts(spIdx); const auto inputStdDevs = detectorWS.countStandardDeviations(spIdx); // Create a vector for the projected errors for this spectrum. // (Output Y values can simply be accumulated directly into the output // workspace, but for error values we need to create a separate error // vector for the projected errors from each input spectrum and then // do an overall sum in quadrature.) std::vector<double> projectedE(outputE.size(), 0.0); // Process each value in the spectrum const int ySize = static_cast<int>(inputCounts.size()); for (int inputIdx = 0; inputIdx < ySize; ++inputIdx) { // Do the summation in Q processValue(inputIdx, twoThetaRange, refAngles, inputBinEdges, inputCounts, inputStdDevs, *IvsLam, projectedE); } // Sum errors in quadrature const int eSize = static_cast<int>(outputE.size()); for (int outIdx = 0; outIdx < eSize; ++outIdx) { outputE[outIdx] += projectedE[outIdx] * projectedE[outIdx]; } } // Take the square root of all the accumulated squared errors for this // detector group. Assumes Gaussian errors double (*rs)(double) = std::sqrt; std::transform(outputE.begin(), outputE.end(), outputE.begin(), rs); return IvsLam; }
//--------------------------------------------------------------------------------------------------------------- Residue ImplProfile::asResidue( const Position column ) const { if (isMasked(column)) return getToolkit()->getEncoder()->getMaskCode(); return getMaximumCount( column ); }
void ColorHistogramLabelMatch::match( const sensor_msgs::Image::ConstPtr& image_msg, const sensor_msgs::Image::ConstPtr& label_msg, const sensor_msgs::Image::ConstPtr& mask_msg) { boost::mutex::scoped_lock lock(mutex_); if (histogram_.empty()) { NODELET_DEBUG("no reference histogram is available"); return; } cv::Mat image = cv_bridge::toCvShare(image_msg, image_msg->encoding)->image; cv::Mat label = cv_bridge::toCvShare(label_msg, label_msg->encoding)->image; cv::Mat whole_mask = cv_bridge::toCvShare(mask_msg, mask_msg->encoding)->image; cv::Mat coefficient_image = cv::Mat::zeros( image_msg->height, image_msg->width, CV_32FC1); std::vector<int> labels; getLabels(label, labels); cv::Mat coefficients_heat_image = cv::Mat::zeros( image_msg->height, image_msg->width, CV_8UC3); // BGR8 int hist_size = histogram_.cols; float range[] = { min_value_, max_value_ }; const float* hist_range = { range }; double min_coef = DBL_MAX; double max_coef = - DBL_MAX; for (size_t i = 0; i < labels.size(); i++) { int label_index = labels[i]; cv::Mat label_mask = cv::Mat::zeros(label.rows, label.cols, CV_8UC1); getMaskImage(label, label_index, label_mask); double coef = 0.0; // get label_mask & whole_mask and check is it all black or not cv::Mat masked_label; label_mask.copyTo(masked_label, whole_mask); if (isMasked(label_mask, masked_label)) { coef = masked_coefficient_; } else { cv::MatND hist; bool uniform = true; bool accumulate = false; cv::calcHist(&image, 1, 0, label_mask, hist, 1, &hist_size, &hist_range, uniform, accumulate); cv::normalize(hist, hist, 1, hist.rows, cv::NORM_L2, -1, cv::Mat()); cv::Mat hist_mat = cv::Mat::zeros(1, hist_size, CV_32FC1); for (size_t j = 0; j < hist_size; j++) { hist_mat.at<float>(0, j) = hist.at<float>(0, j); } //cv::Mat hist_mat = hist; coef = coefficients(hist_mat, histogram_); if (min_coef > coef) { min_coef = coef; } if (max_coef < coef) { max_coef = coef; } } std_msgs::ColorRGBA coef_color = jsk_topic_tools::heatColor(coef); for (size_t j = 0; j < coefficients_heat_image.rows; j++) { for (size_t i = 0; i < coefficients_heat_image.cols; i++) { if (label_mask.at<uchar>(j, i) == 255) { coefficients_heat_image.at<cv::Vec3b>(j, i) = cv::Vec3b(int(coef_color.b * 255), int(coef_color.g * 255), int(coef_color.r * 255)); coefficient_image.at<float>(j, i) = coef; } } } } NODELET_INFO("coef: %f - %f", min_coef, max_coef); pub_debug_.publish( cv_bridge::CvImage(image_msg->header, sensor_msgs::image_encodings::BGR8, coefficients_heat_image).toImageMsg()); pub_coefficient_image_.publish( cv_bridge::CvImage(image_msg->header, sensor_msgs::image_encodings::TYPE_32FC1, coefficient_image).toImageMsg()); // apply threshold operation cv::Mat threshold_image = cv::Mat::zeros( coefficient_image.rows, coefficient_image.cols, CV_32FC1); if (threshold_method_ == 0) { // smaller than cv::threshold(coefficient_image, threshold_image, coef_threshold_, 1, cv::THRESH_BINARY_INV); } else if (threshold_method_ == 1) { // greater than cv::threshold(coefficient_image, threshold_image, coef_threshold_, 1, cv::THRESH_BINARY); } else if (threshold_method_ == 2 || threshold_method_ == 3) { // convert image into 8UC to apply otsu' method cv::Mat otsu_image = cv::Mat::zeros( coefficient_image.rows, coefficient_image.cols, CV_8UC1); cv::Mat otsu_result_image = cv::Mat::zeros( coefficient_image.rows, coefficient_image.cols, CV_8UC1); coefficient_image.convertTo(otsu_image, 8, 255.0); cv::threshold(otsu_image, otsu_result_image, coef_threshold_, 255, cv::THRESH_OTSU); // convert it into float image again if (threshold_method_ == 2) { otsu_result_image.convertTo(threshold_image, 32, 1 / 255.0); } else if (threshold_method_ == 3) { otsu_result_image.convertTo(threshold_image, 32, - 1 / 255.0, 1.0); } } cv::Mat threshold_uchar_image = cv::Mat(threshold_image.rows, threshold_image.cols, CV_8UC1); threshold_image.convertTo(threshold_uchar_image, 8, 255.0); // convert image from float to uchar pub_result_.publish( cv_bridge::CvImage(image_msg->header, sensor_msgs::image_encodings::MONO8, threshold_uchar_image).toImageMsg()); }
/** * Computed the normalization for the input workspace. Results are stored in * m_normWS * @param otherValues * @param affineTrans */ void MDNormDirectSC::calculateNormalization( const std::vector<coord_t> &otherValues, const Kernel::Matrix<coord_t> &affineTrans) { constexpr double energyToK = 8.0 * M_PI * M_PI * PhysicalConstants::NeutronMass * PhysicalConstants::meV * 1e-20 / (PhysicalConstants::h * PhysicalConstants::h); const auto &exptInfoZero = *(m_inputWS->getExperimentInfo(0)); typedef Kernel::PropertyWithValue<std::vector<double>> VectorDoubleProperty; auto *rubwLog = dynamic_cast<VectorDoubleProperty *>(exptInfoZero.getLog("RUBW_MATRIX")); if (!rubwLog) { throw std::runtime_error( "Wokspace does not contain a log entry for the RUBW matrix." "Cannot continue."); } else { Kernel::DblMatrix rubwValue( (*rubwLog)()); // includes the 2*pi factor but not goniometer for now :) m_rubw = exptInfoZero.run().getGoniometerMatrix() * rubwValue; m_rubw.Invert(); } const double protonCharge = exptInfoZero.run().getProtonCharge(); auto instrument = exptInfoZero.getInstrument(); std::vector<detid_t> detIDs = instrument->getDetectorIDs(true); // Prune out those that are part of a group and simply leave the head of the // group detIDs = removeGroupedIDs(exptInfoZero, detIDs); // Mapping const int64_t ndets = static_cast<int64_t>(detIDs.size()); bool haveSA = false; API::MatrixWorkspace_const_sptr solidAngleWS = getProperty("SolidAngleWorkspace"); detid2index_map solidAngDetToIdx; if (solidAngleWS != nullptr) { haveSA = true; solidAngDetToIdx = solidAngleWS->getDetectorIDToWorkspaceIndexMap(); } auto prog = make_unique<API::Progress>(this, 0.3, 1.0, ndets); PARALLEL_FOR_NO_WSP_CHECK() for (int64_t i = 0; i < ndets; i++) { PARALLEL_START_INTERUPT_REGION const auto detID = detIDs[i]; double theta(0.0), phi(0.0); bool skip(false); try { auto spectrum = getThetaPhi(detID, exptInfoZero, theta, phi); if (spectrum->isMonitor() || spectrum->isMasked()) continue; } catch ( std::exception &) // detector might not exist or has no been included // in grouping { skip = true; // Intel compiler has a problem with continue inside a catch // inside openmp... } if (skip) continue; // Intersections auto intersections = calculateIntersections(theta, phi); if (intersections.empty()) continue; // Get solid angle for this contribution double solid = protonCharge; if (haveSA) { solid = solidAngleWS->readY(solidAngDetToIdx.find(detID)->second)[0] * protonCharge; } // Compute final position in HKL const size_t vmdDims = intersections.front().size(); // pre-allocate for efficiency and copy non-hkl dim values into place std::vector<coord_t> pos(vmdDims + otherValues.size() + 1); std::copy(otherValues.begin(), otherValues.end(), pos.begin() + vmdDims); pos.push_back(1.); auto intersectionsBegin = intersections.begin(); for (auto it = intersectionsBegin + 1; it != intersections.end(); ++it) { const auto &curIntSec = *it; const auto &prevIntSec = *(it - 1); // the full vector isn't used so compute only what is necessary double delta = (curIntSec[3] * curIntSec[3] - prevIntSec[3] * prevIntSec[3]) / energyToK; if (delta < 1e-10) continue; // Assume zero contribution if difference is small // Average between two intersections for final position std::transform(curIntSec.getBareArray(), curIntSec.getBareArray() + vmdDims, prevIntSec.getBareArray(), pos.begin(), VectorHelper::SimpleAverage<coord_t>()); // transform kf to energy transfer pos[3] = static_cast<coord_t>(m_Ei - pos[3] * pos[3] / energyToK); std::vector<coord_t> posNew = affineTrans * pos; size_t linIndex = m_normWS->getLinearIndexAtCoord(posNew.data()); if (linIndex == size_t(-1)) continue; // signal = integral between two consecutive intersections *solid angle // *PC double signal = solid * delta; PARALLEL_CRITICAL(updateMD) { signal += m_normWS->getSignalAt(linIndex); m_normWS->setSignalAt(linIndex, signal); } } prog->report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION }
/** * Computed the normalization for the input workspace. Results are stored in * m_normWS * @param otherValues * @param affineTrans */ void MDNormSCD::calculateNormalization( const std::vector<coord_t> &otherValues, const Kernel::Matrix<coord_t> &affineTrans) { API::MatrixWorkspace_const_sptr integrFlux = getProperty("FluxWorkspace"); integrFlux->getXMinMax(m_kiMin, m_kiMax); API::MatrixWorkspace_const_sptr solidAngleWS = getProperty("SolidAngleWorkspace"); const auto &exptInfoZero = *(m_inputWS->getExperimentInfo(0)); typedef Kernel::PropertyWithValue<std::vector<double>> VectorDoubleProperty; auto *rubwLog = dynamic_cast<VectorDoubleProperty *>(exptInfoZero.getLog("RUBW_MATRIX")); if (!rubwLog) { throw std::runtime_error( "Wokspace does not contain a log entry for the RUBW matrix." "Cannot continue."); } else { Kernel::DblMatrix rubwValue( (*rubwLog)()); // includes the 2*pi factor but not goniometer for now :) m_rubw = exptInfoZero.run().getGoniometerMatrix() * rubwValue; m_rubw.Invert(); } const double protonCharge = exptInfoZero.run().getProtonCharge(); auto instrument = exptInfoZero.getInstrument(); std::vector<detid_t> detIDs = instrument->getDetectorIDs(true); // Prune out those that are part of a group and simply leave the head of the // group detIDs = removeGroupedIDs(exptInfoZero, detIDs); // Mappings const int64_t ndets = static_cast<int64_t>(detIDs.size()); const detid2index_map fluxDetToIdx = integrFlux->getDetectorIDToWorkspaceIndexMap(); const detid2index_map solidAngDetToIdx = solidAngleWS->getDetectorIDToWorkspaceIndexMap(); auto prog = make_unique<API::Progress>(this, 0.3, 1.0, ndets); PARALLEL_FOR1(integrFlux) for (int64_t i = 0; i < ndets; i++) { PARALLEL_START_INTERUPT_REGION const auto detID = detIDs[i]; double theta(0.0), phi(0.0); bool skip(false); try { auto spectrum = getThetaPhi(detID, exptInfoZero, theta, phi); if (spectrum->isMonitor() || spectrum->isMasked()) continue; } catch ( std::exception &) // detector might not exist or has no been included // in grouping { skip = true; // Intel compiler has a problem with continue inside a catch // inside openmp... } if (skip) continue; // Intersections auto intersections = calculateIntersections(theta, phi); if (intersections.empty()) continue; // get the flux spetrum number size_t wsIdx = fluxDetToIdx.find(detID)->second; // Get solid angle for this contribution double solid = solidAngleWS->readY(solidAngDetToIdx.find(detID)->second)[0] * protonCharge; // -- calculate integrals for the intersection -- // momentum values at intersections auto intersectionsBegin = intersections.begin(); std::vector<double> xValues(intersections.size()), yValues(intersections.size()); { // copy momenta to xValues auto x = xValues.begin(); for (auto it = intersectionsBegin; it != intersections.end(); ++it, ++x) { *x = (*it)[3]; } } // calculate integrals at momenta from xValues by interpolating between // points in spectrum sp // of workspace integrFlux. The result is stored in yValues calcIntegralsForIntersections(xValues, *integrFlux, wsIdx, yValues); // Compute final position in HKL const size_t vmdDims = intersections.front().size(); // pre-allocate for efficiency and copy non-hkl dim values into place std::vector<coord_t> pos(vmdDims + otherValues.size()); std::copy(otherValues.begin(), otherValues.end(), pos.begin() + vmdDims - 1); pos.push_back(1.); for (auto it = intersectionsBegin + 1; it != intersections.end(); ++it) { const auto &curIntSec = *it; const auto &prevIntSec = *(it - 1); // the full vector isn't used so compute only what is necessary double delta = curIntSec[3] - prevIntSec[3]; if (delta < 1e-07) continue; // Assume zero contribution if difference is small // Average between two intersections for final position std::transform(curIntSec.getBareArray(), curIntSec.getBareArray() + vmdDims - 1, prevIntSec.getBareArray(), pos.begin(), VectorHelper::SimpleAverage<coord_t>()); std::vector<coord_t> posNew = affineTrans * pos; size_t linIndex = m_normWS->getLinearIndexAtCoord(posNew.data()); if (linIndex == size_t(-1)) continue; // index of the current intersection size_t k = static_cast<size_t>(std::distance(intersectionsBegin, it)); // signal = integral between two consecutive intersections double signal = (yValues[k] - yValues[k - 1]) * solid; PARALLEL_CRITICAL(updateMD) { signal += m_normWS->getSignalAt(linIndex); m_normWS->setSignalAt(linIndex, signal); } } prog->report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION }
void Column::calculateStatistics() { m_column_private->statistics = ColumnStatistics(); ColumnStatistics& statistics = m_column_private->statistics; QVector<double>* rowValues = reinterpret_cast<QVector<double>*>(data()); int notNanCount = 0; double val; double columnSum = 0.0; double columnProduct = 1.0; double columnSumNeg = 0.0; double columnSumSquare = 0.0; statistics.minimum = INFINITY; statistics.maximum = -INFINITY; QMap<double, int> frequencyOfValues; QVector<double> rowData; rowData.reserve(rowValues->size()); for (int row = 0; row < rowValues->size(); ++row) { val = rowValues->value(row); if (std::isnan(val) || isMasked(row)) continue; if (val < statistics.minimum){ statistics.minimum = val; } if (val > statistics.maximum){ statistics.maximum = val; } columnSum+= val; columnSumNeg += (1.0 / val); columnSumSquare += pow(val, 2.0); columnProduct *= val; if (frequencyOfValues.contains(val)){ frequencyOfValues.operator [](val)++; } else{ frequencyOfValues.insert(val, 1); } ++notNanCount; rowData.push_back(val); } if (notNanCount == 0) { setStatisticsAvailable(true); return; } if (rowData.size() < rowValues->size()){ rowData.squeeze(); } statistics.arithmeticMean = columnSum / notNanCount; statistics.geometricMean = pow(columnProduct, 1.0 / notNanCount); statistics.harmonicMean = notNanCount / columnSumNeg; statistics.contraharmonicMean = columnSumSquare / columnSum; double columnSumVariance = 0; double columnSumMeanDeviation = 0.0; double columnSumMedianDeviation = 0.0; double sumForCentralMoment_r3 = 0.0; double sumForCentralMoment_r4 = 0.0; gsl_sort(rowData.data(), 1, notNanCount); statistics.median = (notNanCount % 2 ? rowData.at((notNanCount-1)/2) : (rowData.at((notNanCount-1)/2) + rowData.at(notNanCount/2))/2.0); QVector<double> absoluteMedianList; absoluteMedianList.reserve(notNanCount); absoluteMedianList.resize(notNanCount); int idx = 0; for(int row = 0; row < rowValues->size(); ++row){ val = rowValues->value(row); if ( std::isnan(val) || isMasked(row) ) continue; columnSumVariance+= pow(val - statistics.arithmeticMean, 2.0); sumForCentralMoment_r3 += pow(val - statistics.arithmeticMean, 3.0); sumForCentralMoment_r4 += pow(val - statistics.arithmeticMean, 4.0); columnSumMeanDeviation += fabs( val - statistics.arithmeticMean ); absoluteMedianList[idx] = fabs(val - statistics.median); columnSumMedianDeviation += absoluteMedianList[idx]; idx++; } statistics.meanDeviationAroundMedian = columnSumMedianDeviation / notNanCount; statistics.medianDeviation = (notNanCount % 2 ? absoluteMedianList.at((notNanCount-1)/2) : (absoluteMedianList.at((notNanCount-1)/2) + absoluteMedianList.at(notNanCount/2))/2.0); const double centralMoment_r3 = sumForCentralMoment_r3 / notNanCount; const double centralMoment_r4 = sumForCentralMoment_r4 / notNanCount; statistics.variance = columnSumVariance / notNanCount; statistics.standardDeviation = sqrt(statistics.variance); statistics.skewness = centralMoment_r3 / pow(statistics.standardDeviation, 3.0); statistics.kurtosis = (centralMoment_r4 / pow(statistics.standardDeviation, 4.0)) - 3.0; statistics.meanDeviation = columnSumMeanDeviation / notNanCount; double entropy = 0.0; QList<int> frequencyOfValuesValues = frequencyOfValues.values(); for (int i = 0; i < frequencyOfValuesValues.size(); ++i){ double frequencyNorm = static_cast<double>(frequencyOfValuesValues.at(i)) / notNanCount; entropy += (frequencyNorm * log2(frequencyNorm)); } statistics.entropy = -entropy; setStatisticsAvailable(true); }