cdiscbuilder 1.2.2__tar.gz → 1.2.3__tar.gz

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.
Files changed (78) hide show
  1. {cdiscbuilder-1.2.2/src/cdiscbuilder.egg-info → cdiscbuilder-1.2.3}/PKG-INFO +1 -2
  2. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/pyproject.toml +2 -3
  3. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/__init__.py +1 -1
  4. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/classes/general.py +19 -2
  5. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/processor.py +21 -2
  6. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/tests/test_boundary_standardization.py +1 -1
  7. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/tests/test_processor.py +4 -4
  8. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3/src/cdiscbuilder.egg-info}/PKG-INFO +1 -2
  9. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder.egg-info/requires.txt +0 -1
  10. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/LICENSE +0 -0
  11. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/MANIFEST.in +0 -0
  12. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/README.md +0 -0
  13. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/setup.cfg +0 -0
  14. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/__init__.py +0 -0
  15. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/__init__.py +0 -0
  16. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/derivations/__init__.py +0 -0
  17. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/derivations/base.py +0 -0
  18. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/derivations/function_derivation.py +0 -0
  19. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/derivations/sql_derivation.py +0 -0
  20. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/engine.py +0 -0
  21. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/functions/__init__.py +0 -0
  22. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/functions/get_bmi.py +0 -0
  23. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/loaders/__init__.py +0 -0
  24. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/loaders/sdtm_loader.py +0 -0
  25. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/tests/test_engine.py +0 -0
  26. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/utils/__init__.py +0 -0
  27. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_derivation/utils/logger.py +0 -0
  28. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/__init__.py +0 -0
  29. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/adam_spec.py +0 -0
  30. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/merge_yaml.py +0 -0
  31. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/schema_validator.py +0 -0
  32. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/__init__.py +0 -0
  33. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/data/scenarios/organization/adsl_common.yaml +0 -0
  34. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/data/scenarios/project/adsl_project.yaml +0 -0
  35. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/data/scenarios/schema.yaml +0 -0
  36. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/data/scenarios/study1/adam_study1.yaml +0 -0
  37. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/data/scenarios/study1/adsl_study1.yaml +0 -0
  38. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/data/scenarios/study1/final_adsl_study1.yaml +0 -0
  39. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/data/scenarios/study2/adam_study2.yaml +0 -0
  40. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/data/scenarios/study2/adsl_study2.yaml +0 -0
  41. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/data/scenarios/study2/final_adsl_study2.yaml +0 -0
  42. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/test_adam_spec.py +0 -0
  43. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/test_merge_yaml.py +0 -0
  44. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_spec/tests/test_schema_validator.py +0 -0
  45. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_validation/__init__.py +0 -0
  46. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/adam_validation/data_validator.py +0 -0
  47. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/adam/schema.yaml +0 -0
  48. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/cli.py +0 -0
  49. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/functions/__init__.py +0 -0
  50. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/functions/calculate_study_day.py +0 -0
  51. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/functions/extract_value.py +0 -0
  52. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/functions/get_bmi.py +0 -0
  53. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/__init__.py +0 -0
  54. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/__init__.py +0 -0
  55. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/classes/__init__.py +0 -0
  56. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/classes/base.py +0 -0
  57. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/classes/events.py +0 -0
  58. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/classes/findings.py +0 -0
  59. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/classes/interventions.py +0 -0
  60. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/classes/special_purpose.py +0 -0
  61. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/config.py +0 -0
  62. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/tests/test_config.py +0 -0
  63. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/tests/test_findings.py +0 -0
  64. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/tests/test_general.py +0 -0
  65. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/tests/test_metadata_extractor.py +0 -0
  66. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/tests/test_validate.py +0 -0
  67. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/engine/validate.py +0 -0
  68. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/loader/__init__.py +0 -0
  69. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/loader/load.py +0 -0
  70. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/loader/tests/__init__.py +0 -0
  71. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/loader/tests/test_load.py +0 -0
  72. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/odm_parser.py +0 -0
  73. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/sdtm/sdtm.py +0 -0
  74. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder/tlf/__init__.py +0 -0
  75. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder.egg-info/SOURCES.txt +0 -0
  76. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder.egg-info/dependency_links.txt +0 -0
  77. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder.egg-info/entry_points.txt +0 -0
  78. {cdiscbuilder-1.2.2 → cdiscbuilder-1.2.3}/src/cdiscbuilder.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cdiscbuilder
