imap-processing 0.7.0__py3-none-any.whl → 0.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of imap-processing might be problematic. Click here for more details.

Files changed (172) hide show
  1. imap_processing/__init__.py +1 -1
  2. imap_processing/_version.py +2 -2
  3. imap_processing/ccsds/excel_to_xtce.py +36 -2
  4. imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +1 -1
  5. imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +145 -30
  6. imap_processing/cdf/config/imap_glows_l1b_variable_attrs.yaml +36 -36
  7. imap_processing/cdf/config/imap_hi_variable_attrs.yaml +136 -9
  8. imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +14 -0
  9. imap_processing/cdf/config/imap_hit_l1a_variable_attrs.yaml +63 -1
  10. imap_processing/cdf/config/imap_hit_l1b_variable_attrs.yaml +9 -0
  11. imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +14 -7
  12. imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +577 -235
  13. imap_processing/cdf/config/imap_idex_l1b_variable_attrs.yaml +326 -0
  14. imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +33 -23
  15. imap_processing/cdf/config/imap_mag_l1_variable_attrs.yaml +24 -28
  16. imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +1 -0
  17. imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +137 -79
  18. imap_processing/cdf/config/imap_variable_schema.yaml +13 -0
  19. imap_processing/cdf/imap_cdf_manager.py +31 -27
  20. imap_processing/cdf/utils.py +3 -5
  21. imap_processing/cli.py +25 -14
  22. imap_processing/codice/codice_l1a.py +153 -63
  23. imap_processing/codice/constants.py +10 -10
  24. imap_processing/codice/decompress.py +10 -11
  25. imap_processing/codice/utils.py +1 -0
  26. imap_processing/glows/l1a/glows_l1a.py +1 -2
  27. imap_processing/glows/l1b/glows_l1b.py +3 -3
  28. imap_processing/glows/l1b/glows_l1b_data.py +59 -37
  29. imap_processing/glows/l2/glows_l2_data.py +123 -0
  30. imap_processing/hi/l1a/hi_l1a.py +4 -4
  31. imap_processing/hi/l1a/histogram.py +107 -109
  32. imap_processing/hi/l1a/science_direct_event.py +92 -225
  33. imap_processing/hi/l1b/hi_l1b.py +85 -11
  34. imap_processing/hi/l1c/hi_l1c.py +23 -1
  35. imap_processing/hi/packet_definitions/TLM_HI_COMBINED_SCI.xml +3994 -0
  36. imap_processing/hi/utils.py +1 -1
  37. imap_processing/hit/hit_utils.py +221 -0
  38. imap_processing/hit/l0/constants.py +118 -0
  39. imap_processing/hit/l0/decom_hit.py +100 -156
  40. imap_processing/hit/l1a/hit_l1a.py +170 -184
  41. imap_processing/hit/l1b/hit_l1b.py +33 -153
  42. imap_processing/ialirt/l0/process_codicelo.py +153 -0
  43. imap_processing/ialirt/l0/process_hit.py +5 -5
  44. imap_processing/ialirt/packet_definitions/ialirt_codicelo.xml +281 -0
  45. imap_processing/ialirt/process_ephemeris.py +212 -0
  46. imap_processing/idex/idex_l1a.py +65 -84
  47. imap_processing/idex/idex_l1b.py +192 -0
  48. imap_processing/idex/idex_variable_unpacking_and_eu_conversion.csv +33 -0
  49. imap_processing/idex/packet_definitions/idex_packet_definition.xml +97 -595
  50. imap_processing/lo/l0/decompression_tables/decompression_tables.py +17 -1
  51. imap_processing/lo/l0/lo_science.py +45 -13
  52. imap_processing/lo/l1a/lo_l1a.py +76 -8
  53. imap_processing/lo/packet_definitions/lo_xtce.xml +8344 -1849
  54. imap_processing/mag/l0/decom_mag.py +4 -3
  55. imap_processing/mag/l1a/mag_l1a.py +12 -13
  56. imap_processing/mag/l1a/mag_l1a_data.py +1 -2
  57. imap_processing/mag/l1b/mag_l1b.py +90 -7
  58. imap_processing/spice/geometry.py +156 -16
  59. imap_processing/spice/time.py +144 -2
  60. imap_processing/swapi/l1/swapi_l1.py +4 -4
  61. imap_processing/swapi/l2/swapi_l2.py +1 -1
  62. imap_processing/swapi/packet_definitions/swapi_packet_definition.xml +1535 -446
  63. imap_processing/swe/l1b/swe_l1b_science.py +8 -8
  64. imap_processing/swe/l2/swe_l2.py +134 -17
  65. imap_processing/tests/ccsds/test_data/expected_output.xml +2 -1
  66. imap_processing/tests/ccsds/test_excel_to_xtce.py +4 -4
  67. imap_processing/tests/cdf/test_imap_cdf_manager.py +0 -10
  68. imap_processing/tests/codice/conftest.py +1 -17
  69. imap_processing/tests/codice/data/imap_codice_l0_raw_20241110_v001.pkts +0 -0
  70. imap_processing/tests/codice/test_codice_l0.py +8 -2
  71. imap_processing/tests/codice/test_codice_l1a.py +127 -107
  72. imap_processing/tests/codice/test_codice_l1b.py +1 -0
  73. imap_processing/tests/codice/test_decompress.py +7 -7
  74. imap_processing/tests/conftest.py +100 -58
  75. imap_processing/tests/glows/conftest.py +6 -0
  76. imap_processing/tests/glows/test_glows_l1b.py +9 -9
  77. imap_processing/tests/glows/test_glows_l1b_data.py +9 -9
  78. imap_processing/tests/hi/test_data/l0/H90_NHK_20241104.bin +0 -0
  79. imap_processing/tests/hi/test_data/l0/H90_sci_cnt_20241104.bin +0 -0
  80. imap_processing/tests/hi/test_data/l0/H90_sci_de_20241104.bin +0 -0
  81. imap_processing/tests/hi/test_data/l1a/imap_hi_l1a_45sensor-de_20250415_v000.cdf +0 -0
  82. imap_processing/tests/hi/test_hi_l1b.py +73 -3
  83. imap_processing/tests/hi/test_hi_l1c.py +10 -2
  84. imap_processing/tests/hi/test_l1a.py +31 -58
  85. imap_processing/tests/hi/test_science_direct_event.py +58 -0
  86. imap_processing/tests/hi/test_utils.py +4 -3
  87. imap_processing/tests/hit/test_data/sci_sample1.ccsds +0 -0
  88. imap_processing/tests/hit/{test_hit_decom.py → test_decom_hit.py} +95 -36
  89. imap_processing/tests/hit/test_hit_l1a.py +299 -179
  90. imap_processing/tests/hit/test_hit_l1b.py +231 -24
  91. imap_processing/tests/hit/test_hit_utils.py +218 -0
  92. imap_processing/tests/hit/validation_data/hskp_sample_eu.csv +89 -0
  93. imap_processing/tests/hit/validation_data/sci_sample_raw1.csv +29 -0
  94. imap_processing/tests/ialirt/test_data/l0/apid01152.tlm +0 -0
  95. imap_processing/tests/ialirt/test_data/l0/imap_codice_l1a_lo-ialirt_20241110193700_v0.0.0.cdf +0 -0
  96. imap_processing/tests/ialirt/unit/test_process_codicelo.py +106 -0
  97. imap_processing/tests/ialirt/unit/test_process_ephemeris.py +109 -0
  98. imap_processing/tests/ialirt/unit/test_process_hit.py +9 -6
  99. imap_processing/tests/idex/conftest.py +2 -2
  100. imap_processing/tests/idex/imap_idex_l0_raw_20231214_v001.pkts +0 -0
  101. imap_processing/tests/idex/impact_14_tof_high_data.txt +4444 -4444
  102. imap_processing/tests/idex/test_idex_l0.py +4 -4
  103. imap_processing/tests/idex/test_idex_l1a.py +8 -2
  104. imap_processing/tests/idex/test_idex_l1b.py +126 -0
  105. imap_processing/tests/lo/test_lo_l1a.py +7 -16
  106. imap_processing/tests/lo/test_lo_science.py +69 -5
  107. imap_processing/tests/lo/test_pkts/imap_lo_l0_raw_20240803_v002.pkts +0 -0
  108. imap_processing/tests/lo/validation_data/Instrument_FM1_T104_R129_20240803_ILO_SCI_DE_dec_DN_with_fills.csv +1999 -0
  109. imap_processing/tests/mag/imap_mag_l1a_norm-magi_20251017_v001.cdf +0 -0
  110. imap_processing/tests/mag/test_mag_l1b.py +97 -7
  111. imap_processing/tests/spice/test_data/imap_ena_sim_metakernel.template +3 -1
  112. imap_processing/tests/spice/test_geometry.py +115 -9
  113. imap_processing/tests/spice/test_time.py +135 -6
  114. imap_processing/tests/swapi/test_swapi_decom.py +75 -69
  115. imap_processing/tests/swapi/test_swapi_l1.py +4 -4
  116. imap_processing/tests/swe/conftest.py +33 -0
  117. imap_processing/tests/swe/l1_validation/swe_l0_unpacked-data_20240510_v001_VALIDATION_L1B_v3.dat +4332 -0
  118. imap_processing/tests/swe/test_swe_l1b.py +29 -8
  119. imap_processing/tests/swe/test_swe_l2.py +64 -8
  120. imap_processing/tests/test_utils.py +2 -2
  121. imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultrarawimg_withFSWcalcs_FM45_40P_Phi28p5_BeamCal_LinearScan_phi2850_theta-000_20240207T102740.csv +3314 -3314
  122. imap_processing/tests/ultra/test_data/l1/dps_exposure_helio_45_E12.cdf +0 -0
  123. imap_processing/tests/ultra/test_data/l1/dps_exposure_helio_45_E24.cdf +0 -0
  124. imap_processing/tests/ultra/unit/test_de.py +113 -0
  125. imap_processing/tests/ultra/unit/test_spatial_utils.py +125 -0
  126. imap_processing/tests/ultra/unit/test_ultra_l1b.py +27 -3
  127. imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +31 -10
  128. imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +55 -35
  129. imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +10 -68
  130. imap_processing/ultra/constants.py +12 -3
  131. imap_processing/ultra/l1b/de.py +168 -30
  132. imap_processing/ultra/l1b/ultra_l1b_annotated.py +24 -10
  133. imap_processing/ultra/l1b/ultra_l1b_extended.py +46 -80
  134. imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +60 -144
  135. imap_processing/ultra/utils/spatial_utils.py +221 -0
  136. {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/METADATA +15 -14
  137. {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/RECORD +142 -139
  138. imap_processing/cdf/cdf_attribute_manager.py +0 -322
  139. imap_processing/cdf/config/shared/default_global_cdf_attrs_schema.yaml +0 -246
  140. imap_processing/cdf/config/shared/default_variable_cdf_attrs_schema.yaml +0 -466
  141. imap_processing/hi/l0/decom_hi.py +0 -24
  142. imap_processing/hi/packet_definitions/hi_packet_definition.xml +0 -482
  143. imap_processing/hit/l0/data_classes/housekeeping.py +0 -240
  144. imap_processing/hit/l0/data_classes/science_packet.py +0 -259
  145. imap_processing/hit/l0/utils/hit_base.py +0 -57
  146. imap_processing/tests/cdf/shared/default_global_cdf_attrs_schema.yaml +0 -246
  147. imap_processing/tests/cdf/shared/default_variable_cdf_attrs_schema.yaml +0 -466
  148. imap_processing/tests/cdf/test_cdf_attribute_manager.py +0 -353
  149. imap_processing/tests/codice/data/imap_codice_l0_hi-counters-aggregated_20240429_v001.pkts +0 -0
  150. imap_processing/tests/codice/data/imap_codice_l0_hi-counters-singles_20240429_v001.pkts +0 -0
  151. imap_processing/tests/codice/data/imap_codice_l0_hi-omni_20240429_v001.pkts +0 -0
  152. imap_processing/tests/codice/data/imap_codice_l0_hi-pha_20240429_v001.pkts +0 -0
  153. imap_processing/tests/codice/data/imap_codice_l0_hi-sectored_20240429_v001.pkts +0 -0
  154. imap_processing/tests/codice/data/imap_codice_l0_hskp_20100101_v001.pkts +0 -0
  155. imap_processing/tests/codice/data/imap_codice_l0_lo-counters-aggregated_20240429_v001.pkts +0 -0
  156. imap_processing/tests/codice/data/imap_codice_l0_lo-counters-singles_20240429_v001.pkts +0 -0
  157. imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-angular_20240429_v001.pkts +0 -0
  158. imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-priority_20240429_v001.pkts +0 -0
  159. imap_processing/tests/codice/data/imap_codice_l0_lo-nsw-species_20240429_v001.pkts +0 -0
  160. imap_processing/tests/codice/data/imap_codice_l0_lo-pha_20240429_v001.pkts +0 -0
  161. imap_processing/tests/codice/data/imap_codice_l0_lo-sw-angular_20240429_v001.pkts +0 -0
  162. imap_processing/tests/codice/data/imap_codice_l0_lo-sw-priority_20240429_v001.pkts +0 -0
  163. imap_processing/tests/codice/data/imap_codice_l0_lo-sw-species_20240429_v001.pkts +0 -0
  164. imap_processing/tests/hi/test_decom.py +0 -55
  165. imap_processing/tests/hi/test_l1a_sci_de.py +0 -72
  166. imap_processing/tests/idex/imap_idex_l0_raw_20230725_v001.pkts +0 -0
  167. imap_processing/tests/mag/imap_mag_l1a_burst-magi_20231025_v001.cdf +0 -0
  168. /imap_processing/{hi/l0/__init__.py → tests/glows/test_glows_l2_data.py} +0 -0
  169. /imap_processing/tests/hit/test_data/{imap_hit_l0_hk_20100105_v001.pkts → imap_hit_l0_raw_20100105_v001.pkts} +0 -0
  170. {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/LICENSE +0 -0
  171. {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/WHEEL +0 -0
  172. {imap_processing-0.7.0.dist-info → imap_processing-0.9.0.dist-info}/entry_points.txt +0 -0
@@ -6,6 +6,10 @@ from imap_processing.cdf.utils import load_cdf, write_cdf
6
6
  from imap_processing.swe.l1a.swe_l1a import swe_l1a
7
7
  from imap_processing.swe.l1a.swe_science import swe_science
8
8
  from imap_processing.swe.l1b.swe_l1b import swe_l1b
9
+ from imap_processing.swe.l1b.swe_l1b_science import (
10
+ convert_counts_to_rate,
11
+ deadtime_correction,
12
+ )
9
13
 
10
14
 
11
15
  def test_swe_l1b(decom_test_data_derived):
@@ -41,19 +45,36 @@ def test_swe_l1b(decom_test_data_derived):
41
45
  )
42
46
 
43
47
 
44
- def test_cdf_creation():
48
+ def test_cdf_creation(l1b_validation_df):
45
49
  """Test that CDF file is created and has the correct name."""
46
50
  test_data_path = "tests/swe/l0_data/2024051010_SWE_SCIENCE_packet.bin"
47
51
  l1a_datasets = swe_l1a(imap_module_directory / test_data_path, "002")
48
52
 
49
- sci_l1a_filepath = write_cdf(l1a_datasets)
50
-
51
- assert sci_l1a_filepath.name == "imap_swe_l1a_sci_20240510_v002.cdf"
52
-
53
- # reads data from CDF file and passes to l1b
54
- l1a_cdf_dataset = load_cdf(sci_l1a_filepath)
55
- l1b_dataset = swe_l1b(l1a_cdf_dataset, "002")
53
+ l1b_dataset = swe_l1b(l1a_datasets, "002")
56
54
 
57
55
  sci_l1b_filepath = write_cdf(l1b_dataset)
58
56
 
59
57
  assert sci_l1b_filepath.name == "imap_swe_l1b_sci_20240510_v002.cdf"
58
+ # load the CDF file and compare the values
59
+ l1b_cdf_dataset = load_cdf(sci_l1b_filepath)
60
+ processed_science = l1b_cdf_dataset["science_data"].data
61
+ validation_science = l1b_validation_df.values[:, 1:].reshape(6, 24, 30, 7)
62
+ np.testing.assert_allclose(processed_science, validation_science, rtol=1e-7)
63
+
64
+
65
+ def test_count_rate():
66
+ x = np.array([1, 10, 100, 1000, 10000, 38911, 65535])
67
+ acq_duration = 80000
68
+ deatime_corrected = deadtime_correction(x, acq_duration)
69
+ count_rate = convert_counts_to_rate(deatime_corrected, acq_duration)
70
+ # Ruth provided the expected output for this test
71
+ expected_output = [
72
+ 12.50005653,
73
+ 125.00562805,
74
+ 1250.56278121,
75
+ 12556.50455087,
76
+ 130890.05519127,
77
+ 589631.73670132,
78
+ 1161815.68783304,
79
+ ]
80
+ np.testing.assert_allclose(count_rate, expected_output, rtol=1e-7)
@@ -2,13 +2,19 @@ from unittest.mock import patch
2
2
 
3
3
  import numpy as np
4
4
  import pandas as pd
5
+ import pytest
5
6
  import xarray as xr
6
7
 
8
+ from imap_processing import imap_module_directory
9
+ from imap_processing.swe.l1a.swe_l1a import swe_l1a
10
+ from imap_processing.swe.l1b.swe_l1b import swe_l1b
7
11
  from imap_processing.swe.l2.swe_l2 import (
8
- ELECTRON_MASS,
9
12
  ENERGY_CONVERSION_FACTOR,
13
+ VELOCITY_CONVERSION_FACTOR,
14
+ calculate_flux,
10
15
  calculate_phase_space_density,
11
16
  get_particle_energy,
17
+ swe_l2,
12
18
  )
13
19
  from imap_processing.swe.utils.swe_utils import read_lookup_table
14
20
 
@@ -17,7 +23,7 @@ def test_get_particle_energy():
17
23
  """Test get_particle_energy function."""
18
24
  all_energy = get_particle_energy()
19
25
  expected_energy = read_lookup_table()["esa_v"].values * ENERGY_CONVERSION_FACTOR
20
- assert np.all(all_energy["energy"] == expected_energy)
26
+ np.testing.assert_array_equal(all_energy["energy"], expected_energy)
21
27
 
22
28
 
23
29
  @patch("imap_processing.swe.l2.swe_l2.GEOMETRIC_FACTORS", new=np.full(7, 1))
@@ -50,20 +56,70 @@ def test_calculate_phase_space_density(patch_get_particle_energy):
50
56
  ),
51
57
  }
52
58
  )
