comparison layer/SliceLayer.cpp @ 1472:dbff4b290bf0 by-id

Further layer updates
author Chris Cannam
date Mon, 01 Jul 2019 14:25:53 +0100
parents c8a6fd3f9dff
children 0e971e3d93e2
comparison
equal deleted inserted replaced
1471:f2525e6cbdf1 1472:dbff4b290bf0
30 #include <QPainterPath> 30 #include <QPainterPath>
31 #include <QTextStream> 31 #include <QTextStream>
32 32
33 33
34 SliceLayer::SliceLayer() : 34 SliceLayer::SliceLayer() :
35 m_sliceableModel(nullptr),
36 m_binAlignment(BinsSpanScalePoints), 35 m_binAlignment(BinsSpanScalePoints),
37 m_colourMap(int(ColourMapper::Ice)), 36 m_colourMap(int(ColourMapper::Ice)),
38 m_colourInverted(false), 37 m_colourInverted(false),
39 m_energyScale(dBScale), 38 m_energyScale(dBScale),
40 m_samplingMode(SampleMean), 39 m_samplingMode(SampleMean),
55 { 54 {
56 55
57 } 56 }
58 57
59 void 58 void
60 SliceLayer::setSliceableModel(const Model *model) 59 SliceLayer::setSliceableModel(ModelId modelId)
61 { 60 {
62 const DenseThreeDimensionalModel *sliceable = 61 auto newModel = ModelById::getAs<DenseThreeDimensionalModel>(modelId);
63 dynamic_cast<const DenseThreeDimensionalModel *>(model); 62
64 63 if (!modelId.isNone() && !newModel) {
65 if (model && !sliceable) { 64 throw std::logic_error("Not a DenseThreeDimensionalModel");
66 cerr << "WARNING: SliceLayer::setSliceableModel(" << model 65 }
67 << "): model is not a DenseThreeDimensionalModel" << endl; 66
68 } 67 if (m_sliceableModel == modelId) return;
69 68 m_sliceableModel = modelId;
70 if (m_sliceableModel == sliceable) return; 69
71 70 if (newModel) {
72 m_sliceableModel = sliceable; 71 connectSignals(m_sliceableModel);
73 72
74 if (!m_sliceableModel) return; 73 if (m_minbin == 0 && m_maxbin == 0) {
75 74 m_minbin = 0;
76 connectSignals(m_sliceableModel); 75 m_maxbin = newModel->getHeight();
77 76 }
78 if (m_minbin == 0 && m_maxbin == 0) {
79 m_minbin = 0;
80 m_maxbin = m_sliceableModel->getHeight();
81 } 77 }
82 78
83 emit modelReplaced(); 79 emit modelReplaced();
84 emit layerParametersChanged(); 80 emit layerParametersChanged();
85 } 81 }
86 82
87 void 83 void
88 SliceLayer::sliceableModelReplaced(const Model *orig, const Model *replacement) 84 SliceLayer::sliceableModelReplaced(ModelId orig, ModelId replacement)
89 { 85 {
90 SVDEBUG << "SliceLayer::sliceableModelReplaced(" << orig << ", " << replacement << ")" << endl; 86 SVDEBUG << "SliceLayer::sliceableModelReplaced(" << orig << ", " << replacement << ")" << endl;
91 87
92 if (orig == m_sliceableModel) { 88 if (orig == m_sliceableModel) {
93 setSliceableModel 89 setSliceableModel(replacement);
94 (dynamic_cast<const DenseThreeDimensionalModel *>(replacement)); 90 }
95 } 91 }
96 } 92 /*!!!
97
98 void 93 void
99 SliceLayer::modelAboutToBeDeleted(Model *m) 94 SliceLayer::modelAboutToBeDeleted(Model *m)
100 { 95 {
101 SVDEBUG << "SliceLayer::modelAboutToBeDeleted(" << m << ")" << endl; 96 SVDEBUG << "SliceLayer::modelAboutToBeDeleted(" << m << ")" << endl;
102 97
103 if (m == m_sliceableModel) { 98 if (m == m_sliceableModel) {
104 setSliceableModel(nullptr); 99 setSliceableModel(nullptr);
105 } 100 }
106 } 101 }
107 102 */
108 QString 103 QString
109 SliceLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &p) const 104 SliceLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &p) const
110 { 105 {
111 int minbin, maxbin, range; 106 int minbin, maxbin, range;
112 return getFeatureDescriptionAux(v, p, true, minbin, maxbin, range); 107 return getFeatureDescriptionAux(v, p, true, minbin, maxbin, range);
117 bool includeBinDescription, 112 bool includeBinDescription,
118 int &minbin, int &maxbin, int &range) const 113 int &minbin, int &maxbin, int &range) const
119 { 114 {
120 minbin = 0; 115 minbin = 0;
121 maxbin = 0; 116 maxbin = 0;
122 if (!m_sliceableModel) return ""; 117
118 auto sliceableModel =
119 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel);
120 if (!sliceableModel) return "";
123 121
124 if (m_binAlignment == BinsSpanScalePoints) { 122 if (m_binAlignment == BinsSpanScalePoints) {
125 minbin = int(getBinForX(v, p.x())); 123 minbin = int(getBinForX(v, p.x()));
126 maxbin = int(getBinForX(v, p.x() + 1)); 124 maxbin = int(getBinForX(v, p.x() + 1));
127 } else { 125 } else {
128 minbin = int(getBinForX(v, p.x()) + 0.5); 126 minbin = int(getBinForX(v, p.x()) + 0.5);
129 maxbin = int(getBinForX(v, p.x() + 1) + 0.5); 127 maxbin = int(getBinForX(v, p.x() + 1) + 0.5);
130 } 128 }
131 129
132 int mh = m_sliceableModel->getHeight(); 130 int mh = sliceableModel->getHeight();
133 if (minbin >= mh) minbin = mh - 1; 131 if (minbin >= mh) minbin = mh - 1;
134 if (maxbin >= mh) maxbin = mh - 1; 132 if (maxbin >= mh) maxbin = mh - 1;
135 if (minbin < 0) minbin = 0; 133 if (minbin < 0) minbin = 0;
136 if (maxbin < 0) maxbin = 0; 134 if (maxbin < 0) maxbin = 0;
137 135
138 sv_samplerate_t sampleRate = m_sliceableModel->getSampleRate(); 136 sv_samplerate_t sampleRate = sliceableModel->getSampleRate();
139 137
140 sv_frame_t f0 = m_currentf0; 138 sv_frame_t f0 = m_currentf0;
141 sv_frame_t f1 = m_currentf1; 139 sv_frame_t f1 = m_currentf1;
142 140
143 RealTime rt0 = RealTime::frame2RealTime(f0, sampleRate); 141 RealTime rt0 = RealTime::frame2RealTime(f0, sampleRate);
418 } 416 }
419 417
420 void 418 void
421 SliceLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const 419 SliceLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const
422 { 420 {
423 if (!m_sliceableModel || 421 auto sliceableModel =
424 !m_sliceableModel->isOK() || 422 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel);
425 !m_sliceableModel->isReady()) return; 423 if (!sliceableModel ||
424 !sliceableModel->isOK() ||
425 !sliceableModel->isReady()) return;
426 426
427 Profiler profiler("SliceLayer::paint()"); 427 Profiler profiler("SliceLayer::paint()");
428 428
429 paint.save(); 429 paint.save();
430 paint.setRenderHint(QPainter::Antialiasing, true); 430 paint.setRenderHint(QPainter::Antialiasing, true);
440 rect.width(), m_scalePoints[i] * ratio); 440 rect.width(), m_scalePoints[i] * ratio);
441 } 441 }
442 } 442 }
443 } 443 }
444 444
445 int mh = m_sliceableModel->getHeight(); 445 int mh = sliceableModel->getHeight();
446 int bin0 = 0; 446 int bin0 = 0;
447 if (m_maxbin > m_minbin) { 447 if (m_maxbin > m_minbin) {
448 mh = m_maxbin - m_minbin; 448 mh = m_maxbin - m_minbin;
449 bin0 = m_minbin; 449 bin0 = m_minbin;
450 } 450 }
491 sv_frame_t f1 = v->getFrameForX(f0x + 1); 491 sv_frame_t f1 = v->getFrameForX(f0x + 1);
492 if (f1 > f0) --f1; 492 if (f1 > f0) --f1;
493 493
494 // cerr << "centre frame " << v->getCentreFrame() << ", x " << f0x << ", f0 " << f0 << ", f1 " << f1 << endl; 494 // cerr << "centre frame " << v->getCentreFrame() << ", x " << f0x << ", f0 " << f0 << ", f1 " << f1 << endl;
495 495
496 int res = m_sliceableModel->getResolution(); 496 int res = sliceableModel->getResolution();
497 int col0 = int(f0 / res); 497 int col0 = int(f0 / res);
498 int col1 = col0; 498 int col1 = col0;
499 if (m_samplingMode != NearestSample) col1 = int(f1 / res); 499 if (m_samplingMode != NearestSample) col1 = int(f1 / res);
500 f0 = col0 * res; 500 f0 = col0 * res;
501 f1 = (col1 + 1) * res - 1; 501 f1 = (col1 + 1) * res - 1;
510 getBiasCurve(curve); 510 getBiasCurve(curve);
511 int cs = int(curve.size()); 511 int cs = int(curve.size());
512 512
513 for (int col = col0; col <= col1; ++col) { 513 for (int col = col0; col <= col1; ++col) {
514 DenseThreeDimensionalModel::Column column = 514 DenseThreeDimensionalModel::Column column =
515 m_sliceableModel->getColumn(col); 515 sliceableModel->getColumn(col);
516 for (int bin = 0; bin < mh; ++bin) { 516 for (int bin = 0; bin < mh; ++bin) {
517 float value = column[bin0 + bin]; 517 float value = column[bin0 + bin];
518 if (bin < cs) value *= curve[bin]; 518 if (bin < cs) value *= curve[bin];
519 if (m_samplingMode == SamplePeak) { 519 if (m_samplingMode == SamplePeak) {
520 if (value > m_values[bin]) m_values[bin] = value; 520 if (value > m_values[bin]) m_values[bin] = value;
672 } 672 }
673 673
674 int 674 int
675 SliceLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) const 675 SliceLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) const
676 { 676 {
677 // Qt 5.13 deprecates QFontMetrics::width(), but its suggested
678 // replacement (horizontalAdvance) was only added in Qt 5.11
679 // which is too new for us
680 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
681
677 int width; 682 int width;
678 if (m_energyScale == LinearScale || m_energyScale == AbsoluteScale) { 683 if (m_energyScale == LinearScale || m_energyScale == AbsoluteScale) {
679 width = std::max(paint.fontMetrics().width("0.0") + 13, 684 width = std::max(paint.fontMetrics().width("0.0") + 13,
680 paint.fontMetrics().width("x10-10")); 685 paint.fontMetrics().width("x10-10"));
681 } else { 686 } else {
1164 1169
1165 bool 1170 bool
1166 SliceLayer::getValueExtents(double &min, double &max, bool &logarithmic, 1171 SliceLayer::getValueExtents(double &min, double &max, bool &logarithmic,
1167 QString &unit) const 1172 QString &unit) const
1168 { 1173 {
1169 if (!m_sliceableModel) return false; 1174 auto sliceableModel =
1175 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel);
1176 if (!sliceableModel) return false;
1170 1177
1171 min = 0; 1178 min = 0;
1172 max = double(m_sliceableModel->getHeight()); 1179 max = double(sliceableModel->getHeight());
1173 1180
1174 logarithmic = (m_binScale == BinScale::LogBins); 1181 logarithmic = (m_binScale == BinScale::LogBins);
1175 unit = ""; 1182 unit = "";
1176 1183
1177 return true; 1184 return true;
1178 } 1185 }
1179 1186
1180 bool 1187 bool
1181 SliceLayer::getDisplayExtents(double &min, double &max) const 1188 SliceLayer::getDisplayExtents(double &min, double &max) const
1182 { 1189 {
1183 if (!m_sliceableModel) return false; 1190 auto sliceableModel =
1184 1191 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel);
1185 double hmax = double(m_sliceableModel->getHeight()); 1192 if (!sliceableModel) return false;
1193
1194 double hmax = double(sliceableModel->getHeight());
1186 1195
1187 min = m_minbin; 1196 min = m_minbin;
1188 max = m_maxbin; 1197 max = m_maxbin;
1189 if (max <= min) { 1198 if (max <= min) {
1190 min = 0; 1199 min = 0;
1197 } 1206 }
1198 1207
1199 bool 1208 bool
1200 SliceLayer::setDisplayExtents(double min, double max) 1209 SliceLayer::setDisplayExtents(double min, double max)
1201 { 1210 {
1202 if (!m_sliceableModel) return false; 1211 auto sliceableModel =
1212 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel);
1213 if (!sliceableModel) return false;
1203 1214
1204 m_minbin = int(lrint(min)); 1215 m_minbin = int(lrint(min));
1205 m_maxbin = int(lrint(max)); 1216 m_maxbin = int(lrint(max));
1206 1217
1207 if (m_minbin < 0) { 1218 if (m_minbin < 0) {
1208 m_minbin = 0; 1219 m_minbin = 0;
1209 } 1220 }
1210 if (m_maxbin < 0) { 1221 if (m_maxbin < 0) {
1211 m_maxbin = 0; 1222 m_maxbin = 0;
1212 } 1223 }
1213 if (m_minbin > m_sliceableModel->getHeight()) { 1224 if (m_minbin > sliceableModel->getHeight()) {
1214 m_minbin = m_sliceableModel->getHeight(); 1225 m_minbin = sliceableModel->getHeight();
1215 } 1226 }
1216 if (m_maxbin > m_sliceableModel->getHeight()) { 1227 if (m_maxbin > sliceableModel->getHeight()) {
1217 m_maxbin = m_sliceableModel->getHeight(); 1228 m_maxbin = sliceableModel->getHeight();
1218 } 1229 }
1219 if (m_maxbin < m_minbin) { 1230 if (m_maxbin < m_minbin) {
1220 m_maxbin = m_minbin; 1231 m_maxbin = m_minbin;
1221 } 1232 }
1222 1233
1225 } 1236 }
1226 1237
1227 int 1238 int
1228 SliceLayer::getVerticalZoomSteps(int &defaultStep) const 1239 SliceLayer::getVerticalZoomSteps(int &defaultStep) const
1229 { 1240 {
1230 if (!m_sliceableModel) return 0; 1241 auto sliceableModel =
1242 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel);
1243 if (!sliceableModel) return 0;
1231 1244
1232 defaultStep = 0; 1245 defaultStep = 0;
1233 int h = m_sliceableModel->getHeight(); 1246 int h = sliceableModel->getHeight();
1234 return h; 1247 return h;
1235 } 1248 }
1236 1249
1237 int 1250 int
1238 SliceLayer::getCurrentVerticalZoomStep() const 1251 SliceLayer::getCurrentVerticalZoomStep() const
1239 { 1252 {
1240 if (!m_sliceableModel) return 0; 1253 auto sliceableModel =
1254 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel);
1255 if (!sliceableModel) return 0;
1241 1256
1242 double min, max; 1257 double min, max;
1243 getDisplayExtents(min, max); 1258 getDisplayExtents(min, max);
1244 return m_sliceableModel->getHeight() - int(lrint(max - min)); 1259 return sliceableModel->getHeight() - int(lrint(max - min));
1245 } 1260 }
1246 1261
1247 void 1262 void
1248 SliceLayer::setVerticalZoomStep(int step) 1263 SliceLayer::setVerticalZoomStep(int step)
1249 { 1264 {
1250 if (!m_sliceableModel) return; 1265 auto sliceableModel =
1266 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel);
1267 if (!sliceableModel) return;
1251 1268
1252 // SVDEBUG << "SliceLayer::setVerticalZoomStep(" <<step <<"): before: minbin = " << m_minbin << ", maxbin = " << m_maxbin << endl; 1269 // SVDEBUG << "SliceLayer::setVerticalZoomStep(" <<step <<"): before: minbin = " << m_minbin << ", maxbin = " << m_maxbin << endl;
1253 1270
1254 int dist = m_sliceableModel->getHeight() - step; 1271 int dist = sliceableModel->getHeight() - step;
1255 if (dist < 1) dist = 1; 1272 if (dist < 1) dist = 1;
1256 double centre = m_minbin + (m_maxbin - m_minbin) / 2.0; 1273 double centre = m_minbin + (m_maxbin - m_minbin) / 2.0;
1257 int minbin = int(lrint(centre - dist/2.0)); 1274 int minbin = int(lrint(centre - dist/2.0));
1258 int maxbin = minbin + dist; 1275 int maxbin = minbin + dist;
1259 setDisplayExtents(minbin, maxbin); 1276 setDisplayExtents(minbin, maxbin);
1260 } 1277 }
1261 1278
1262 RangeMapper * 1279 RangeMapper *
1263 SliceLayer::getNewVerticalZoomRangeMapper() const 1280 SliceLayer::getNewVerticalZoomRangeMapper() const
1264 { 1281 {
1265 if (!m_sliceableModel) return nullptr; 1282 auto sliceableModel =
1266 1283 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel);
1267 return new LinearRangeMapper(0, m_sliceableModel->getHeight(), 1284 if (!sliceableModel) return nullptr;
1268 0, m_sliceableModel->getHeight(), ""); 1285
1286 return new LinearRangeMapper(0, sliceableModel->getHeight(),
1287 0, sliceableModel->getHeight(), "");
1269 } 1288 }
1270 1289
1271 void 1290 void
1272 SliceLayer::zoomToRegion(const LayerGeometryProvider *v, QRect rect) 1291 SliceLayer::zoomToRegion(const LayerGeometryProvider *v, QRect rect)
1273 { 1292 {