metadata_related.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import re
  2. import pandas as pd
  3. from view.python_core.get_internal_files import get_metadata_definition
  4. from view.python_core.stimuli import PulsedStimuliiHandler
  5. def parse_p1_metadata_from_measurement_list_row(row):
  6. """
  7. Parse metadata from the row of a measurement list into a pandas Series object
  8. :param pandas.Series row: row of a measurement list
  9. :rtype: pandas.Series
  10. """
  11. # get metadata names and default values
  12. meta_def = MetadataDefinition()
  13. p1_metadata = meta_def.get_default_row()
  14. extra_metadata = {}
  15. list_column_p1_metadata_mapping = meta_def.get_list_column_p1_metadata_mapping()
  16. for k, v in row.items():
  17. if k in list_column_p1_metadata_mapping:
  18. p1_metadata_name = list_column_p1_metadata_mapping[k]
  19. if not pd.isnull(p1_metadata_name):
  20. p1_metadata[p1_metadata_name] = v
  21. else:
  22. extra_metadata[k] = v
  23. # stimulus information is stored in this object
  24. p1_metadata["pulsed_stimuli_handler"] = PulsedStimuliiHandler.create_from_row(row)
  25. if "agetxt" in p1_metadata:
  26. age = re.split('-|;', str(p1_metadata["agetxt"]))
  27. # age can be one number, or a range separated by ; or -
  28. # now age is ['5'] or ['3','7']
  29. p1_metadata["age"] = age[0] # the youngest age in the range, or the only age
  30. p1_metadata["agemax"] = age[-1] # the second number or the only number
  31. # calculate stimulus times in seconds
  32. p1_metadata["frequency"] = 1000.0 / p1_metadata["trial_ticks"]
  33. try:
  34. temp = p1_metadata["pixelsizex"] + 1
  35. except TypeError:
  36. print(f"Pixelsize has been converted to a date: {p1_metadata['pixelsizex']} "
  37. f"by excel - please correct. I assume 2.4 for now")
  38. p1_metadata["pixelsizex"], p1_metadata["pixelsizey"] = 2.4, 2.4
  39. except KeyError: # pixelsizex is not specified
  40. pass
  41. return p1_metadata, extra_metadata
  42. class MetadataDefinition(object):
  43. def __init__(self):
  44. self._def_df = get_metadata_definition()
  45. @property
  46. def def_df(self):
  47. return self._def_df.copy()
  48. def get_list_column_p1_metadata_mapping(self):
  49. temp = self._def_df.loc[:, "p1"]
  50. return temp.to_dict()
  51. def get_default_row(self):
  52. """
  53. returns a pandas Series representing a row of a measurement, with all default values
  54. :return: pandas Series
  55. """
  56. default_row = self._def_df["Default values"]
  57. return default_row.apply(lambda x: pd.to_numeric(x, errors="ignore"))
  58. def is_value_default(self, metadata_name, value):
  59. def_df2use = self._def_df
  60. assert metadata_name in def_df2use.index.values, f"Unknown metadata name {metadata_name}"
  61. default_value = def_df2use.loc[metadata_name, "Default values"]
  62. return value == pd.to_numeric(default_value, errors="ignore")