53
- density = calculate_phase_space_density(l1b_dataset)
54
- assert density.shape == (total_sweeps, 24, 30, 7)
59
+ phase_space_density_ds = calculate_phase_space_density(l1b_dataset)
60
+ assert phase_space_density_ds["phase_space_density"].shape == (
61
+ total_sweeps,
62
+ 24,
63
+ 30,
64
+ 7,
65
+ )
55
66
 
56
67
  # Test that first sweep has correct values. In patch,
57
68
  # 1. we have set GEOMETRIC_FACTORS to 1.
58
69
  # 2. we have set energy to 1.
59
70
  # 3. we have set science_data to 1.
60
71
  # Using this in the formula, we calculate expected density value.
61
- expected_calculated_density = (2 * 1) / (1 * (np.sqrt(2 * 1 / ELECTRON_MASS)) ** 4)
72
+ expected_calculated_density = (2 * 1) / (1 * VELOCITY_CONVERSION_FACTOR * 1**2)
62
73
  expected_density = np.full((24, 30, 7), expected_calculated_density)
63
- assert np.all(density[0].data == expected_density)
74
+ np.testing.assert_array_equal(
75
+ phase_space_density_ds["phase_space_density"][0].data, expected_density
76
+ )
64
77
 
65
78
  # Test that second sweep has correct values, similar to first sweep,
