Skip to content

Commit

Permalink
Modified XRD Reading and Writing Process (#28)
Browse files Browse the repository at this point in the history
* Modified XRD Reading and Writing Process

Added method for getting read and write functions

Added empty NeXus read and write functions

* Fixed Typo

* updating nexus reader and wrote.

* Populate nexus section.

* Including nexus reader.

* update

* update.

* fixing plot.

* fixing plot.

* Changed to Call Read and Write Every Normalize

Added utils function for merging sections

Changed to call file read and write every time

Added merging of read data into self

Linting

* Commented Out NeXus Reader Integration

* Changed to Not Warn For Empty Update SubSections

* Linting

* Added Quotes on Type Hinted BoundLogger

* Removed read_xrd function

Added .brml to get_read_write_functions method

* Removed call to missing read or write  function

---------

Co-authored-by: Rubel <[email protected]>
  • Loading branch information
hampusnasstrom and RubelMozumder authored Dec 8, 2023
1 parent f191c00 commit 8326872
Show file tree
Hide file tree
Showing 4 changed files with 343 additions and 39 deletions.
72 changes: 69 additions & 3 deletions src/nomad_measurements/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,35 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
from typing import (
TYPE_CHECKING,
)
if TYPE_CHECKING:
from nomad.datamodel.data import (
ArchiveSection,
)
from nomad.datamodel.datamodel import (
EntryArchive,
)
from structlog.stdlib import (
BoundLogger,
)


def get_reference(upload_id, entry_id):
def get_reference(upload_id: str, entry_id: str) -> str:
return f'../uploads/{upload_id}/archive/{entry_id}#data'


def get_entry_id_from_file_name(file_name, archive):
def get_entry_id_from_file_name(file_name: str, archive: 'EntryArchive') -> str:
from nomad.utils import hash
return hash(archive.metadata.upload_id, file_name)


def create_archive(entity, archive, file_name) -> str:
def create_archive(
entity: 'ArchiveSection',
archive: 'EntryArchive',
file_name: str,
) -> str:
import json
from nomad.datamodel.context import ClientContext
if isinstance(archive.m_context, ClientContext):
Expand All @@ -40,3 +57,52 @@ def create_archive(entity, archive, file_name) -> str:
archive.metadata.upload_id,
get_entry_id_from_file_name(file_name, archive)
)


def merge_sections(
section: 'ArchiveSection',
update: 'ArchiveSection',
logger: 'BoundLogger'=None,
) -> None:
if update is None:
return
if section is None:
section = update.m_copy()
return
if not isinstance(section, type(update)):
raise TypeError(
'Cannot merge sections of different types: '
f'{type(section)} and {type(update)}'
)
for name, quantity in update.m_def.all_quantities.items():
if not update.m_is_set(quantity):
continue
if not section.m_is_set(quantity):
section.m_set(quantity, update.m_get(quantity))
elif (
quantity.is_scalar and section.m_get(quantity) != update.m_get(quantity)
or quantity.repeats and (section.m_get(quantity) != update.m_get(quantity)).any()
):
warning = f'Merging sections with different values for quantity "{name}".'
if logger:
logger.warning(warning)
else:
print(warning)
for name, sub_section_def in update.m_def.all_sub_sections.items():
count = section.m_sub_section_count(sub_section_def)
if count == 0:
for update_sub_section in update.m_get_sub_sections(sub_section_def):
section.m_add_sub_section(sub_section_def, update_sub_section)
elif count == update.m_sub_section_count(sub_section_def):
for i in range(count):
merge_sections(
section.m_get_sub_section(sub_section_def, i),
update.m_get_sub_section(sub_section_def, i),
logger,
)
elif update.m_sub_section_count(sub_section_def) > 0:
warning = f'Merging sections with different number of "{name}" sub sections.'
if logger:
logger.warning(warning)
else:
print(warning)
46 changes: 25 additions & 21 deletions src/nomad_measurements/xrd/readers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,23 @@
from typing import (
Dict,
Any,
TYPE_CHECKING
)
import numpy as np
from structlog.stdlib import (
BoundLogger,
)
from nomad.units import ureg
# from pynxtools.dataconverter.convert import transfer_data_into_template
from nomad_measurements.xrd.IKZ import RASXfile, BRMLfile

if TYPE_CHECKING:
from structlog.stdlib import (
BoundLogger,
)


def transfer_data_into_template(**kwargs):
raise NotImplementedError

def read_panalytical_xrdml(file_path: str, logger: BoundLogger=None) -> Dict[str, Any]:
def read_panalytical_xrdml(file_path: str, logger: 'BoundLogger'=None) -> Dict[str, Any]:
'''
Function for reading the X-ray diffraction data in a Panalytical `.xrdml` file.
Expand Down Expand Up @@ -160,7 +167,7 @@ def find_string(path):
}


def read_rigaku_rasx(file_path: str, logger: BoundLogger=None) -> Dict[str, Any]:
def read_rigaku_rasx(file_path: str, logger: 'BoundLogger'=None) -> Dict[str, Any]:
'''
Reads .rasx files from Rigaku instruments
- reader is based on IKZ module
Expand Down Expand Up @@ -235,7 +242,7 @@ def set_quantity(value: Any=None, unit: str=None) -> Any:

return output

def read_bruker_brml(file_path: str, logger: BoundLogger=None) -> Dict[str, Any]:
def read_bruker_brml(file_path: str, logger: 'BoundLogger'=None) -> Dict[str, Any]:
'''
Reads .brml files from Bruker instruments
- reader is based on IKZ module
Expand Down Expand Up @@ -291,24 +298,21 @@ def set_quantity(value: Any=None, unit: str=None) -> Any:

return output


def read_xrd(file_path: str, logger: BoundLogger) -> Dict[str, Any]:
def read_nexus_xrd(file_path: str, logger: 'BoundLogger'=None) -> Dict[str, Any]:
'''
Function for reading an XRD file.
Function for reading the X-ray diffraction data in a Nexus file.
Args:
file_path (str): The path of the file to be read.
logger (BoundLogger): A structlog logger.
file_path (str): The path to the X-ray diffraction data file.
logger (BoundLogger, optional): A structlog logger. Defaults to None.
Returns:
dict: The parsed and converted data in a common dictionary format.
Dict[str, Any]: The X-ray diffraction data in a Python dictionary.
'''
file_path = os.path.abspath(file_path)

if file_path.endswith('.xrdml'):
return read_panalytical_xrdml(file_path, logger)
if file_path.endswith('.rasx'):
return read_rigaku_rasx(file_path, logger)
if file_path.endswith('.brml'):
return read_bruker_brml(file_path,logger)
raise ValueError(f'Unsupported file format: {file_path.split(".")[-1]}')
nxdl_name = 'NXxrd_pan'
xrd_template = transfer_data_into_template(
nxdl_name=nxdl_name,
input_file=file_path,
reader='xrd',
)
return xrd_template
Loading

0 comments on commit 8326872

Please sign in to comment.