3
- Version: 1.2.2
3
+ Version: 1.2.3
4
4
  Summary: A package to convert ODM XML to SDTM/ADaM Datasets
5
5
  Author-email: Ming-Chun Chen <hellomingchun@gmail.com>
6
6
  Requires-Python: >=3.9
@@ -10,7 +10,6 @@ Requires-Dist: pandas
10
10
  Requires-Dist: pyyaml
11
11
  Requires-Dist: polars>=0.20.0
12
12
  Requires-Dist: reactable>=0.1.6
13
- Requires-Dist: pyarrow
14
13
  Dynamic: license-file
15
14
 
16
15
  # CDISC Builder
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cdiscbuilder"
7
- version = "1.2.2"
7
+ version = "1.2.3"
8
8
  description = "A package to convert ODM XML to SDTM/ADaM Datasets"
9
9
  readme = "README.md"
10
10
  authors = [{name = "Ming-Chun Chen", email = "hellomingchun@gmail.com"}]
@@ -12,8 +12,7 @@ dependencies = [
12
12
  "pandas",
13
13
  "pyyaml",
14
14
  "polars>=0.20.0",
15
- "reactable>=0.1.6",
16
- "pyarrow"
15
+ "reactable>=0.1.6"
17
16
  ]
18
17
  requires-python = ">=3.9"
19
18
 
@@ -1,4 +1,4 @@
1
- __version__ = "1.2.1"
1
+ __version__ = "1.2.3"
2
2
 
3
3
  from . import adam as adam
4
4
  from . import tlf as tlf
@@ -168,6 +168,9 @@ class GeneralProcessor:
168
168
  temp_df = final_df[group_cols].copy()
169
169
 
170
170
  sort_keys = group_cols[:] # Always sort by group first
171
+ ascending_list = [True] * len(group_cols)
172
+
173
+ order_cfg = col_config.get("order")
171
174
 
172
175
  if sort_cols:
173
176
  if not isinstance(sort_cols, list):
@@ -184,12 +187,26 @@ class GeneralProcessor:
184
187
  for c in sort_cols:
185
188
  temp_df[c] = final_df[c]
186
189
  sort_keys.extend(sort_cols)
190
+
191
+ # Apply custom order if provided
192
+ if order_cfg:
193
+ if not isinstance(order_cfg, list):
194
+ order_cfg = [order_cfg]
195
+
196
+ # Map "asc"/"desc" to True/False for the sort_cols
197
+ for o in order_cfg:
198
+ if str(o).lower() in ["desc", "descending", "false"]:
199
+ ascending_list.append(False)
200
+ else:
201
+ ascending_list.append(True)
202
+ else:
203
+ ascending_list.extend([True] * len(sort_cols))
187
204
 
188
205
  # Sort
189
- temp_df = temp_df.sort_values(by=sort_keys)
206
+ temp_df = temp_df.sort_values(by=sort_keys, ascending=ascending_list)
190
207
 
191
208
  # Calculate Cumcount + 1
192
- seq_series = temp_df.groupby(group_cols).cumcount() + 1
209
+ seq_series = temp_df.groupby(group_cols, sort=False).cumcount() + 1
193
210
 
194
211
  # Map back to original index
195
212
  series = seq_series.sort_index()
