comparison 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
comparison
equal deleted inserted replaced
197:6b023411087b 198:c2ed5014d4ff
30 SliceLayer::SliceLayer() : 30 SliceLayer::SliceLayer() :
31 m_sliceableModel(0), 31 m_sliceableModel(0),
32 m_colour(Qt::darkBlue), 32 m_colour(Qt::darkBlue),
33 m_colourMap(0), 33 m_colourMap(0),
34 m_energyScale(dBScale), 34 m_energyScale(dBScale),
35 m_samplingMode(SamplePeak), 35 m_samplingMode(SampleMean),
36 m_plotStyle(PlotSteps), 36 m_plotStyle(PlotSteps),
37 m_binScale(LinearBins), 37 m_binScale(LinearBins),
38 m_normalize(false), 38 m_normalize(false),
39 m_bias(false), 39 m_bias(false),
40 m_gain(1.0) 40 m_gain(1.0),
41 m_currentf0(0),
42 m_currentf1(0)
41 { 43 {
42 } 44 }
43 45
44 SliceLayer::~SliceLayer() 46 SliceLayer::~SliceLayer()
45 { 47 {
90 std::cerr << "SliceLayer::modelAboutToBeDeleted(" << m << ")" << std::endl; 92 std::cerr << "SliceLayer::modelAboutToBeDeleted(" << m << ")" << std::endl;
91 93
92 if (m == m_sliceableModel) { 94 if (m == m_sliceableModel) {
93 setSliceableModel(0); 95 setSliceableModel(0);
94 } 96 }
97 }
98
99 QString
100 SliceLayer::getFeatureDescription(View *v, QPoint &p) const
101 {
102 if (!m_sliceableModel) return "";
103
104 int xorigin = m_xorigins[v];
105 int w = v->width() - xorigin - 1;
106
107 int mh = m_sliceableModel->getHeight();
108 int bin = getBinForX(p.x() - xorigin, mh, w);
109 if (bin >= mh) bin = mh - 1;
110 if (bin < 0) bin = 0;
111
112 int sampleRate = m_sliceableModel->getSampleRate();
113
114 size_t f0 = m_currentf0;
115 size_t f1 = m_currentf1;
116
117 RealTime rt0 = RealTime::frame2RealTime(f0, sampleRate);
118 RealTime rt1 = RealTime::frame2RealTime(f1, sampleRate);
119
120 size_t range = f1 - f0 + 1;
121
122 float value = 0.f;
123 if (bin < m_values.size()) value = m_values[bin];
124
125 QString description = tr("Time:\t%1 - %2\nRange:\t%3 samples\nBin:\t%4\n%5 value:\t%6")
126 .arg(QString::fromStdString(rt0.toText(true)))
127 .arg(QString::fromStdString(rt1.toText(true)))
128 .arg(range)
129 .arg(bin + 1)
130 .arg(m_samplingMode == NearestSample ? tr("First") :
131 m_samplingMode == SampleMean ? tr("Mean") : tr("Peak"))
132 .arg(value);
133
134 return description;
135 }
136
137 float
138 SliceLayer::getXForBin(int bin, int count, float w) const
139 {
140 float x = 0;
141
142 switch (m_binScale) {
143
144 case LinearBins:
145 x = (float(w) * bin) / count;
146 break;
147
148 case LogBins:
149 x = (float(w) * log10f(bin + 1)) / log10f(count + 1);
150 break;
151
152 case InvertedLogBins:
153 x = w - (float(w) * log10f(count - bin - 1)) / log10f(count);
154 break;
155 }
156
157 return x;
158 }
159
160 int
161 SliceLayer::getBinForX(float x, int count, float w) const
162 {
163 int bin = 0;
164
165 switch (m_binScale) {
166
167 case LinearBins:
168 bin = int((x * count) / w + 0.0001);
169 break;
170
171 case LogBins:
172 bin = int(powf(10.f, (x * log10f(count + 1)) / w) - 1 + 0.0001);
173 break;
174
175 case InvertedLogBins:
176 bin = count + 1 - int(powf(10.f, (log10f(count) * (w - x)) / float(w)) + 0.0001);
177 break;
178 }
179
180 return bin;
95 } 181 }
96 182
97 void 183 void
98 SliceLayer::paint(View *v, QPainter &paint, QRect rect) const 184 SliceLayer::paint(View *v, QPainter &paint, QRect rect) const
99 { 185 {
114 paint.setPen(m_colour); 200 paint.setPen(m_colour);
115 201
116 // int w = (v->width() * 2) / 3; 202 // int w = (v->width() * 2) / 3;
117 int xorigin = getVerticalScaleWidth(v, paint) + 1; //!!! (v->width() / 2) - (w / 2); 203 int xorigin = getVerticalScaleWidth(v, paint) + 1; //!!! (v->width() / 2) - (w / 2);
118 int w = v->width() - xorigin - 1; 204 int w = v->width() - xorigin - 1;
205
206 m_xorigins[v] = xorigin; // for use in getFeatureDescription
119 207
120 int yorigin = v->height() - 20 - paint.fontMetrics().height() - 7; 208 int yorigin = v->height() - 20 - paint.fontMetrics().height() - 7;
121 int h = yorigin - paint.fontMetrics().height() - 8; 209 int h = yorigin - paint.fontMetrics().height() - 8;
122 if (h < 0) return; 210 if (h < 0) return;
123 211
127 QPainterPath path; 215 QPainterPath path;
128 float thresh = -80.f; 216 float thresh = -80.f;
129 217
130 int mh = m_sliceableModel->getHeight(); 218 int mh = m_sliceableModel->getHeight();
131 219
132 float *values = new float[mh];
133 int divisor = 0; 220 int divisor = 0;
134 221
222 m_values.clear();
135 for (size_t bin = 0; bin < mh; ++bin) { 223 for (size_t bin = 0; bin < mh; ++bin) {
136 values[bin] = 0.f; 224 m_values.push_back(0.f);
137 } 225 }
138 226
139 size_t f0 = v->getCentreFrame(); 227 size_t f0 = v->getCentreFrame();
140 int f0x = v->getXForFrame(f0); 228 int f0x = v->getXForFrame(f0);
141 f0 = v->getFrameForX(f0x); 229 f0 = v->getFrameForX(f0x);
148 col1 = f1 / m_sliceableModel->getResolution(); 236 col1 = f1 / m_sliceableModel->getResolution();
149 } 237 }
150 f0 = col0 * m_sliceableModel->getResolution(); 238 f0 = col0 * m_sliceableModel->getResolution();
151 f1 = (col1 + 1) * m_sliceableModel->getResolution() - 1; 239 f1 = (col1 + 1) * m_sliceableModel->getResolution() - 1;
152 240
241 m_currentf0 = f0;
242 m_currentf1 = f1;
243
153 for (size_t col = col0; col <= col1; ++col) { 244 for (size_t col = col0; col <= col1; ++col) {
154 for (size_t bin = 0; bin < mh; ++bin) { 245 for (size_t bin = 0; bin < mh; ++bin) {
155 float value = m_sliceableModel->getValueAt(col, bin); 246 float value = m_sliceableModel->getValueAt(col, bin);
156 if (m_bias) value *= bin + 1; 247 if (m_bias) value *= bin + 1;
157 if (m_samplingMode == SamplePeak) { 248 if (m_samplingMode == SamplePeak) {
158 if (value > values[bin]) values[bin] = value; 249 if (value > m_values[bin]) m_values[bin] = value;
159 } else { 250 } else {
160 values[bin] += value; 251 m_values[bin] += value;
161 } 252 }
162 } 253 }
163 ++divisor; 254 ++divisor;
164 } 255 }
165 256
166 float max = 0.f; 257 float max = 0.f;
167 for (size_t bin = 0; bin < mh; ++bin) { 258 for (size_t bin = 0; bin < mh; ++bin) {
168 if (m_samplingMode == SampleMean) values[bin] /= divisor; 259 if (m_samplingMode == SampleMean) m_values[bin] /= divisor;
169 if (values[bin] > max) max = values[bin]; 260 if (m_values[bin] > max) max = m_values[bin];
170 } 261 }
171 if (max != 0.f && m_normalize) { 262 if (max != 0.f && m_normalize) {
172 for (size_t bin = 0; bin < mh; ++bin) { 263 for (size_t bin = 0; bin < mh; ++bin) {
173 values[bin] /= max; 264 m_values[bin] /= max;
174 } 265 }
175 } 266 }
176 267
177 float py = 0; 268 float py = 0;
178 float nx = xorigin; 269 float nx = xorigin;
179 270
180 ColourMapper mapper(m_colourMap, 0, 1); 271 ColourMapper mapper(m_colourMap, 0, 1);
181 272
182 for (size_t bin = 0; bin < mh; ++bin) { 273 for (size_t bin = 0; bin < mh; ++bin) {
183 274
184 float x; 275 float x = nx;
185 276 nx = xorigin + getXForBin(bin + 1, mh, w);
186 switch (m_binScale) { 277
187 278 float value = m_values[bin];
188 case LinearBins:
189 x = nx;
190 nx = xorigin + (float(w) * (bin + 1)) / mh;
191 break;
192
193 case LogBins:
194 x = nx;
195 nx = xorigin + (float(w) * (log10f(bin + 2) - log10f(1))) /
196 (log10f(mh + 1) - log10f(1));
197 break;
198
199 case InvertedLogBins:
200 x = nx;
201 nx = xorigin + w - (float(w) * (log10f(mh - bin) - log10f(1))) /
202 (log10f(mh) - log10f(1));
203 break;
204 }
205
206 float value = values[bin];
207 279
208 value *= m_gain; 280 value *= m_gain;
209 float norm = 0.f; 281 float norm = 0.f;
210 float y = 0.f; 282 float y = 0.f;
211 283
268 340
269 if (m_plotStyle != PlotFilledBlocks) { 341 if (m_plotStyle != PlotFilledBlocks) {
270 paint.drawPath(path); 342 paint.drawPath(path);
271 } 343 }
272 paint.restore(); 344 paint.restore();
273 345 /*
274 QPoint discard; 346 QPoint discard;
275 347
276 if (v->getViewManager() && v->getViewManager()->shouldShowFrameCount() && 348 if (v->getViewManager() && v->getViewManager()->shouldShowFrameCount() &&
277 v->shouldIlluminateLocalFeatures(this, discard)) { 349 v->shouldIlluminateLocalFeatures(this, discard)) {
278 350
309 v->drawVisibleText 381 v->drawVisibleText
310 (paint, xorigin + 5, 382 (paint, xorigin + 5,
311 paint.fontMetrics().ascent() + 2*paint.fontMetrics().height() + 15, 383 paint.fontMetrics().ascent() + 2*paint.fontMetrics().height() + 15,
312 durationText, View::OutlinedText); 384 durationText, View::OutlinedText);
313 } 385 }
314
315 /*
316
317 QString frameRange;
318 if (f1 != f0) {
319 frameRange = QString("%1 - %2").arg(f0).arg(f1);
320 } else {
321 frameRange = QString("%1").arg(f0);
322 }
323
324 QString colRange;
325 if (col1 != col0) {
326 colRange = tr("%1 hops").arg(col1 - col0 + 1);
327 } else {
328 colRange = tr("1 hop");
329 }
330
331 if (v->getViewManager() && v->getViewManager()->shouldShowFrameCount()) {
332
333 v->drawVisibleText
334 (paint, xorigin + 5,
335 paint.fontMetrics().ascent() + 5,
336 frameRange, View::OutlinedText);
337
338 v->drawVisibleText
339 (paint, xorigin + 5,
340 paint.fontMetrics().ascent() + paint.fontMetrics().height() + 10,
341 colRange, View::OutlinedText);
342 }
343 */ 386 */
344 } 387 }
345 388
346 int 389 int
347 SliceLayer::getVerticalScaleWidth(View *v, QPainter &paint) const 390 SliceLayer::getVerticalScaleWidth(View *v, QPainter &paint) const
381 SliceLayer::getProperties() const 424 SliceLayer::getProperties() const
382 { 425 {
383 PropertyList list; 426 PropertyList list;
384 list.push_back("Colour"); 427 list.push_back("Colour");
385 list.push_back("Plot Type"); 428 list.push_back("Plot Type");
386 list.push_back("Sampling Mode"); 429 // list.push_back("Sampling Mode");
387 list.push_back("Scale"); 430 list.push_back("Scale");
388 list.push_back("Normalize"); 431 list.push_back("Normalize");
389 list.push_back("Gain"); 432 list.push_back("Gain");
390 list.push_back("Bin Scale"); 433 list.push_back("Bin Scale");
391 434
494 deft = (int)m_plotStyle; 537 deft = (int)m_plotStyle;
495 538
496 } else if (name == "Bin Scale") { 539 } else if (name == "Bin Scale") {
497 540
498 *min = 0; 541 *min = 0;
499 // *max = 2; 542 *max = 2;
500 *max = 1; // I don't think we really do want to offer inverted log 543 // *max = 1; // I don't think we really do want to offer inverted log
501 544
502 deft = (int)m_binScale; 545 deft = (int)m_binScale;
503 546
504 } else { 547 } else {
505 deft = Layer::getPropertyRangeAndValue(name, min, max); 548 deft = Layer::getPropertyRangeAndValue(name, min, max);
553 } 596 }
554 } 597 }
555 if (name == "Bin Scale") { 598 if (name == "Bin Scale") {
556 switch (value) { 599 switch (value) {
557 default: 600 default:
558 case 0: return tr("Linear"); 601 case 0: return tr("Linear Bins");
559 case 1: return tr("Log"); 602 case 1: return tr("Log Bins");
560 case 2: return tr("Rev Log"); 603 case 2: return tr("Rev Log Bins");
561 } 604 }
562 } 605 }
563 return tr("<unknown>"); 606 return tr("<unknown>");
564 } 607 }
565 608