66
79
  # but with energy 2.
67
- expected_calculated_density = (2 * 1) / (1 * (np.sqrt(2 * 2 / ELECTRON_MASS)) ** 4)
80
+ expected_calculated_density = (2 * 1) / (1 * VELOCITY_CONVERSION_FACTOR * 2**2)
68
81
  expected_density = np.full((24, 30, 7), expected_calculated_density)
69
- assert np.all(density[1].data == expected_density)
82
+ np.testing.assert_array_equal(
83
+ phase_space_density_ds["phase_space_density"][1].data, expected_density
84
+ )
85
+ assert type(phase_space_density_ds) == xr.Dataset
86
+
87
+
88
+ def test_calculate_flux():
89
+ """Test calculate_flux function."""
90
+ # Create a dummy l1b dataset
91
+ total_sweeps = 2
92
+ l1b_dataset = xr.Dataset(
93
+ {
94
+ "science_data": (
95
+ ["epoch", "energy", "angle", "cem"],
96
+ np.full((total_sweeps, 24, 30, 7), 1),
97
+ ),
98
+ "acq_duration": (["epoch", "cycle"], np.full((total_sweeps, 4), 80.0)),
99
+ "esa_table_num": (
100
+ ["epoch", "cycle"],
101
+ np.repeat([0, 1], 4).reshape(total_sweeps, 4),
102
+ ),
103
+ }
104
+ )
105
+
106
+ flux = calculate_flux(l1b_dataset)
107
+ assert flux.shape == (total_sweeps, 24, 30, 7)
108
+ assert type(flux) == np.ndarray
109
+
110
+
111
+ @pytest.mark.usefixtures("use_fake_spin_data_for_time")
112
+ def test_swe_l2(use_fake_spin_data_for_time):
113
+ """Test L2 processing."""
114
+ data_start_time = 453051293.099714
115
+ data_end_time = 453066734
116
+ use_fake_spin_data_for_time(data_start_time, data_end_time)
117
+
118
+ test_data_path = "tests/swe/l0_data/2024051010_SWE_SCIENCE_packet.bin"
119
+ l1a_datasets = swe_l1a(imap_module_directory / test_data_path, "002")
120
+
121
+ l1b_dataset = swe_l1b(l1a_datasets, "002")
122
+ l2_dataset = swe_l2(l1b_dataset, "002")
123
+
124
+ assert type(l2_dataset) == xr.Dataset
125
+ assert l2_dataset["spin_phase"].shape == (6, 24, 30, 7)
@@ -91,7 +91,7 @@ def test_packet_file_to_datasets(use_derived_value, expected_mode):
91
91
  packet_files, packet_definition, use_derived_value=use_derived_value
92
92
  )
93
93
  # 3 apids in the test data
94
- assert len(datasets_by_apid) == 4
94
+ assert len(datasets_by_apid) == 2
95
95
  data = datasets_by_apid[1188]
96
96
  assert data["sec_hdr_flg"].dtype == np.uint8
97
97
  assert data["pkt_apid"].dtype == np.uint16
@@ -99,7 +99,7 @@ def test_packet_file_to_datasets(use_derived_value, expected_mode):
99
99
 
100
100
 
101
101
  def test_packet_file_to_datasets_flat_definition():
102
- test_file = "tests/idex/imap_idex_l0_raw_20230725_v001.pkts"
102
+ test_file = "tests/idex/imap_idex_l0_raw_20231214_v001.pkts"
103
103
  packet_files = imap_module_directory / test_file
104
104
  packet_definition = (
105
105
  imap_module_directory / "idex/packet_definitions/idex_packet_definition.xml"