Conversation
…h is defined by one or the other, and they are not the same. IMO, we assume the width values given in the dQ column correspond to sigma.
…et methods do not exist. Valid solution or should we implement _raw_metadata and children?
…Using a dict now for the axis and changed also name to plural: Trend.trend_axes, so unit tests changed accordingly
There was a problem hiding this comment.
No quality gates enabled for this code.
See analysis details in CodeScene
Quality Gate Profile: Custom Configuration
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.
| where *Q* is assumed to have units of 1/Angstrom, *I(Q)* is assumed to have | ||
| units of 1/cm, *dI(Q)* is the uncertainty on the intensity value (also as 1/cm), | ||
| and *dQ(Q)* **is the one-sigma FWHM Gaussian instrumental resolution in** *Q*, | ||
| and *dQ(Q)* **is the one-sigma Gaussian instrumental resolution in** *Q*, |
There was a problem hiding this comment.
dQ(Q) values come from the Mildner & Carpenter equation. But what they actually represent depends if they come from reactor-SANS or a TOF-SANS; the former has 'Gaussian' wavelength distributions, the latter uses rectangular bins. @RichardHeenan discusses this in https://doi.org/10.1107/S0021889897002173, but see https://docs.mantidproject.org/nightly/algorithms/TOFSANSResolutionByPixel-v1.html for how ISIS SANS and SNS SANS (and probably CSNS SANS) compute dQ(Q). So I would argue that neither the existing text, nor the proposed text, are sufficiently generic.
Maybe change to:
and *dQ(Q)* **is the one-sigma instrumental resolution in** *Q* and may be defined differently by different instruments (consult the instrument team),
| if self.contents: | ||
| if type(self.contents) is str: | ||
| match self.contents: | ||
| case str(): |
There was a problem hiding this comment.
The string, Quantity and ndarray cases are exactly the same as the default case. Maybe just remove all but the default?
| else: | ||
| return current_item.data | ||
| raise ValueError('End of path without finding a dataset.') | ||
| # Not a list, can't navigate further | ||
| raise ValueError('Path does not lead to a valid metadatum.') | ||
|
|
||
| if current_item is None: | ||
| raise ValueError('Path does not lead to a valid metadatum.') |
There was a problem hiding this comment.
Duplicate errors. Combine?
|
|
||
| # Warn about filtered items | ||
| if invalid_indices: | ||
| print(f"Warning: Removed data items at indices {invalid_indices} - not SasData objects or missing/invalid metadata") |
There was a problem hiding this comment.
The print statements should probably be changed to logging.warn.
| for axis_name, axis_config in self.trend_axes.items(): | ||
| if isinstance(axis_config, list) and not isinstance(axis_config[0], str): | ||
| # This is a manual value list (not a path) | ||
| if len(axis_config) != len(self.data): |
|
|
||
| axis_config = self.trend_axes[axis_name] | ||
|
|
||
| if isinstance(axis_config, list) and len(axis_config) > 0 and isinstance(axis_config[0], str): |
There was a problem hiding this comment.
This check is already performed when creating the trend. Is this necessary?
Proposition to modify the original Trend class. The idea is that one can define as many axes as desired, using a dict to store them. Each axis can be linked to a metadata (given a list with the path to the metadata as before) or generated "on the fly" (in this case one has also to give a list, with the constraints that the first element must NOT be a string and the number of elements in the list must be equal to the number of SasData objects in data. Are these limitations OK)?
If it is agreed that this is the right way, next steps should be to clean up a little bit the code and add new utests.