Skip to content
This repository has been archived by the owner on Nov 7, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into sort-json-keys
Browse files Browse the repository at this point in the history
  • Loading branch information
ggoneiESS authored Aug 3, 2023
2 parents d6b04ab + c64b186 commit e252710
Show file tree
Hide file tree
Showing 12 changed files with 388 additions and 64 deletions.
7 changes: 7 additions & 0 deletions nexus_constructor/geometry/pixel_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class PixelGrid(PixelData):
The corner that counting starts in, and whether counting should first happen along rows or columns can be set with
the 'count_direction' and 'initial_count_corner' attributes, which respectively take 'CountDirection' and 'Corner'
Enum values.
If there are gaps between pixels at regular intervals, the number of pixels between two gaps is configured
via the 'gap_every_rows' / 'gap_every_columns' attributes, and the size of the gap is set with 'row_gap_height'
/ 'column_gap_width'.
"""

rows = attr.ib(default=1, type=int)
Expand All @@ -51,6 +54,10 @@ class PixelGrid(PixelData):
first_id = attr.ib(default=0, type=int)
count_direction = attr.ib(default=CountDirection.ROW, type=CountDirection)
initial_count_corner = attr.ib(default=Corner.BOTTOM_LEFT, type=Corner)
gap_every_rows = attr.ib(default=0, type=int)
gap_every_columns = attr.ib(default=0, type=int)
row_gap_height = attr.ib(default=0, type=float)
column_gap_width = attr.ib(default=0, type=float)


@attr.s
Expand Down
40 changes: 32 additions & 8 deletions nexus_constructor/geometry/pixel_data_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,22 @@ def get_x_offsets_from_pixel_grid(grid: PixelGrid) -> Union[np.ndarray, float]:
Returns an array of x-offsets. Each value in the array is the x position of a pixel instance defined in the
PixelGrid.
"""
half_distance = grid.col_width / 2
end = half_distance * (grid.columns - 1)

