void SC_Statistics::CalcMode(const SC_DoubleArray& data) { if (nOK == 0) return; // min == max if (realResults[soVar] < stdEps) { realResults[soMode] = realResults[soMean]; return; } // Scott, 1979 algorithm for bin width // W = (3.49)(std.dev.)[(#samples)^(-1/3)] double width = 3.49 * realResults[soStdDev] * (pow(realResults[soN], -0.3333)); if (width < stdEps) { realResults[soMode] = realResults[soMean]; return; } double maxNBins = (realResults[soMax] - realResults[soMin]) / width; if (maxNBins > 10000.0) return; int nbins = int(ceil(maxNBins)); // note just linear bins width = (realResults[soMax] - realResults[soMin]) / double(nbins); SC_IntArray binCount(nbins, 0); for (int i = 0; i < data.Size(); i++) { double dVal = data[i]; if (RealIsNull(dVal) || (dVal < realResults[soMin])) // can happen if stats calc was log continue; int binIndex = int(floor((dVal - realResults[soMin]) / width)); // pathological case == maxVal if (binIndex == nbins) binIndex--; binCount[binIndex]++; } int maxBin = 0; int maxCount = binCount[0]; for (int i = 1; i < nbins; i++) if (binCount[i] > maxCount) { maxBin = i; maxCount = binCount[i]; } realResults[soMode] = realResults[soMin] + (double(maxBin) + 0.5) * width; }
/** * This gets called every time the scatter plot is re-drawn. This returns the * counts for each DN (x), DN (y), or if the bin is alarmed this returns the * max count. * * @param x The X-Dn value * @param y The Y-Dn value * @return The bin's colorizable-value */ double ScatterPlotData::value(double x, double y) const { double value = 0; QPair<int, int> indices = binXYIndices(x, y); int index = binIndex(indices.first, indices.second); if (index != -1 && (*m_alarmedBins)[index]) value = m_maxCount; else value = binCount(indices.first, indices.second); return value; }
void CMT::estimate(const std::vector<std::pair<cv::KeyPoint, int> >& keypointsIN, cv::Point2f& center, float& scaleEstimate, float& medRot, std::vector<std::pair<cv::KeyPoint, int> >& keypoints) { center = cv::Point2f(NAN,NAN); scaleEstimate = NAN; medRot = NAN; //At least 2 keypoints are needed for scale if(keypointsIN.size() > 1) { //sort std::vector<PairInt> list; for(int i = 0; i < keypointsIN.size(); i++) list.push_back(std::make_pair(keypointsIN[i].second, i)); std::sort(&list[0], &list[0]+list.size(), comparatorPair<int>); for(int i = 0; i < list.size(); i++) keypoints.push_back(keypointsIN[list[i].second]); std::vector<int> ind1; std::vector<int> ind2; for(int i = 0; i < list.size(); i++) for(int j = 0; j < list.size(); j++) { if(i != j && keypoints[i].second != keypoints[j].second) { ind1.push_back(i); ind2.push_back(j); } } if(ind1.size() > 0) { std::vector<int> class_ind1; std::vector<int> class_ind2; std::vector<cv::KeyPoint> pts_ind1; std::vector<cv::KeyPoint> pts_ind2; for(int i = 0; i < ind1.size(); i++) { class_ind1.push_back(keypoints[ind1[i]].second-1); class_ind2.push_back(keypoints[ind2[i]].second-1); pts_ind1.push_back(keypoints[ind1[i]].first); pts_ind2.push_back(keypoints[ind2[i]].first); } std::vector<float> scaleChange; std::vector<float> angleDiffs; for(int i = 0; i < pts_ind1.size(); i++) { cv::Point2f p = pts_ind2[i].pt - pts_ind1[i].pt; //This distance might be 0 for some combinations, //as it can happen that there is more than one keypoint at a single location float dist = sqrt(p.dot(p)); float origDist = squareForm[class_ind1[i]][class_ind2[i]]; scaleChange.push_back(dist/origDist); //Compute angle float angle = atan2(p.y, p.x); float origAngle = angles[class_ind1[i]][class_ind2[i]]; float angleDiff = angle - origAngle; //Fix long way angles if(fabs(angleDiff) > CV_PI) angleDiff -= sign(angleDiff) * 2 * CV_PI; angleDiffs.push_back(angleDiff); } scaleEstimate = median(scaleChange); if(!estimateScale) scaleEstimate = 1; medRot = median(angleDiffs); if(!estimateRotation) medRot = 0; votes = std::vector<cv::Point2f>(); for(int i = 0; i < keypoints.size(); i++) votes.push_back(keypoints[i].first.pt - scaleEstimate * rotate(springs[keypoints[i].second-1], medRot)); //Compute linkage between pairwise distances std::vector<Cluster> linkageData = linkage(votes); //Perform hierarchical distance-based clustering std::vector<int> T = fcluster(linkageData, thrOutlier); //Count votes for each cluster std::vector<int> cnt = binCount(T); //Get largest class int Cmax = argmax(cnt); //Remember outliers outliers = std::vector<std::pair<cv::KeyPoint, int> >(); std::vector<std::pair<cv::KeyPoint, int> > newKeypoints; std::vector<cv::Point2f> newVotes; for(int i = 0; i < keypoints.size(); i++) { if(T[i] != Cmax) outliers.push_back(keypoints[i]); else { newKeypoints.push_back(keypoints[i]); newVotes.push_back(votes[i]); } } keypoints = newKeypoints; center = cv::Point2f(0,0); for(int i = 0; i < newVotes.size(); i++) center += newVotes[i]; center *= (1.0/newVotes.size()); } } }
void PeaksWorkspace::saveNexus(::NeXus::File * file) const { //Number of Peaks const size_t np(peaks.size()); // Column vectors for peaks table std::vector<int> detectorID(np); std::vector<double> H(np); std::vector<double> K(np); std::vector<double> L(np); std::vector<double> intensity(np); std::vector<double> sigmaIntensity(np); std::vector<double> binCount(np); std::vector<double> initialEnergy(np); std::vector<double> finalEnergy(np); std::vector<double> waveLength(np); std::vector<double> scattering(np); std::vector<double> dSpacing(np); std::vector<double> TOF(np); std::vector<int> runNumber(np); std::vector<double> goniometerMatrix(9 * np); // Populate column vectors from Peak Workspace for (size_t i = 0; i < np; i++) { Peak p = peaks[i]; detectorID[i] = p.getDetectorID(); H[i] = p.getH(); K[i] = p.getK(); L[i] = p.getL(); intensity[i] = p.getIntensity(); sigmaIntensity[i] = p.getSigmaIntensity(); binCount[i] = p.getBinCount(); initialEnergy[i] = p.getInitialEnergy(); finalEnergy[i] = p.getFinalEnergy(); waveLength[i] = p.getWavelength(); scattering[i] = p.getScattering(); dSpacing[i] = p.getDSpacing(); TOF[i] = p.getTOF(); runNumber[i] = p.getRunNumber(); { Matrix<double> gm = p.getGoniometerMatrix(); goniometerMatrix[9 * i] = gm[0][0]; goniometerMatrix[9 * i + 1] = gm[1][0]; goniometerMatrix[9 * i + 2] = gm[2][0]; goniometerMatrix[9 * i + 3] = gm[0][1]; goniometerMatrix[9 * i + 4] = gm[1][1]; goniometerMatrix[9 * i + 5] = gm[2][1]; goniometerMatrix[9 * i + 6] = gm[0][2]; goniometerMatrix[9 * i + 7] = gm[1][2]; goniometerMatrix[9 * i + 8] = gm[1][2]; } // etc. } // Start Peaks Workspace in Nexus File std::string specifyInteger = "An integer"; std::string specifyDouble = "A double"; file->makeGroup("peaks_workspace", "NXentry", true); // For when peaksWorkspace can be loaded // Detectors column file->writeData("column_1", detectorID); file->openData("column_1"); file->putAttr("name", "Dectector ID"); file->putAttr("interpret_as", specifyInteger); file->putAttr("units", "Not known"); file->closeData(); // H column file->writeData("column_2", H); file->openData("column_2"); file->putAttr("name", "H"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // K column file->writeData("column_3", K); file->openData("column_3"); file->putAttr("name", "K"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // L column file->writeData("column_4", L); file->openData("column_4"); file->putAttr("name", "L"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Intensity column file->writeData("column_5", intensity); file->openData("column_5"); file->putAttr("name", "Intensity"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Sigma Intensity column file->writeData("column_6", sigmaIntensity); file->openData("column_6"); file->putAttr("name", "Sigma Intensity"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Bin Count column file->writeData("column_7", binCount); file->openData("column_7"); file->putAttr("name", "Bin Count"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Initial Energy column file->writeData("column_8", initialEnergy); file->openData("column_8"); file->putAttr("name", "Initial Energy"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Final Energy column file->writeData("column_9", finalEnergy); file->openData("column_9"); file->putAttr("name", "Final Energy"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Wave Length Column file->writeData("column_10", waveLength); file->openData("column_10"); file->putAttr("name", "Wave Length"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Scattering Column file->writeData("column_11", scattering); file->openData("column_11"); file->putAttr("name", "Scattering"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // D Spacing Column file->writeData("column_12", dSpacing); file->openData("column_12"); file->putAttr("name", "D Spacing"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // TOF Column file->writeData("column_13", TOF); file->openData("column_13"); file->putAttr("name", "TOF"); file->putAttr("interpret_as", specifyDouble); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); //Run Number column file->writeData("column_14", runNumber); file->openData("column_14"); file->putAttr("name", "Run Number"); file->putAttr("interpret_as", specifyInteger); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // Goniometer Matrix Column std::vector<int> array_dims; array_dims.push_back(static_cast<int>(peaks.size())); array_dims.push_back(9); file->writeData("column_15", goniometerMatrix, array_dims); file->openData("column_15"); file->putAttr("name", "Goniometer Matrix"); file->putAttr("interpret_as", "A matrix of 3x3 doubles"); file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); // QLab & QSample are calculated and do not need to be saved file->closeGroup(); // end of peaks workpace }
/** * Get the count (number of values) which fall into the bin at index. * * @param binIndex The bin we're getting the data from * @return The total number of cube DNs which fall into the given bin */ int ScatterPlotData::binCount(int binIndex) const { QPair<int, int> indices = binXYIndices(binIndex); return binCount(indices.first, indices.second); }