Compare commits
5 Commits
41ff025098
...
207d166227
| Author | SHA256 | Date | |
|---|---|---|---|
| 207d166227 | |||
| 74b8c9cfae | |||
| 1b1834d4e6 | |||
| dfd3c07d2f | |||
| d094a60725 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,8 +1,10 @@
|
||||
# ignores logs of h5tojson, jsontoh5
|
||||
*.log
|
||||
|
||||
# ignores output json of main.py
|
||||
# ignores any output of main.py
|
||||
output/*.json
|
||||
output/*.h5
|
||||
output/*.nxs
|
||||
|
||||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
|
||||
@@ -175,7 +175,8 @@ class Substrate(Material):
|
||||
self.miscut_angle_unit = self.extra["Miscut Angle"]["unit"]
|
||||
self.miscut_direction = self.extra["Miscut Direction"]["value"]
|
||||
# Not present (yet) on eLabFTW for Substrates:
|
||||
self.thickness = None #self.extra["Thickness"]["value"]
|
||||
self.thickness = "" #self.extra["Thickness"]["value"]
|
||||
self.thickness_unit = "μm" #self.extra["Thickness"]["unit"]
|
||||
self.surface_treatment = self.extra["Surface treatment"]["value"]
|
||||
self.manufacturer = self.extra["Supplier"]["value"]
|
||||
self.batch_id = self.extra["Batch ID"]["value"]
|
||||
@@ -194,7 +195,7 @@ class Target(Material):
|
||||
except KeyError as k:
|
||||
raise KeyError(f"The provided dictionary lacks a \"{k}\" key - which is specific for PLD targets. Check the {self.name} target entry on eLabFTW and make sure you used the correct Resource template.")
|
||||
# Non-required attributes:
|
||||
self.description = material_data.get("body") or None
|
||||
self.description = material_data.get("body") or ""
|
||||
|
||||
|
||||
|
||||
|
||||
181
src/main.py
181
src/main.py
@@ -135,9 +135,15 @@ def make_nexus_schema_dictionary(substrate_object, layers):
|
||||
"name": substrate_object.name,
|
||||
"chemical_formula" : substrate_object.get_compound_formula(apikey),
|
||||
"orientation" : substrate_object.orientation,
|
||||
"miscut_angle" : substrate_object.miscut_angle,
|
||||
"miscut_angle" : {
|
||||
"value": substrate_object.miscut_angle,
|
||||
"units": substrate_object.miscut_angle_unit
|
||||
},
|
||||
"miscut_direction" : substrate_object.miscut_direction,
|
||||
"thickness" : substrate_object.thickness,
|
||||
"thickness" : {
|
||||
"value": substrate_object.thickness,
|
||||
"units": substrate_object.thickness_unit,
|
||||
},
|
||||
"dimensions" : substrate_object.dimensions,
|
||||
"surface_treatment" : substrate_object.surface_treatment,
|
||||
"manufacturer" : substrate_object.manufacturer,
|
||||
@@ -157,11 +163,14 @@ def make_nexus_schema_dictionary(substrate_object, layers):
|
||||
"description" : target_object.description,
|
||||
"shape" : target_object.shape,
|
||||
"dimensions" : target_object.dimensions,
|
||||
"thickness" : target_object.thickness,
|
||||
"thickness" : {
|
||||
"value": target_object.thickness,
|
||||
"units": target_object.thickness_unit,
|
||||
},
|
||||
"solid_form" : target_object.solid_form,
|
||||
"manufacturer" : target_object.manufacturer,
|
||||
"batch_id" : target_object.name,
|
||||
# TO-DO: currently not available:
|
||||
# "batch_id" : target_object.batch_id,
|
||||
}
|
||||
multilayer[name] = {
|
||||
"target": target_dict,
|
||||
@@ -169,17 +178,44 @@ def make_nexus_schema_dictionary(substrate_object, layers):
|
||||
"operator": layer.operator,
|
||||
"description": layer.description,
|
||||
"number_of_pulses": layer.number_of_pulses,
|
||||
"deposition_time": layer.deposition_time,
|
||||
"temperature": layer.temperature,
|
||||
"deposition_time": {
|
||||
"value": layer.deposition_time,
|
||||
"units": layer.deposition_time_unit,
|
||||
},
|
||||
"temperature": {
|
||||
"value": layer.temperature,
|
||||
"units": layer.temperature_unit,
|
||||
},
|
||||
"heating_method": layer.heating_method,
|
||||
"layer_thickness": layer.layer_thickness,
|
||||
"layer_thickness": {
|
||||
"value": layer.layer_thickness,
|
||||
"units": layer.layer_thickness_unit,
|
||||
},
|
||||
"buffer_gas": layer.buffer_gas,
|
||||
"process_pressure": layer.process_pressure,
|
||||
"heater_target_distance": layer.heater_target_distance,
|
||||
"repetition_rate": layer.repetition_rate,
|
||||
"laser_fluence": layer.laser_fluence,
|
||||
"laser_spot_area": layer.laser_spot_area,
|
||||
"laser_energy": layer.laser_energy,
|
||||
"process_pressure": {
|
||||
"value": layer.process_pressure,
|
||||
"units": layer.process_pressure_unit,
|
||||
},
|
||||
"heater_target_distance": {
|
||||
"value": layer.heater_target_distance,
|
||||
"units": layer.heater_target_distance_unit,
|
||||
},
|
||||
"repetition_rate": {
|
||||
"value": layer.repetition_rate,
|
||||
"units": layer.repetition_rate_unit,
|
||||
},
|
||||
"laser_fluence": {
|
||||
"value": layer.laser_fluence,
|
||||
"units": layer.laser_fluence_unit,
|
||||
},
|
||||
"laser_spot_area": {
|
||||
"value": layer.laser_spot_area,
|
||||
"units": layer.laser_spot_area_unit,
|
||||
},
|
||||
"laser_energy": {
|
||||
"value": layer.laser_energy,
|
||||
"units": layer.laser_energy_unit,
|
||||
},
|
||||
"laser_rastering": {
|
||||
"geometry": layer.laser_rastering_geometry,
|
||||
"positions": layer.laser_rastering_positions,
|
||||
@@ -187,15 +223,33 @@ def make_nexus_schema_dictionary(substrate_object, layers):
|
||||
},
|
||||
"pre_annealing": {
|
||||
"ambient_gas": layer.pre_annealing_ambient_gas,
|
||||
"pressure": layer.pre_annealing_pressure,
|
||||
"temperature": layer.pre_annealing_temperature,
|
||||
"duration": layer.pre_annealing_duration,
|
||||
"pressure": {
|
||||
"value": layer.pre_annealing_pressure,
|
||||
"units": layer.pre_annealing_pressure_unit,
|
||||
},
|
||||
"temperature": {
|
||||
"value": layer.pre_annealing_temperature,
|
||||
"units": layer.pre_annealing_temperature_unit,
|
||||
},
|
||||
"duration": {
|
||||
"value": layer.pre_annealing_duration,
|
||||
"units": layer.pre_annealing_duration_unit,
|
||||
},
|
||||
},
|
||||
"post_annealing": {
|
||||
"ambient_gas": layer.post_annealing_ambient_gas,
|
||||
"pressure": layer.post_annealing_pressure,
|
||||
"temperature": layer.post_annealing_temperature,
|
||||
"duration": layer.post_annealing_duration,
|
||||
"pressure": {
|
||||
"value": layer.post_annealing_pressure,
|
||||
"units": layer.post_annealing_pressure_unit,
|
||||
},
|
||||
"temperature": {
|
||||
"value": layer.post_annealing_temperature,
|
||||
"units": layer.post_annealing_temperature_unit,
|
||||
},
|
||||
"duration": {
|
||||
"value": layer.post_annealing_duration,
|
||||
"units": layer.post_annealing_duration_unit,
|
||||
},
|
||||
},
|
||||
}
|
||||
return pld_fabrication
|
||||
@@ -209,11 +263,90 @@ def build_nexus_file(pld_fabrication, output_path):
|
||||
# Sample section
|
||||
nx_sample = nx_pld_entry.create_group("sample")
|
||||
nx_sample.attrs["NX_class"] = "NXsample"
|
||||
sample_dict = pld_fabrication["sample"]
|
||||
|
||||
# Substrate section
|
||||
nx_substrate = nx_pld_entry.create_group("substrate")
|
||||
# Substrate sub-section
|
||||
nx_substrate = nx_sample.create_group("substrate")
|
||||
nx_substrate.attrs["NX_class"] = "NXsubentry"
|
||||
pass
|
||||
substrate_dict = sample_dict["substrate"]
|
||||
try:
|
||||
# Substrate fields (datasets)
|
||||
nx_substrate.create_dataset("name", data=substrate_dict["name"])
|
||||
nx_substrate.create_dataset("chemical_formula", data=substrate_dict["chemical_formula"])
|
||||
nx_substrate.create_dataset("orientation", data=substrate_dict["orientation"])
|
||||
nx_substrate.create_dataset("miscut_angle", data=substrate_dict["miscut_angle"]["value"]) # float
|
||||
nx_substrate["miscut_angle"].attrs["units"] = substrate_dict["miscut_angle"]["units"]
|
||||
nx_substrate.create_dataset("miscut_direction", data=substrate_dict["miscut_direction"])
|
||||
nx_substrate.create_dataset("thickness", data=substrate_dict["thickness"]["value"]) # float/int
|
||||
nx_substrate["thickness"].attrs["units"] = substrate_dict["thickness"]["units"]
|
||||
nx_substrate.create_dataset("dimensions", data=substrate_dict["dimensions"])
|
||||
nx_substrate.create_dataset("surface_treatment", data=substrate_dict["surface_treatment"])
|
||||
nx_substrate.create_dataset("manufacturer", data=substrate_dict["manufacturer"])
|
||||
nx_substrate.create_dataset("batch_id", data=substrate_dict["batch_id"])
|
||||
except TypeError as te:
|
||||
# sooner or later I'll handle this too - not today tho
|
||||
raise TypeError(te)
|
||||
|
||||
# Multilayer sub-section
|
||||
nx_multilayer = nx_sample.create_group("multilayer")
|
||||
nx_multilayer.attrs["NX_class"] = "NXsubentry"
|
||||
multilayer_dict = sample_dict["multilayer"]
|
||||
# Repeat FOR EACH LAYER:
|
||||
for layer in multilayer_dict:
|
||||
nx_layer = nx_multilayer.create_group(layer)
|
||||
nx_layer.attrs["NX_class"] = "NXsubentry"
|
||||
layer_dict = multilayer_dict[layer]
|
||||
# Sub-groups of a layer
|
||||
nx_target = nx_layer.create_group("target")
|
||||
nx_target.attrs["NX_class"] = "NXsample"
|
||||
target_dict = layer_dict["target"]
|
||||
nx_laser_rastering = nx_layer.create_group("laser_rastering")
|
||||
nx_pre_annealing = nx_layer.create_group("pre_annealing")
|
||||
nx_post_annealing = nx_layer.create_group("post_annealing")
|
||||
nx_laser_rastering.attrs["NX_class"] = "NXprocess"
|
||||
nx_pre_annealing.attrs["NX_class"] = "NXprocess"
|
||||
nx_post_annealing.attrs["NX_class"] = "NXprocess"
|
||||
|
||||
try:
|
||||
nx_target.create_dataset("name", data=target_dict["name"])
|
||||
nx_target.create_dataset("chemical_formula", data=target_dict["chemical_formula"])
|
||||
nx_target.create_dataset("description", data=target_dict["description"])
|
||||
nx_target.create_dataset("shape", data=target_dict["shape"])
|
||||
nx_target.create_dataset("dimensions", data=target_dict["dimensions"])
|
||||
nx_target.create_dataset("thickness", data=target_dict["thickness"]["value"]) # float/int
|
||||
nx_target["thickness"].attrs["units"] = target_dict["thickness"]["units"]
|
||||
nx_target.create_dataset("solid_form", data=target_dict["solid_form"])
|
||||
nx_target.create_dataset("manufacturer", data=target_dict["manufacturer"])
|
||||
nx_target.create_dataset("batch_id", data=target_dict["batch_id"])
|
||||
except TypeError as te:
|
||||
raise TypeError(te)
|
||||
try:
|
||||
nx_layer.create_dataset("start_time", data = layer_dict["start_time"])
|
||||
nx_layer.create_dataset("operator", data = layer_dict["operator"])
|
||||
nx_layer.create_dataset("number_of_pulses", data = layer_dict["number_of_pulses"])
|
||||
nx_layer.create_dataset("deposition_time", data = layer_dict["deposition_time"]["value"])
|
||||
nx_layer["deposition_time"].attrs["units"] = layer_dict["deposition_time"]["units"]
|
||||
nx_layer.create_dataset("repetition_rate", data = layer_dict["repetition_rate"]["value"])
|
||||
nx_layer["repetition_rate"].attrs["units"] = layer_dict["repetition_rate"]["units"]
|
||||
nx_layer.create_dataset("temperature", data = layer_dict["temperature"]["value"])
|
||||
nx_layer["temperature"].attrs["units"] = layer_dict["temperature"]["units"]
|
||||
nx_layer.create_dataset("heating_method", data = layer_dict["heating_method"])
|
||||
nx_layer.create_dataset("layer_thickness", data = layer_dict["layer_thickness"]["value"])
|
||||
nx_layer["layer_thickness"].attrs["units"] = layer_dict["layer_thickness"]["units"]
|
||||
nx_layer.create_dataset("buffer_gas", data = layer_dict["buffer_gas"])
|
||||
nx_layer.create_dataset("process_pressure", data = layer_dict["process_pressure"]["value"])
|
||||
nx_layer["process_pressure"].attrs["units"] = layer_dict["process_pressure"]["units"]
|
||||
nx_layer.create_dataset("heater_target_distance", data = layer_dict["heater_target_distance"]["value"])
|
||||
nx_layer["heater_target_distance"].attrs["units"] = layer_dict["heater_target_distance"]["units"]
|
||||
nx_layer.create_dataset("laser_fluence", data = layer_dict["laser_fluence"]["value"])
|
||||
nx_layer["laser_fluence"].attrs["units"] = layer_dict["laser_fluence"]["units"]
|
||||
nx_layer.create_dataset("laser_spot_area", data = layer_dict["laser_spot_area"]["value"])
|
||||
nx_layer["laser_spot_area"].attrs["units"] = layer_dict["laser_spot_area"]["units"]
|
||||
nx_layer.create_dataset("laser_energy", data = layer_dict["laser_energy"]["value"])
|
||||
nx_layer["laser_energy"].attrs["units"] = layer_dict["laser_energy"]["units"]
|
||||
except TypeError as te:
|
||||
raise TypeError(te)
|
||||
return
|
||||
|
||||
if __name__=="__main__":
|
||||
# TO-DO: place the API base URL somewhere else.
|
||||
@@ -222,9 +355,11 @@ if __name__=="__main__":
|
||||
elabid = input("Enter elabid of your starting sample [default= 1111]: ") or 1111
|
||||
data = APIHandler(apikey).get_entry_from_elabid(elabid)
|
||||
sample = Entrypoint(data)
|
||||
sample_name = sample.name.strip().replace(" ","_")
|
||||
substrate_object = chain_entrypoint_to_batch(sample) # Substrate-class object
|
||||
layers = chain_entrypoint_to_layers(sample) # list of Layer-class objects
|
||||
result = make_nexus_schema_dictionary(substrate_object, layers)
|
||||
# print(make_nexus_schema_dictionary(substrate_object, layers)) # debug
|
||||
with open (f"output/sample-{elabid}.json", "w") as f:
|
||||
with open (f"output/sample-{sample_name}.json", "w") as f:
|
||||
json.dump(result, f, indent=3)
|
||||
build_nexus_file(result, output_path=f"output/sample-{sample_name}-nexus.h5")
|
||||
|
||||
Reference in New Issue
Block a user