viewer: draw grid scan cells in the proportion of the scan steps
A grid scan with, say, a 20 um step in x and a 5 um step in y was drawn as a square grid, so the picture had nothing to do with the shape of the area that was scanned. The cells now carry that proportion. The anisotropy lives only in the view transform: JFJochImage gains a pixel_aspect_ (the drawn height of one pixel in units of its width, 1.0 for a detector image), the initial fit fits the image as if it were that much taller and then puts the factor back into the transform, and the grid view sets it from |step_y / step_x|. Scene coordinates stay one unit per cell, so the mouse mapping, the selected-image box, the pixel labels and the ROI code need no change and the uniform wheel zoom keeps the proportion. Measured on an 8x4 grid driven offscreen: m11/m22 comes out 4.000 for steps 20/5 um, 0.250 for 5/20, 12.333 for 37/3 and exactly 1.000 - the old behaviour - for a square step. Every cell centre still maps back through mapToScene to its own cell in all four cases. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hcoh6VNrmSswjfeMeDQqWP
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
* `rugnux` writes the unmerged MTZ by default, and a P1 merge beside it, so a wrong space group can be re-merged without reprocessing.
|
||||
* Significant improvements to symmetry handling in `rugnux`: the lattice, the point group, the setting and the systematic absences.
|
||||
* The `rugnux` report gives the resolution the CC1/2 fit reached, beside the range the reflections were written to.
|
||||
* The `jfjoch_viewer` grid scan view draws the cells in the proportion of the scan steps, so the map has the shape of the scanned area.
|
||||
|
||||
### 1.0.0-rc.165
|
||||
This is an UNSTABLE release. It includes many experimental features, as well as many AI generated fixes. We recommend using rc.152 for production use.
|
||||
|
||||
@@ -25,6 +25,9 @@ void JFJochGridScanImage::loadData(const std::vector<float> &data, const GridSca
|
||||
|
||||
W = settings.GetGridSizeX_step();
|
||||
H = settings.GetGridSizeY_step();
|
||||
// Draw a cell in the proportion of the area it covers, so a scan with a coarse x step and a
|
||||
// fine y step looks like the sample region it was taken over, not like a square grid.
|
||||
pixel_aspect_ = std::fabs(settings.GetGridStepY_um() / settings.GetGridStepX_um());
|
||||
image_fp = settings.Rearrange(data, NAN);
|
||||
|
||||
std::vector<int64_t> indices(image_fp.size());
|
||||
|
||||
@@ -954,7 +954,7 @@ void JFJochImage::fitToView() {
|
||||
}
|
||||
|
||||
void JFJochImage::fitToViewShorterSideOnce() {
|
||||
if (initial_fit_done_ && prev_H == H && prev_W == W)
|
||||
if (initial_fit_done_ && prev_H == H && prev_W == W && prev_aspect_ == pixel_aspect_)
|
||||
return;
|
||||
|
||||
|
||||
@@ -963,6 +963,7 @@ void JFJochImage::fitToViewShorterSideOnce() {
|
||||
|
||||
prev_H = H;
|
||||
prev_W = W;
|
||||
prev_aspect_ = pixel_aspect_;
|
||||
|
||||
// Guard against tiny or zero viewport (happens before layout settles)
|
||||
const QSize vp = viewport()->size();
|
||||
@@ -976,7 +977,11 @@ void JFJochImage::fitToViewShorterSideOnce() {
|
||||
setTransformationAnchor(QGraphicsView::AnchorViewCenter);
|
||||
setTransform(QTransform());
|
||||
|
||||
fitInView(QRectF(0, 0, static_cast<qreal>(W), static_cast<qreal>(H)), Qt::KeepAspectRatio);
|
||||
// Non-square pixels are fitted as if the image were as tall as they draw it, and the extra
|
||||
// height is then put back into the transform: the image still fits, and the uniform zooms
|
||||
// that follow keep the proportion.
|
||||
fitInView(QRectF(0, 0, static_cast<qreal>(W), static_cast<qreal>(H) * pixel_aspect_), Qt::KeepAspectRatio);
|
||||
scale(1.0, pixel_aspect_);
|
||||
|
||||
scale_factor = transform().m11();
|
||||
centerOn(QPointF(static_cast<qreal>(W) * 0.5, static_cast<qreal>(H) * 0.5));
|
||||
@@ -998,7 +1003,7 @@ void JFJochImage::setZoom(double input) {
|
||||
scale_factor = input;
|
||||
if (!scene())
|
||||
return;
|
||||
setTransform(QTransform::fromScale(input, input));
|
||||
setTransform(QTransform::fromScale(input, input * pixel_aspect_));
|
||||
updateOverlay();
|
||||
emitViewportChanged();
|
||||
}
|
||||
|
||||
@@ -109,6 +109,13 @@ protected:
|
||||
size_t W = 0, H = 0;
|
||||
size_t prev_W = 0, prev_H = 0;
|
||||
|
||||
// Height of one pixel as it is drawn, in units of its width. 1.0 for a detector image, where
|
||||
// pixels are square; a grid scan whose x and y steps differ sets it so that a cell is drawn
|
||||
// in the proportion of the area it covers. Only the view transform is anisotropic - scene
|
||||
// coordinates stay one unit per pixel everywhere.
|
||||
qreal pixel_aspect_ = 1.0;
|
||||
qreal prev_aspect_ = 1.0;
|
||||
|
||||
// Track initial fit state and last image size
|
||||
bool initial_fit_done_ = false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user