@@ -86,6 +86,8 @@ def process_domain(domain_name, sources, df_long, default_keys, output_dir, cust
86
86
  group_cols = col_config.get("group")
87
87
  sort_cols = col_config.get("sort_by")
88
88
 
89
+ order_cfg = col_config.get("order")
90
+
89
91
  if not isinstance(group_cols, list):
90
92
  group_cols = [group_cols]
91
93
 
@@ -99,6 +101,9 @@ def process_domain(domain_name, sources, df_long, default_keys, output_dir, cust
99
101
  # Create sort view
100
102
  temp_df = combined_df[group_cols].copy()
101
103
  sort_keys = group_cols[:]
104
+
105
+ # Determine sorting order (ascending by default)
106
+ ascending_list = [True] * len(group_cols)
102
107
 
103
108
  if sort_cols:
104
109
  if not isinstance(sort_cols, list):
@@ -108,11 +113,25 @@ def process_domain(domain_name, sources, df_long, default_keys, output_dir, cust
108
113
  for c in sort_cols:
109
114
  temp_df[c] = combined_df[c]
110
115
  sort_keys.extend(sort_cols)
116
+
117
+ # Apply custom order if provided
118
+ if order_cfg:
119
+ if not isinstance(order_cfg, list):
120
+ order_cfg = [order_cfg]
121
+
122
+ # Map "asc"/"desc" to True/False for the sort_cols
123
+ for o in order_cfg:
124
+ if str(o).lower() in ["desc", "descending", "false"]:
125
+ ascending_list.append(False)
126
+ else:
127
+ ascending_list.append(True)
128
+ else:
129
+ ascending_list.extend([True] * len(sort_cols))
111
130
 
112
131
  # Sort
113
- temp_df = temp_df.sort_values(by=sort_keys)
132
+ temp_df = temp_df.sort_values(by=sort_keys, ascending=ascending_list)
114
133
  # Cumcount + 1
115
- seq_series = temp_df.groupby(group_cols).cumcount() + 1
134
+ seq_series = temp_df.groupby(group_cols, sort=False).cumcount() + 1
116
135
  # Re-align to combined_df index
117
136
  combined_df[target_col] = seq_series.sort_index()
118
137
 
@@ -125,7 +125,7 @@ def test_create_sdtm_datasets_boundary_standardization(tmp_path):
125
125
  create_sdtm_datasets(str(spec_dir), str(input_csv), str(output_dir))
126
126
 
127
127
  # Verify dataset exists
128
- out_file = output_dir / "AE.parquet"
128
+ out_file = output_dir / "ae.parquet"
129
129
  assert out_file.exists()
130
130
 
131
131
  res_df = pd.read_parquet(out_file)
@@ -90,7 +90,7 @@ def test_process_domain_append_real(tmp_path):
90
90
  out_dir = tmp_path / "sdtm_out"
91
91
  process_domain("DM", sources, pd.DataFrame(), ["Subj"], str(out_dir))
92
92
 
93
- out_file = out_dir / "DM.parquet"
93
+ out_file = out_dir / "dm.parquet"
94
94
  assert out_file.exists()
95
95
 
96
96
  res_df = pd.read_parquet(out_file)
@@ -114,7 +114,7 @@ def test_process_domain_merge_blocks(tmp_path):
114
114
  out_dir = tmp_path / "sdtm_out"
115
115
  process_domain("DM", sources, pd.DataFrame(), ["Subj"], str(out_dir))
116
116
 
117
- res_df = pd.read_parquet(out_dir / "DM.parquet")
117
+ res_df = pd.read_parquet(out_dir / "dm.parquet")
118
118
  assert len(res_df) == 2
119
119
  assert "AGE" in res_df.columns
120
120
  assert "SEX" in res_df.columns
@@ -140,7 +140,7 @@ def test_process_domain_merge_blocks_missing_keys(tmp_path, capsys):
140
140
  out, err = capsys.readouterr()
141
141
  assert "missing keys: ['USUBJID']" in out
142
142
 
143
- res_df = pd.read_parquet(out_dir / "DM.parquet")
143
+ res_df = pd.read_parquet(out_dir / "dm.parquet")
144
144
  # Appended instead of merged
145
145
  assert len(res_df) == 2
146
146
  assert "SEX" in res_df.columns
@@ -174,6 +174,6 @@ def test_process_domain_global_sequence(tmp_path):
174
174
  out_dir = tmp_path / "sdtm_out"
175
175
  process_domain("DM", sources, pd.DataFrame(), ["Subj"], str(out_dir))
176
176
 
177
- res_df = pd.read_parquet(out_dir / "DM.parquet")
177
+ res_df = pd.read_parquet(out_dir / "dm.parquet")
178
178
  assert "SEQ" in res_df.columns
179
179
  assert list(res_df["SEQ"]) == [1, 2, 1, 2]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cdiscbuilder
3
- Version: 1.2.2
3
+ Version: 1.2.3
4
4
  Summary: A package to convert ODM XML to SDTM/ADaM Datasets
5
5
  Author-email: Ming-Chun Chen <hellomingchun@gmail.com>
6
6
  Requires-Python: >=3.9
@@ -10,7 +10,6 @@ Requires-Dist: pandas
10
10
  Requires-Dist: pyyaml
11
11
  Requires-Dist: polars>=0.20.0
12
12
  Requires-Dist: reactable>=0.1.6
13
- Requires-Dist: pyarrow
14
13
  Dynamic: license-file
15
14
 
16
15
  # CDISC Builder
@@ -2,4 +2,3 @@ pandas
2
2
  pyyaml
3
3
  polars>=0.20.0
4
4
  reactable>=0.1.6
5
- pyarrow
File without changes
File without changes
File without changes
File without changes