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

26 reader for brml brucker files #43

Merged
merged 11 commits into from
Dec 8, 2023
Merged

Conversation

ka-sarthak
Copy link
Collaborator

No description provided.

@ka-sarthak ka-sarthak linked an issue Nov 30, 2023 that may be closed by this pull request
7 tasks
@ka-sarthak ka-sarthak force-pushed the 26-reader-for-brml-brucker-files branch 3 times, most recently from 4b4238f to 3f1f121 Compare December 7, 2023 12:43
@ka-sarthak ka-sarthak force-pushed the 26-reader-for-brml-brucker-files branch from f865196 to 5dab071 Compare December 8, 2023 10:07
@ka-sarthak ka-sarthak marked this pull request as ready for review December 8, 2023 10:08
Copy link
Collaborator

@hampusnasstrom hampusnasstrom left a comment

Choose a reason for hiding this comment

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

Looks good Sarthak! Would be okay like this but I'm wondering if we could deal with the units a bit better now that we anyways decided to modify the IKZ.py file. What do you think? We can also merge this for now and do that later.

@@ -259,7 +260,7 @@ def get_1d_scan(self, logger: BoundLogger=None):
if not self.data.shape[0] == 1:
if logger is not None:
logger.warning(
'Multiple/2D scan currently not supported. '
'Multiple/2D/RSM scan currently not supported. '
Copy link
Collaborator

Choose a reason for hiding this comment

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

Did you intend to also change the RASX reader now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, yeah, I agree it's not the best practice. But as it is a minor change to keep the warning message same for the two readers, i thought of pushing it here.

Comment on lines +332 to +426
class BRMLfile(object):
def __init__(self, path, exp_nbr=0, encoding="utf-8", verbose=True):
self.path = path
with zipfile.ZipFile(path, 'r') as fh:
experiment = "Experiment%i"%exp_nbr
datacontainer = "%s/DataContainer.xml"%experiment

with fh.open(datacontainer, "r") as xml:
data = xmltodict.parse(xml.read(), encoding=encoding)
rawlist = data["DataContainer"]["RawDataReferenceList"]["string"]
# rawlist contains the reference to all the raw files (multiple in case of RSM)
if not isinstance(rawlist, list):
rawlist = [rawlist]

self.data = collections.defaultdict(list)
self.motors = self.data # collections.defaultdict(list)
for i, rawpath in enumerate(rawlist):
if verbose:
if not i:
print("Loading frame %i"%i, end="")
else:
print(", %i"%i, end="")
with fh.open(rawpath, "r") as xml:
# entering RawData<int>.xml
data = xmltodict.parse(xml.read(), encoding=encoding)
dataroute = data["RawData"]["DataRoutes"]["DataRoute"]
scaninfo = dataroute["ScanInformation"]
nsteps = int(scaninfo["MeasurementPoints"])
if nsteps==1:
rawdata = np.array(dataroute["Datum"].split(","))
elif nsteps>1:
rawdata = np.array([d.split(",") for d in dataroute["Datum"]])

rawdata = rawdata.astype(float).T
rdv = dataroute["DataViews"]["RawDataView"]
for view in rdv:
viewtype = view["@xsi:type"]
vstart = int(view["@Start"])
vlen = int(view["@Length"])
if viewtype=="FixedRawDataView":
vname = view["@LogicName"]
self.data[vname].append(rawdata[vstart:(vstart+vlen)])
elif viewtype=="RecordedRawDataView":
vname = view["Recording"]["@LogicName"]
self.data[vname].append(rawdata[vstart:(vstart+vlen)])

self.data["ScanName"].append(scaninfo["@ScanName"])
self.data["TimePerStep"].append(scaninfo["TimePerStep"])
self.data["TimePerStepEffective"].append(scaninfo["TimePerStepEffective"])
self.data["ScanMode"].append(scaninfo["ScanMode"])

scanaxes = scaninfo["ScanAxes"]["ScanAxisInfo"]
if not isinstance(scanaxes, list):
scanaxes = [scanaxes]
for axis in scanaxes:
aname = axis["@AxisName"]
aunit = axis["Unit"]["@Base"]
aref = float(axis["Reference"])
astart = float(axis["Start"]) + aref
astop = float(axis["Stop"]) + aref
astep = float(axis["Increment"])
nint = int(round(abs(astop-astart)/astep))
adata = {} # not originally part of Carsten's code
adata["Value"] = np.linspace(astart, astop, nint+1)
adata["Unit"] = aunit.lower()
self.data[aname].append(adata)

drives = data["RawData"]["FixedInformation"]["Drives"]["InfoData"]
for axis in drives:
aname = axis["@LogicName"]
apos = float(axis["Position"]["@Value"])
aunit = axis["Position"]["@Unit"]
adata = {} # not originally part of Carsten's code
adata["Value"] = apos
adata["Unit"] = aunit.lower()
self.motors[aname].append(adata)

# (block starts) not originally part of Carsten's code
try:
self.mounted_optics_info = (
data["RawData"]["FixedInformation"]["Instrument"]
["PrimaryTracks"]["TrackInfoData"]["MountedOptics"]["InfoData"]
)
except (KeyError, TypeError):
self.mounted_optics_info = []
# (block end) not originally part of Carsten's code

for key in self.data:
self.data[key] = np.array(self.data[key]).squeeze()
if not self.data[key].shape:
self.data[key] = self.data[key].item()
for key in self.motors:
self.motors[key] = np.array(self.motors[key]).squeeze()
if not self.motors[key].shape:
self.motors[key] = self.motors[key].item()
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm guessing this part is from Carsten so I only skimmed through it. Let me know if you want me to look closer at it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Correct, and I have tried to keep most of the code from Carsten as it is. So you can skim though it.

Comment on lines +434 to +437
Dict[str, Any]: Each dict item contains a list with numerical value
(numpy.ndarray) at index 0 and unit (str) at index 1. If quantity
is not available, the dict item will default to []. If units are not
available for two_theta or axis positions, they will default to 'deg'.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is fine but just out of curiosity, why do you not just return the pint.Quantity directly?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, we could do that but I did not want to introduce any nomad functionality (ureg in this case) in IKZ.py.

Comment on lines +255 to +268
def set_quantity(value: Any=None, unit: str=None) -> Any:
'''
Sets the quantity based on whether value or/and unit are available.

Args:
value (Any): Value of the quantity.
unit (str): Unit of the quantity.

Returns:
Any: Processed quantity with datatype depending on the value.
'''
if not unit:
return value
return value * ureg(unit)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is repeated from above. I would say that we either extract this function out or like I commented in the IKZ.py we could move the unit addition in there.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, indeed. I was thinking about moving this function to nomad_measurements/utils.py after merging this commit. Or we could also put this function elsewhere.

Copy link
Collaborator

@hampusnasstrom hampusnasstrom left a comment

Choose a reason for hiding this comment

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

Looks good Sarthak! Would be okay like this but I'm wondering if we could deal with the units a bit better now that we anyways decided to modify the IKZ.py file. What do you think? We can also merge this for now and do that later.

@hampusnasstrom hampusnasstrom linked an issue Dec 8, 2023 that may be closed by this pull request
6 tasks
@ka-sarthak
Copy link
Collaborator Author

Thanks Hampus! It is indeed an important point about the units and we can make it better in next commits. For now, let's go ahead with merging this.

@ka-sarthak ka-sarthak merged commit f191c00 into main Dec 8, 2023
@hampusnasstrom hampusnasstrom deleted the 26-reader-for-brml-brucker-files branch December 8, 2023 14:51
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.

Reader for .brml Brucker files XRD plugin
2 participants