Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SANS Loki basic workflow #60

Merged
merged 136 commits into from Feb 7, 2022
Merged

SANS Loki basic workflow #60

merged 136 commits into from Feb 7, 2022

Conversation

wpotrzebowski
Copy link
Contributor

Basic workflow for LoKI demonstarted on SANS2D data.

@wpotrzebowski wpotrzebowski marked this pull request as draft November 2, 2021 05:40
Copy link
Member

@SimonHeybrock SimonHeybrock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this addition! A number of comments below (if have not looked at the notebook yet). I think either @nvaytet or myself would pair-program with you to address some potentially more complex bits, and to ensure that this is in line with our latest guidelines (for example, helping in setting up unit tests).

src/ess/loki/load_files.py Outdated Show resolved Hide resolved
Comment on lines 52 to 53
sample.masks[f"mask_{i}_xml"] = mask_xml["spectrum", :spectrum_size].data
background.masks[f"mask_{i}_xml"] = mask_xml["spectrum", :spectrum_size].data
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Looks SANS2D specific again (with the spectrum_size argument)?
  • Is there a more sensible mask name than just enumerating? Maybe parts of the filename?

src/ess/sans/contrib.py Outdated Show resolved Hide resolved
src/ess/sans/contrib.py Outdated Show resolved Hide resolved
src/ess/sans/contrib.py Outdated Show resolved Hide resolved
src/ess/sans/sans.py Outdated Show resolved Hide resolved
src/ess/sans/sans.py Outdated Show resolved Hide resolved
src/ess/sans/sans.py Outdated Show resolved Hide resolved
src/ess/sans/contrib.py Outdated Show resolved Hide resolved
src/ess/sans/contrib.py Outdated Show resolved Hide resolved
Copy link
Member

@nvaytet nvaytet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial thoughts/comments.

import scippneutron as scn


def load_isis(filename, spectrum_size, tof_bins):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could put these functions into an io submodule

src/ess/loki/sans2d/SANS2D_reduction.ipynb Outdated Show resolved Hide resolved
" !python make_config.py -h # change to `-f path` or run in terminal\n",
"\n",
"path = dataconfig.data_root\n",
"direct_beam_file = 'DIRECT_SANS2D_REAR_34327_4m_8mm_16Feb16.dat'\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these files should be put somewhere so that the notebook can find them so it can run. We should put them on the dmsc web server.

"background_transmission_run_number = 63159 \n",
"direct_run_number = 63091\n",
"\n",
"mask_1 = f'{path}/MASK_SANS2D_REAR_Edges_16Mar2015.xml'\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand the point of having all these masks in xml files.
From the names, it seems they are masking either tubes or physical regions in space.

We should be able to come up with a programmatic way of masking the tubes, maybe if we reshape the data into logical (tube,straw,pixel) dimensions?

Maybe some masking based on count values would also be more compact?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but I believe this is simply for reproducing specific SANS2D results, so maybe ok for that, as long as we ensure that for ESS instruments a better mechanism is put in place?