offsets = np.linspace(start=-end, stop=end, num=grid.columns)
if grid.gap_every_columns > 0:
total_width = (
grid.columns * grid.col_width
+ ((grid.columns - 1) // grid.gap_every_columns) * grid.column_gap_width
)
else:
total_width = grid.columns * grid.col_width

start = -total_width / 2 + grid.col_width / 2
offsets = np.zeros(grid.columns)
gap_counter = 0
for i in range(grid.columns):
offsets[i] = start + i * grid.col_width + gap_counter * grid.column_gap_width
# If there is a gap, increment the gap counter
if grid.gap_every_columns > 0 and (i + 1) % grid.gap_every_columns == 0:
gap_counter += 1
return np.tile(offsets, (grid.rows, 1))


Expand All @@ -69,10 +81,22 @@ def get_y_offsets_from_pixel_grid(grid: PixelGrid) -> Union[np.ndarray, float]:
Returns an array of y-offsets. Each value in the array is the y position of a pixel instance defined in the
PixelGrid.
"""
half_distance = grid.row_height / 2
end = half_distance * (grid.rows - 1)

offsets = np.linspace(start=end, stop=-end, num=grid.rows)
if grid.gap_every_rows > 0:
total_height = (
grid.rows * grid.row_height
+ ((grid.rows - 1) // grid.gap_every_rows) * grid.row_gap_height
)
else:
total_height = grid.rows * grid.row_height

start = total_height / 2 - grid.row_height / 2
offsets = np.zeros(grid.rows)
gap_counter = 0
for i in range(grid.rows):
offsets[i] = start - i * grid.row_height - gap_counter * grid.row_gap_height
# If there is a gap, increment the gap counter
if grid.gap_every_rows > 0 and (i + 1) % grid.gap_every_rows == 0:
gap_counter += 1
return np.tile(offsets, (grid.columns, 1)).transpose()


Expand Down
9 changes: 0 additions & 9 deletions nexus_constructor/instrument_view/axis_colors.py

This file was deleted.

6 changes: 2 additions & 4 deletions nexus_constructor/instrument_view/gnomon.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from PySide6.QtCore import QPropertyAnimation
from PySide6.QtGui import QColor, QFont, QMatrix4x4, QVector3D, QVector4D

from nexus_constructor.instrument_view.axis_colors import AxisColors
from nexus_constructor.instrument_view.neutron_animation_controller import (
NeutronAnimationController,
)
Expand Down Expand Up @@ -174,10 +173,9 @@ def create_gnomon_text(self):
x_axis_text = Qt3DExtras.QText2DEntity(self.gnomon_root_entity)
y_axis_text = Qt3DExtras.QText2DEntity(self.gnomon_root_entity)
z_axis_text = Qt3DExtras.QText2DEntity(self.gnomon_root_entity)
self.set_axis_label_text(x_axis_text, "X", AxisColors.X.value)
# Pass "green" rather than the Y axis enum value because otherwise the text is too bright
self.set_axis_label_text(x_axis_text, "X", QColor("red"))
self.set_axis_label_text(y_axis_text, "Y", QColor("green"))
self.set_axis_label_text(z_axis_text, "Z", AxisColors.Z.value)
self.set_axis_label_text(z_axis_text, "Z", QColor("blue"))
(
x_label_matrix,
y_label_matrix,
Expand Down
14 changes: 14 additions & 0 deletions nexus_constructor/model/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,20 @@ def record_pixel_grid(self, pixel_grid: PixelGrid, unit: str = ""):
np.array(get_detector_ids_from_pixel_grid(pixel_grid)),
ValueTypes.INT,
)
if pixel_grid.gap_every_rows and pixel_grid.row_gap_height:
self.attributes.set_attribute_value(
"pixelgrid_gap_every_rows", pixel_grid.gap_every_rows
)
self.attributes.set_attribute_value(
"pixelgrid_row_gap_height", pixel_grid.row_gap_height
)
if pixel_grid.gap_every_columns and pixel_grid.column_gap_width:
self.attributes.set_attribute_value(
"pixelgrid_gap_every_columns", pixel_grid.gap_every_columns
)
self.attributes.set_attribute_value(
"pixelgrid_column_gap_width", pixel_grid.column_gap_width
)

def record_pixel_mapping(self, pixel_mapping: PixelMapping):
"""
Expand Down
4 changes: 0 additions & 4 deletions nexus_constructor/model/transformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,13 @@ def ui_value(self) -> float:
if np.isscalar(self.values.values):
val: "ValueType" = self.values.values
self.ui_value = float(val)
return float(val)
else:
self.ui_value = float(self.values.values[0])
return float(self.values.values[0])
except (ValueError, TypeError):
pass

if self._ui_value is None:
default_value = 0.0
self.ui_value = 0.0
return default_value

return self._ui_value

Expand Down
50 changes: 50 additions & 0 deletions nexus_constructor/pixel_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,18 @@ def _fill_single_pixel_fields(self, component_to_edit: Component):
self.start_counting_combo_box.setCurrentText(start_counting_text)
self.count_first_combo_box.setCurrentText(count_along_text)

# Set pixel gap information from attributes
(
gap_every_rows,
gap_every_columns,
row_gap_height,
column_gap_width,
) = self._get_pixel_gaps_information(component_to_edit)
self.gap_every_rows_spin_box.setValue(gap_every_rows)
self.gap_every_columns_spin_box.setValue(gap_every_columns)
self.row_gap_height_spin_box.setValue(row_gap_height)
self.column_gap_width_spin_box.setValue(column_gap_width)

else:
# If the pixel offset information represents a single pixel
pass
Expand Down Expand Up @@ -249,6 +261,40 @@ def _get_detector_number_information(

return first_id, start_counting_text, count_along_text

@staticmethod
def _get_pixel_gaps_information(
component_to_edit: Component,
) -> Tuple[Optional[int], Optional[int], Optional[float], Optional[float]]:
"""
Loads pixel gap information from NXdetector custom attributes.
"""
gap_every_rows = (
component_to_edit.attributes.get_attribute_value("pixelgrid_gap_every_rows")
or 0
)
gap_every_columns = (
component_to_edit.attributes.get_attribute_value(
"pixelgrid_gap_every_columns"
)
or 0
)
row_gap_height = (
component_to_edit.attributes.get_attribute_value("pixelgrid_row_gap_height")
or 0
)
column_gap_width = (
component_to_edit.attributes.get_attribute_value(
"pixelgrid_column_gap_width"
)
or 0
)
return (
int(gap_every_rows),
int(gap_every_columns),
float(row_gap_height),
float(column_gap_width),
)

def _fill_entire_shape_fields(self, component_to_edit: Component):
"""
Fill the "entire shape" fields a component that is being edited and contains pixel data.
Expand Down Expand Up @@ -492,6 +538,10 @@ def generate_pixel_data(self) -> PixelData:
initial_count_corner=INITIAL_COUNT_CORNER[
self.start_counting_combo_box.currentText()
],
gap_every_rows=self.gap_every_rows_spin_box.value(),
gap_every_columns=self.gap_every_columns_spin_box.value(),
row_gap_height=self.row_gap_height_spin_box.value(),
column_gap_width=self.column_gap_width_spin_box.value(),
)

if self.entire_shape_radio_button.isChecked():
Expand Down
4 changes: 3 additions & 1 deletion nexus_constructor/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,9 @@ def validate(self, input: str, pos: int) -> QValidator.State:
:param pos: mouse position cursor(ignored, just here to satisfy overriding function)
:return: QValidator state (Acceptable, Intermediate, Invalid) - returning intermediate because invalid stops the user from typing.
"""
if not input and not self.scalar == FILEWRITER: # More criteria here
if self.scalar == FILEWRITER:
return self._emit_and_return(True)
if not input: # More criteria here
return self._emit_and_return(False)
if self.field_type_combo.currentText() == self.scalar:
try:
Expand Down
2 changes: 1 addition & 1 deletion nx-class-documentation/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ <h1>User Manual and Reference Documentation<a class="headerlink" href="#user-man
</div>
<hr class="docutils" />
<p class="rubric">Publishing Information</p>
<p>This manual built Jul 07, 2023.</p>
<p>This manual built Jul 24, 2023.</p>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<p>This document is available in these formats online:</p>
Expand Down
Loading

0 comments on commit e252710

Please sign in to comment.