-
Notifications
You must be signed in to change notification settings - Fork 1
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
Conversation
4b4238f
to
3f1f121
Compare
f865196
to
5dab071
Compare
There was a problem hiding this 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. ' |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
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() |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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'. |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
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. |
No description provided.