"metadata": {},
"outputs": [],
"source": [
"setup_offsets(sample, sample_trans, background, background_trans, direct, sample_pos_z_offset, bench_pos_y_offset, monitor4_pos_z_offset)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the interface to this function is slightly odd. It assumes you always have the same list of input DataArrays, which hampers portability.
The function should probably just take in a single DataArray to apply corrections on, and then you call the function on the DataArrays you wish to correct.

In addition, have you thought about putting your data in a Dataset, so you can do these kind of things in a single call?

import scipp as sc


def setup_offsets(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to accept only one input data array.
You should also add type hints to the arguments

src/ess/sans/reduction.py Outdated Show resolved Hide resolved
src/ess/sans/sans.py Outdated Show resolved Hide resolved
src/ess/sans/sans.py Outdated Show resolved Hide resolved
from .normalization import solid_angle, transmission_fraction


def to_wavelength(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this in a more succint way via transform_coords?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not, because this is essentially doing half of a SANS data reduction?

@wpotrzebowski
Copy link
Contributor Author

@SimonHeybrock @nvaytet thanks for useful comments! I will start off from addressing obvious cases and then indeed pair programing session(s) would be very useful. I can also see some more open questions e.g. xml mask files that may require some broader discussion but I guess we can take it at the later stage.

Copy link
Member

@SimonHeybrock SimonHeybrock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few minor more comments/questions from my side:

idf_filename,
mask_files,
data_set,
spectrum_size,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this parameter required? Isn't it just data_set.sizes['spectrum']?

Note that we typically use ds as a generic variable names for datasets (and da for data arrays).

src/ess/sans/contrib.py Outdated Show resolved Hide resolved
src/ess/sans/normalization.py Outdated Show resolved Hide resolved

def covert_and_rebin(data, wavelength_bins, begin, end):
"""
Convertining and rebinning shifted data
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Convertining and rebinning shifted data
Convertining and rebinning shifted data

This docstring does not say more than the function name? What is the actual function purpose?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this function was called setup and I thought I can give it more descriptive name. Can revert it to setup if it works better.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if a function is just used within a file then a good name may not be so important, but it seems this is imported elsewhere (sans.py) so we probably want something that is truly descriptive?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it was initially used internally in one file but then it turned out that can be applied elswhere. Maybe contrib.py is anyway better place for such helper function?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contrib.py was menat for things that may eventuallt make it into scipp itself. I think that is quite unlikely for this particular function.

src/ess/sans/sans.py Outdated Show resolved Hide resolved
Comment on lines 44 to 45
background = (below.sum() + above.sum()) / sc.scalar(below.sizes[dim] +
above.sizes[dim])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if someone puts a mask on a monitor?

Comment on lines 89 to 91
:param dim: In the case of a numerator containing event data, this is the dimension
along which the lookup operation should be performed. This can be omitted in
case the denominator has only one dimension.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate the idea to keep this flexible, but is this ever not Q in SANS?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I hard-coded the Q in the function body instead.

Copy link
Member

@SimonHeybrock SimonHeybrock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few extra comments from reviewing the notebooks:

Comment on lines +258 to +260
"tof_masked_region = sc.concat([sample.coords['tof']['tof', 0],\n",
" mask_tof_min, mask_tof_max,\n",
" sample.coords['tof']['tof', -1]], dim='tof')\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes event data. Maybe mention this on top of the notebook?

"\n",
"**Note:** We use programatic masks here and not those stored in xml files.\n",
"\n",
"# Mask bad pixels\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"# Mask bad pixels\n",
"### Mask bad pixels\n",

?

"metadata": {},
"outputs": [],
"source": [
"result = sample_q.bins.sum() - background_q.bins.sum()\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two notes here:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I would keep the same binning as was requested at the top of the notebook?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly, but there may be performance advantages to use a coarse Q binning when the computing I(Q) numerator. Not saying the change this now, but you may put a note, maybe?

Comment on lines 288 to 291
" data_incident_monitor=binned['background'].attrs[\"monitor2\"].value,\n",
" data_transmission_monitor=binned['background'].attrs[\"monitor4\"].value,\n",
" direct_incident_monitor=binned['direct'].attrs[\"monitor2\"].value,\n",
" direct_transmission_monitor=binned['direct'].attrs[\"monitor4\"].value,\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is repeated many times. How about changing the functions to take a dict of monitors as input?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we would be relying on special keys inside the to_I_of_Q function?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, you are anyway relying on special function parameter names?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added dicts, and used recursion in some functions to make them accept dict for convenience.
I think it works quite nicely.

Comment on lines 134 to 135
if isinstance(data, dict):
return {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note sure about having this recursion everywhere?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok i'll remove it here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant everywhere. Can this be solved in a more Pythonic way, without having to handle dicts in every function?

@nvaytet
Copy link
Member

nvaytet commented Feb 4, 2022

@SimonHeybrock
Wojciech says to wait before merging, as he needs to be sure that we can have the data publicly available online...

@wpotrzebowski
Copy link
Contributor Author

It is fine to use the data. I will provide reference to the publication.

@wpotrzebowski
Copy link
Contributor Author

wpotrzebowski commented Feb 5, 2022

Reduced data has been published in https://aip.scitation.org/doi/full/10.1063/5.0059238 (it is one of data sets in Fig5d - hd-DES_10_h-C16EO8). It should be sufficent to reference the paper

@nvaytet
Copy link
Member

nvaytet commented Feb 7, 2022

@wpotrzebowski can you have a quick look to see if the way I added the citation is ok?
Thanks

@nvaytet nvaytet merged commit 637b96f into main Feb 7, 2022
@nvaytet nvaytet deleted the loki_basic_workflow branch February 7, 2022 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants