Mercurial > hg > svgui
diff layer/SliceLayer.cpp @ 198:c2ed5014d4ff
* Scale fixes and feature descriptions in slice layer
author | Chris Cannam |
---|---|
date | Thu, 01 Feb 2007 16:54:42 +0000 |
parents | 6b023411087b |
children | 45e995ed84d9 |
line wrap: on
line diff
--- a/layer/SliceLayer.cpp Thu Feb 01 14:31:28 2007 +0000 +++ b/layer/SliceLayer.cpp Thu Feb 01 16:54:42 2007 +0000 @@ -32,12 +32,14 @@ m_colour(Qt::darkBlue), m_colourMap(0), m_energyScale(dBScale), - m_samplingMode(SamplePeak), + m_samplingMode(SampleMean), m_plotStyle(PlotSteps), m_binScale(LinearBins), m_normalize(false), m_bias(false), - m_gain(1.0) + m_gain(1.0), + m_currentf0(0), + m_currentf1(0) { } @@ -94,6 +96,90 @@ } } +QString +SliceLayer::getFeatureDescription(View *v, QPoint &p) const +{ + if (!m_sliceableModel) return ""; + + int xorigin = m_xorigins[v]; + int w = v->width() - xorigin - 1; + + int mh = m_sliceableModel->getHeight(); + int bin = getBinForX(p.x() - xorigin, mh, w); + if (bin >= mh) bin = mh - 1; + if (bin < 0) bin = 0; + + int sampleRate = m_sliceableModel->getSampleRate(); + + size_t f0 = m_currentf0; + size_t f1 = m_currentf1; + + RealTime rt0 = RealTime::frame2RealTime(f0, sampleRate); + RealTime rt1 = RealTime::frame2RealTime(f1, sampleRate); + + size_t range = f1 - f0 + 1; + + float value = 0.f; + if (bin < m_values.size()) value = m_values[bin]; + + QString description = tr("Time:\t%1 - %2\nRange:\t%3 samples\nBin:\t%4\n%5 value:\t%6") + .arg(QString::fromStdString(rt0.toText(true))) + .arg(QString::fromStdString(rt1.toText(true))) + .arg(range) + .arg(bin + 1) + .arg(m_samplingMode == NearestSample ? tr("First") : + m_samplingMode == SampleMean ? tr("Mean") : tr("Peak")) + .arg(value); + + return description; +} + +float +SliceLayer::getXForBin(int bin, int count, float w) const +{ + float x = 0; + + switch (m_binScale) { + + case LinearBins: + x = (float(w) * bin) / count; + break; + + case LogBins: + x = (float(w) * log10f(bin + 1)) / log10f(count + 1); + break; + + case InvertedLogBins: + x = w - (float(w) * log10f(count - bin - 1)) / log10f(count); + break; + } + + return x; +} + +int +SliceLayer::getBinForX(float x, int count, float w) const +{ + int bin = 0; + + switch (m_binScale) { + + case LinearBins: + bin = int((x * count) / w + 0.0001); + break; + + case LogBins: + bin = int(powf(10.f, (x * log10f(count + 1)) / w) - 1 + 0.0001); + break; + + case InvertedLogBins: + bin = count + 1 - int(powf(10.f, (log10f(count) * (w - x)) / float(w)) + 0.0001); + break; + } + + return bin; +} + void SliceLayer::paint(View *v, QPainter &paint, QRect rect) const { @@ -116,6 +202,8 @@ // int w = (v->width() * 2) / 3; int xorigin = getVerticalScaleWidth(v, paint) + 1; //!!! (v->width() / 2) - (w / 2); int w = v->width() - xorigin - 1; + + m_xorigins[v] = xorigin; // for use in getFeatureDescription int yorigin = v->height() - 20 - paint.fontMetrics().height() - 7; int h = yorigin - paint.fontMetrics().height() - 8; @@ -129,11 +217,11 @@ int mh = m_sliceableModel->getHeight(); - float *values = new float[mh]; int divisor = 0; + m_values.clear(); for (size_t bin = 0; bin < mh; ++bin) { - values[bin] = 0.f; + m_values.push_back(0.f); } size_t f0 = v->getCentreFrame(); @@ -150,14 +238,17 @@ f0 = col0 * m_sliceableModel->getResolution(); f1 = (col1 + 1) * m_sliceableModel->getResolution() - 1; + m_currentf0 = f0; + m_currentf1 = f1; + for (size_t col = col0; col <= col1; ++col) { for (size_t bin = 0; bin < mh; ++bin) { float value = m_sliceableModel->getValueAt(col, bin); if (m_bias) value *= bin + 1; if (m_samplingMode == SamplePeak) { - if (value > values[bin]) values[bin] = value; + if (value > m_values[bin]) m_values[bin] = value; } else { - values[bin] += value; + m_values[bin] += value; } } ++divisor; @@ -165,12 +256,12 @@ float max = 0.f; for (size_t bin = 0; bin < mh; ++bin) { - if (m_samplingMode == SampleMean) values[bin] /= divisor; - if (values[bin] > max) max = values[bin]; + if (m_samplingMode == SampleMean) m_values[bin] /= divisor; + if (m_values[bin] > max) max = m_values[bin]; } if (max != 0.f && m_normalize) { for (size_t bin = 0; bin < mh; ++bin) { - values[bin] /= max; + m_values[bin] /= max; } } @@ -181,29 +272,10 @@ for (size_t bin = 0; bin < mh; ++bin) { - float x; + float x = nx; + nx = xorigin + getXForBin(bin + 1, mh, w); - switch (m_binScale) { - - case LinearBins: - x = nx; - nx = xorigin + (float(w) * (bin + 1)) / mh; - break; - - case LogBins: - x = nx; - nx = xorigin + (float(w) * (log10f(bin + 2) - log10f(1))) / - (log10f(mh + 1) - log10f(1)); - break; - - case InvertedLogBins: - x = nx; - nx = xorigin + w - (float(w) * (log10f(mh - bin) - log10f(1))) / - (log10f(mh) - log10f(1)); - break; - } - - float value = values[bin]; + float value = m_values[bin]; value *= m_gain; float norm = 0.f; @@ -270,7 +342,7 @@ paint.drawPath(path); } paint.restore(); - +/* QPoint discard; if (v->getViewManager() && v->getViewManager()->shouldShowFrameCount() && @@ -311,35 +383,6 @@ paint.fontMetrics().ascent() + 2*paint.fontMetrics().height() + 15, durationText, View::OutlinedText); } - -/* - - QString frameRange; - if (f1 != f0) { - frameRange = QString("%1 - %2").arg(f0).arg(f1); - } else { - frameRange = QString("%1").arg(f0); - } - - QString colRange; - if (col1 != col0) { - colRange = tr("%1 hops").arg(col1 - col0 + 1); - } else { - colRange = tr("1 hop"); - } - - if (v->getViewManager() && v->getViewManager()->shouldShowFrameCount()) { - - v->drawVisibleText - (paint, xorigin + 5, - paint.fontMetrics().ascent() + 5, - frameRange, View::OutlinedText); - - v->drawVisibleText - (paint, xorigin + 5, - paint.fontMetrics().ascent() + paint.fontMetrics().height() + 10, - colRange, View::OutlinedText); - } */ } @@ -383,7 +426,7 @@ PropertyList list; list.push_back("Colour"); list.push_back("Plot Type"); - list.push_back("Sampling Mode"); +// list.push_back("Sampling Mode"); list.push_back("Scale"); list.push_back("Normalize"); list.push_back("Gain"); @@ -496,8 +539,8 @@ } else if (name == "Bin Scale") { *min = 0; -// *max = 2; - *max = 1; // I don't think we really do want to offer inverted log + *max = 2; +// *max = 1; // I don't think we really do want to offer inverted log deft = (int)m_binScale; @@ -555,9 +598,9 @@ if (name == "Bin Scale") { switch (value) { default: - case 0: return tr("Linear"); - case 1: return tr("Log"); - case 2: return tr("Rev Log"); + case 0: return tr("Linear Bins"); + case 1: return tr("Log Bins"); + case 2: return tr("Rev Log Bins"); } } return tr("<unknown>");