tricc-oo 1.5.22__py3-none-any.whl → 1.5.24__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.
Files changed (45) hide show
  1. tests/build.py +17 -23
  2. tests/test_cql.py +37 -108
  3. tests/to_ocl.py +15 -17
  4. tricc_oo/__init__.py +0 -6
  5. tricc_oo/converters/codesystem_to_ocl.py +51 -40
  6. tricc_oo/converters/cql/cqlLexer.py +1 -0
  7. tricc_oo/converters/cql/cqlListener.py +1 -0
  8. tricc_oo/converters/cql/cqlParser.py +1 -0
  9. tricc_oo/converters/cql/cqlVisitor.py +1 -0
  10. tricc_oo/converters/cql_to_operation.py +125 -123
  11. tricc_oo/converters/datadictionnary.py +45 -54
  12. tricc_oo/converters/drawio_type_map.py +143 -61
  13. tricc_oo/converters/tricc_to_xls_form.py +14 -24
  14. tricc_oo/converters/utils.py +3 -3
  15. tricc_oo/converters/xml_to_tricc.py +286 -231
  16. tricc_oo/models/__init__.py +2 -1
  17. tricc_oo/models/base.py +300 -308
  18. tricc_oo/models/calculate.py +63 -49
  19. tricc_oo/models/lang.py +26 -27
  20. tricc_oo/models/ocl.py +146 -161
  21. tricc_oo/models/ordered_set.py +15 -19
  22. tricc_oo/models/tricc.py +145 -89
  23. tricc_oo/parsers/xml.py +15 -30
  24. tricc_oo/serializers/planuml.py +4 -6
  25. tricc_oo/serializers/xls_form.py +81 -135
  26. tricc_oo/strategies/input/base_input_strategy.py +28 -32
  27. tricc_oo/strategies/input/drawio.py +59 -71
  28. tricc_oo/strategies/output/base_output_strategy.py +142 -67
  29. tricc_oo/strategies/output/fhir_form.py +377 -0
  30. tricc_oo/strategies/output/html_form.py +224 -0
  31. tricc_oo/strategies/output/openmrs_form.py +647 -0
  32. tricc_oo/strategies/output/spice.py +106 -127
  33. tricc_oo/strategies/output/xls_form.py +263 -222
  34. tricc_oo/strategies/output/xlsform_cdss.py +623 -142
  35. tricc_oo/strategies/output/xlsform_cht.py +108 -115
  36. tricc_oo/strategies/output/xlsform_cht_hf.py +13 -24
  37. tricc_oo/visitors/tricc.py +1297 -1016
  38. tricc_oo/visitors/utils.py +16 -16
  39. tricc_oo/visitors/xform_pd.py +91 -89
  40. {tricc_oo-1.5.22.dist-info → tricc_oo-1.5.24.dist-info}/METADATA +127 -84
  41. tricc_oo-1.5.24.dist-info/RECORD +50 -0
  42. tricc_oo-1.5.24.dist-info/licenses/LICENSE +373 -0
  43. tricc_oo-1.5.22.dist-info/RECORD +0 -46
  44. {tricc_oo-1.5.22.dist-info → tricc_oo-1.5.24.dist-info}/WHEEL +0 -0
  45. {tricc_oo-1.5.22.dist-info → tricc_oo-1.5.24.dist-info}/top_level.txt +0 -0
@@ -1,17 +1,17 @@
1
1
  PROCESSES = [
2
- "triage",
3
- "emergency-care",
4
- "registration",
5
- "history-and-physical",
6
- "local-urgent-care",
7
- "acute-tertiary-care",
8
- "diagnostic-testing",
9
- "determine-diagnosis",
10
- "provide-counseling",
11
- "dispense-medications",
12
- "monitor-and-follow-up-of-patient",
13
- "alerts-reminders-education",
14
- "discharge-referral-of-patient",
15
- "charge-for-service",
16
- "record-and-report",
17
- ]
2
+ "triage",
3
+ "emergency-care",
4
+ "registration",
5
+ "history-and-physical",
6
+ "local-urgent-care",
7
+ "acute-tertiary-care",
8
+ "diagnostic-testing",
9
+ "determine-diagnosis",
10
+ "provide-counseling",
11
+ "dispense-medications",
12
+ "monitor-and-follow-up-of-patient",
13
+ "alerts-reminders-education",
14
+ "discharge-referral-of-patient",
15
+ "charge-for-service",
16
+ "record-and-report",
17
+ ]
@@ -4,15 +4,16 @@ Created on Thu Sep 1 11:21:39 2022
4
4
 
5
5
  @author: kluera
6
6
 
7
- Make subforms that allow to be releoaded seperately as a 'task' in CHT,
8
- allowing to simulate a pause functionality.
7
+ Make subforms that allow to be releoaded seperately as a 'task' in CHT,
8
+ allowing to simulate a pause functionality.
9
9
  """
10
10
 
11
11
  import pandas as pd
12
- import json
12
+
13
13
 
14
14
  def remove_dots(s):
15
- return s.replace('.','_')
15
+ return s.replace(".", "_")
16
+
16
17
 
17
18
  def chf_clean_name(s, remove_dots=False):
18
19
  # Check if there is a dot in the string
@@ -24,159 +25,161 @@ def chf_clean_name(s, remove_dots=False):
24
25
  # If no dot is present, return None or handle it as needed
25
26
  return s
26
27
 
28
+
27
29
  # df is the dataframe to be split
28
30
  # pausepoint is the index of the row after which the form should pause
29
31
  def make_breakpoints(df, pausepoint, calculate_name=None, replace_dots=False):
30
32
  """
31
33
  Creates a dataframe for a follow-up questionnaire while preserving previous inputs.
32
-
34
+
33
35
  Args:
34
36
  df: Input dataframe containing the questionnaire
35
37
  pausepoint: Point where the questionnaire should pause
36
38
  calculate_name: Optional name for calculation fields
37
39
  """
38
-
40
+
39
41
  # Get data points collected before break
40
- if 'input end' not in df['name'].values:
42
+ if "input end" not in df["name"].values:
41
43
  raise ValueError("input end field not found in input dataframe")
42
- end_inputs_loc = df.index[df['name'] == 'input end'][0]
43
- next_begin_group_loc = min([i for i in df.index[df['type'] == 'begin group'] if i > end_inputs_loc])
44
- next_pause_point_begin_group_loc = min([i for i in df.index[df['type'] == 'begin group'] if i > pausepoint])
45
-
44
+ end_inputs_loc = df.index[df["name"] == "input end"][0]
45
+ next_begin_group_loc = min([i for i in df.index[df["type"] == "begin group"] if i > end_inputs_loc])
46
+ next_pause_point_begin_group_loc = min([i for i in df.index[df["type"] == "begin group"] if i > pausepoint])
47
+
46
48
  df_input = df.loc[next_begin_group_loc:next_pause_point_begin_group_loc]
47
-
49
+
48
50
  # Define field types to handle
49
- typesconvert = ['integer', 'decimal', 'select_', 'text']
50
- typeskeep = ['hidden', 'calculate', 'string']
51
-
51
+ typesconvert = ["integer", "decimal", "select_", "text"]
52
+ typeskeep = ["hidden", "calculate", "string"]
53
+
52
54
  # Create masks for filtering
53
- type_mask = df_input['type'].str.contains('|'.join(typeskeep + typesconvert))
54
- optin_mask = ~df_input['name'].str.contains('more_info_optin', na=False)
55
-
55
+ type_mask = df_input["type"].str.contains("|".join(typeskeep + typesconvert))
56
+ optin_mask = ~df_input["name"].str.contains("more_info_optin", na=False)
57
+
56
58
  # Filter dataframe keeping important fields
57
59
  df_input = df_input.loc[type_mask & optin_mask]
58
-
60
+
59
61
  # Preserve existing hidden fields and their calculations
60
- existing_hidden = df_input[df_input['type'] == 'hidden'].copy()
61
-
62
+ existing_hidden = df_input[df_input["type"] == "hidden"].copy()
63
+
62
64
  # Convert specified types to hidden while preserving their data
63
- mask_indices = df_input.index[df_input['type'].str.contains('|'.join(typesconvert))]
65
+ mask_indices = df_input.index[df_input["type"].str.contains("|".join(typesconvert))]
64
66
  # Get hidden field names
65
67
 
66
- df_input.loc[mask_indices, 'type'] = 'hidden'
67
- df_input.loc[mask_indices, 'appearance'] = 'hidden'
68
+ df_input.loc[mask_indices, "type"] = "hidden"
69
+ df_input.loc[mask_indices, "appearance"] = "hidden"
68
70
 
69
71
  # Handle label columns while preserving existing labels where needed
70
- label_cols = [col for col in df.columns if 'label' in col]
71
- df_input.loc[mask_indices, label_cols] = 'NO_LABEL'
72
-
72
+ label_cols = [col for col in df.columns if "label" in col]
73
+ df_input.loc[mask_indices, label_cols] = "NO_LABEL"
74
+
73
75
  # Clear non-essential columns while preserving crucial data
74
- essential_cols = ['name', 'type', 'calculation'] + label_cols
76
+ essential_cols = ["name", "type", "calculation"] + label_cols
75
77
  other_cols = df_input.columns.drop(essential_cols)
76
- df_input[other_cols] = ''
77
-
78
+ df_input[other_cols] = ""
79
+
78
80
  # Preserve calculations for existing hidden fields
79
- df_input.update(existing_hidden[['calculation']])
81
+ df_input.update(existing_hidden[["calculation"]])
80
82
  # SAVE THE INPUT NAMES
81
- hidden_names = list(df_input.loc[df_input['type']=='hidden', 'name'])
83
+ hidden_names = list(df_input.loc[df_input["type"] == "hidden", "name"])
82
84
  if replace_dots:
83
- df_input['name'] = df_input['name'].map(remove_dots)
85
+ df_input["name"] = df_input["name"].map(remove_dots)
84
86
  # Handle indexing and grouping
85
87
  df_input.index = df_input.index.map(str)
86
- hidden_ids = df_input.loc[df_input['type']=='hidden'].index
87
- inputs_group_index = '0'
88
- new_hidden_ids = inputs_group_index + '.' + hidden_ids
89
-
88
+ hidden_ids = df_input.loc[df_input["type"] == "hidden"].index
89
+ inputs_group_index = "0"
90
+ new_hidden_ids = inputs_group_index + "." + hidden_ids
91
+
90
92
  # Update indices
91
93
  index_map = dict(zip(hidden_ids, new_hidden_ids))
92
94
  df_input.rename(index=index_map, inplace=True)
93
95
  df_input.sort_index(inplace=True)
94
96
  df_input.reset_index(drop=True, inplace=True)
95
-
97
+
96
98
  if remove_dots:
97
99
  # Precompute replacement dictionary
98
- replacement_dict = {f'${old_name}': f'${remove_dots(old_name)}' for old_name in hidden_names if '.' in old_name}
100
+ replacement_dict = {f"${old_name}": f"${remove_dots(old_name)}" for old_name in hidden_names if "." in old_name}
99
101
 
100
102
  # Apply replacements to entire DataFrame
101
103
  df_input = df_input.astype(str).replace(replacement_dict, regex=False)
102
-
103
104
 
104
-
105
-
106
-
107
- # put all together
108
- if 'data_load' not in df['name'].values:
105
+ # put all together
106
+ if "data_load" not in df["name"].values:
109
107
  raise ValueError("data_load field not found in input dataframe")
110
- data_load_loc = df.index[df['name'] == 'data_load'][0]
111
-
108
+ data_load_loc = df.index[df["name"] == "data_load"][0]
109
+
112
110
  # Split the dataframe into three parts
113
111
  df_before_data_load = df.loc[:data_load_loc] # Everything up to data_load
114
- df_until_begin_group = df.loc[data_load_loc+1:next_begin_group_loc-1] # From data_load to next begin_group
115
-
112
+ df_until_begin_group = df.loc[data_load_loc + 1: next_begin_group_loc - 1] # From data_load to next begin_group
113
+
116
114
  # Reset indices for proper concatenation
117
115
  df_input = df_input.reset_index(drop=True)
118
116
  df_before_data_load = df_before_data_load.reset_index(drop=True)
119
117
  df_until_begin_group = df_until_begin_group.reset_index(drop=True)
120
-
118
+
121
119
  # Concatenate in the correct order
122
- df_combined = pd.concat([
123
- df_before_data_load, # First part until data_load
124
- df_input, # Injected converted fields
125
- df_until_begin_group # Remaining part until next begin_group
126
- ]).reset_index(drop=True)
127
-
120
+ df_combined = pd.concat(
121
+ [
122
+ df_before_data_load, # First part until data_load
123
+ df_input, # Injected converted fields
124
+ df_until_begin_group, # Remaining part until next begin_group
125
+ ]
126
+ ).reset_index(drop=True)
127
+
128
128
  # Handle post-break section
129
129
  df_after = df.loc[next_pause_point_begin_group_loc:].reset_index(drop=True)
130
130
 
131
-
132
131
  # Final concatenation
133
132
  final_df = pd.concat([df_combined, df_after])
134
133
  if calculate_name:
135
- final_df.loc[final_df['name']=='hidden','calculation']='0'
136
-
137
- final_df.fillna('', inplace=True)
134
+ final_df.loc[final_df["name"] == "hidden", "calculation"] = "0"
135
+
136
+ final_df.fillna("", inplace=True)
138
137
  final_df.reset_index(inplace=True, drop=True)
139
-
140
- return final_df, hidden_names
141
138
 
139
+ return final_df, hidden_names
142
140
 
143
141
 
144
142
  def get_tasksstrings(hidden_names, df_survey):
145
- '''This function makes a list of strings of hidden fields that will be loaded into a form that continues the consultation.
146
- This is very handy as this string must be pasted into the tasks.js file in CHT.
143
+ """This function makes a list of strings of hidden fields that will be loaded
144
+ into a form that continues the consultation.
145
+ This is very handy as this string must be pasted into the tasks.js file in CHT.
147
146
  @hidden_names: are the names of the 'hidden' fields in the input group of the follow up form
148
147
  @df_survey: is the survey tab of the complete (original) form without breaks, going from A to Z
149
- @tasks_strings: is the string that has to be pasted into tasks.js'''
150
-
148
+ @tasks_strings: is the string that has to be pasted into tasks.js"""
149
+
151
150
  task_string_template = "content['{variableName}'] = getField(report, '{full_path}')"
152
151
  task_strings = {}
153
152
  for s in hidden_names:
154
- df_above_s = df_survey.iloc[:df_survey.loc[df_survey['name']==s].index[0]]
155
- df_above_s_groups = df_above_s.loc[df_above_s['type'].isin(['begin group', 'end group'])]
153
+ df_above_s = df_survey.iloc[: df_survey.loc[df_survey["name"] == s].index[0]]
154
+ df_above_s_groups = df_above_s.loc[df_above_s["type"].isin(["begin group", "end group"])]
156
155
  above_s_grouprows = df_above_s_groups.index
157
156
  fullpath = []
158
157
  for i in above_s_grouprows:
159
- if df_above_s.iloc[i]['type']=='begin group':
160
- fullpath.append(df_above_s.iloc[i]['name'])
161
- else:
158
+ if df_above_s.iloc[i]["type"] == "begin group":
159
+ fullpath.append(df_above_s.iloc[i]["name"])
160
+ else:
162
161
  fullpath = fullpath[:-1]
163
- if len(fullpath)>0:
164
- line = task_string_template.format(
165
- variableName=s, full_path='.'.join(fullpath) + chf_clean_name(s)
166
- )
162
+ if len(fullpath) > 0:
163
+ line = task_string_template.format(variableName=s, full_path=".".join(fullpath) + chf_clean_name(s))
167
164
  else:
168
- line = task_string_template.format(
169
- variableName=s, full_path=chf_clean_name(s)
170
- )
171
- task_strings[s]=line
172
- return list(task_strings.values())
173
-
174
-
175
- def get_task_js(form_id, calculate_name, title, form_types, hidden_names, df_survey, repalce_dots=False, task_title="'id: '+getField(report, 'g_registration.p_id')+'; age: '+getField(report, 'p_age')+getField(report, 'g_registration.p_gender')+' months; '+getField(report, 'p_weight') + 'kg; ' + getField(report, 'g_fever.p_temp')+'°'"):
165
+ line = task_string_template.format(variableName=s, full_path=chf_clean_name(s))
166
+ task_strings[s] = line
167
+ return list(task_strings.values())
168
+
169
+
170
+ def get_task_js(
171
+ form_id,
172
+ calculate_name,
173
+ title,
174
+ form_types,
175
+ hidden_names,
176
+ df_survey,
177
+ repalce_dots=False,
178
+ task_title="id: '+getField(report, 'g_registration.p_id')+';age: '+getField(report, 'p_age')+getField(report, 'g_registration.p_gender')+' months; '+getField(report, 'p_weight') + 'kg; ' + getField(report, 'g_fever.p_temp')+'°'", # noqa: E501
179
+ ):
176
180
  task_name = f"{form_id}"
177
181
  task_name_upper = task_name.upper()
178
182
 
179
-
180
183
  return f"""
181
184
  /* eslint-disable no-use-before-define */
182
185
  /* eslint-disable */
@@ -185,7 +188,7 @@ const {{injectDataFromForm, isFormArrayHasSourceId}} = require('./stph-extras');
185
188
  const {{getField}} = require("./nools-extras");
186
189
 
187
190
  const CASE_DATA = ['{"','".join(hidden_names)}'];
188
-
191
+
189
192
 
190
193
  const {task_name_upper}_FORMS = ['{"','".join(form_types)}'];
191
194
 
@@ -195,7 +198,7 @@ const {task_name_upper}_TASK_FORM = '{form_id}';
195
198
 
196
199
  const {task_name}Content = function (content, contact, report){{
197
200
 
198
- injectDataFromForm(content, '', CASE_DATA, {task_name_upper}_FORMS, [report], {'true' if repalce_dots else 'false'});
201
+ injectDataFromForm(content, '', CASE_DATA, {task_name_upper}_FORMS, [report], {'true' if repalce_dots else 'false'});
199
202
  content['patient_id'] = report.contact._id;
200
203
  content['source_id'] = report._id;
201
204
  console.log(content);
@@ -230,7 +233,7 @@ module.exports = {{
230
233
  {task_name}ResolveIf,
231
234
  {task_name}AppliesIf,
232
235
  }}
233
- //
236
+ //
234
237
  //// to be copied in task
235
238
  //
236
239
  //const {{
@@ -238,7 +241,7 @@ module.exports = {{
238
241
  // {task_name_upper}_FORMS,
239
242
  // {task_name}Content,
240
243
  // {task_name}ContactLabel,
241
- // {task_name}ResolveIf,
244
+ // {task_name}ResolveIf,
242
245
  // {task_name}AppliesIf, }} = require('./{task_name}');
243
246
  //
244
247
  //module.exports = [
@@ -270,4 +273,3 @@ module.exports = {{
270
273
  // }}
271
274
  //];
272
275
  """
273
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tricc-oo
3
- Version: 1.5.22
3
+ Version: 1.5.24
4
4
  Summary: Python library that converts CDSS L2 in L3
5
5
  Project-URL: Homepage, https://github.com/SwissTPH/tricc
6
6
  Project-URL: Issues, https://github.com/SwissTPH/tricc/issues
@@ -9,6 +9,7 @@ Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Operating System :: OS Independent
10
10
  Requires-Python: >=3.8
11
11
  Description-Content-Type: text/markdown
12
+ License-File: LICENSE
12
13
  Requires-Dist: lxml
13
14
  Requires-Dist: markdownify
14
15
  Requires-Dist: pydantic
@@ -23,8 +24,132 @@ Requires-Dist: antlr4-python3-runtime==4.13.2
23
24
  Requires-Dist: antlr4-tools==0.2.1
24
25
  Requires-Dist: beautifulsoup4
25
26
  Requires-Dist: ocldev
27
+ Dynamic: license-file
26
28
 
27
- # design rules tricc_oo
29
+ # TRICC-OO
30
+
31
+
32
+ ## Strategy
33
+
34
+ ### XLSFormStrategy
35
+
36
+ to use on OKD and clones,
37
+
38
+ ### XLSFormCDSSStrategy
39
+
40
+ based on XLSFormStrategy
41
+ to use on OKD and clones,
42
+ support the CDSS specific behaviour such as Classification management
43
+
44
+ ### XLSFormCHTStrategy
45
+
46
+ based on XLSFormCDSSStrategy
47
+ to use on medic CHT if the questionnaire is run Patient level
48
+ Support the inputs from patient
49
+ Support the extention libs
50
+
51
+ ### XLSFormCHTHFStrategy
52
+
53
+ based on XLSFormCHTStrategy
54
+ to use on medic CHT if the questionnaire is run on Health facility level without selecting a patient
55
+ Support inputs from HF
56
+
57
+
58
+ ### OpenMRSStrategy
59
+
60
+ (under development)
61
+
62
+ ### FhirStrategy
63
+
64
+ (UNTESTED)
65
+
66
+ ### HTMLStrategy
67
+
68
+ (UNTESTED)
69
+
70
+ ## start nodes
71
+
72
+ ### Main start
73
+
74
+ the flow required at least 1 main start node, but in case of cdss output strategy , several could be used given that they have a 'process' atrribute
75
+
76
+ here is the list of the CPG process, this will be the execution oder too:
77
+ - **registration**,
78
+ - **triage**,
79
+ - **emergency-care**,
80
+ - **local-urgent-care**,
81
+ - **actue-tertiary-care**,
82
+ - **history-and-physical**,
83
+ - **diagnostic-testing**,
84
+ - **determine-diagnosis**,
85
+ - **provide-counseling**,
86
+ - **dispense-medications**,
87
+ - **monitor-and-follow-up-of-patient**,
88
+ - **alerts-reminders-education**,
89
+ - **discharge-referral-of-patient**,
90
+ - **charge-for-service**,
91
+ - **record-and-report**
92
+
93
+
94
+
95
+
96
+ # Note
97
+
98
+ ## generation of the expressions
99
+
100
+ ### add calcualte:
101
+
102
+ - Non or No in an egde will generate a negate node
103
+ - save adds a calcualte
104
+ - a rhombus will generate a calcualte using the reference (can you the label as a test, either with comparaisin or option selected with [option label])
105
+
106
+ ### for calculate
107
+
108
+ Then we calculate based on the previous nodes: [get_prev_node_expression]
109
+ - if a "fake" calculate (Rhombus, exclusion) then get the underlying expression (should not depend of Calcualte = true) [get_calculation_terms]
110
+ - if a Select, manage it as a calculate too (should not depend of Calcualte = true) [get_calculation_terms]
111
+ - else get the expression via [get_calculation_terms] [get_prev_node_expression , calculate = False] -> get_node_expression for the prev node
112
+
113
+ # Running directly
114
+
115
+ `tricc` is technically a python library, but you can run it directly via the [`build.py` script](./tests/build.py).
116
+
117
+ ## Running with Docker
118
+
119
+ Alternatively, if you prefer to build/run the project with Docker, you can do the following.
120
+
121
+ Start by building the Docker image:
122
+
123
+ ```shell
124
+ git clone https://github.com/SwissTPH/tricc.git
125
+ cd tricc
126
+
127
+ docker build -t tricc .
128
+ ```
129
+
130
+ Once you have the image built you can use it to convert local `.drawio` files by mapping the local directory to the `docker run` command. (Note that `--user` is specified to make sure the current host user has write access to the output files.)
131
+
132
+ ```shell
133
+ docker run --rm -v "$PWD":/proj --user $(id -u):$(id -g) tricc --help
134
+ ```
135
+
136
+ This command will convert all `.drawio` files in the current directory:
137
+
138
+ ```shell
139
+ docker run --rm -v "$PWD":/proj --user $(id -u):$(id -g) tricc -i /proj -o /proj
140
+ ```
141
+
142
+ You can also convert a single file:
143
+
144
+ ```shell
145
+ docker run --rm -v "$PWD":/proj --user $(id -u):$(id -g) tricc -i /proj/demo.drawio -o /proj
146
+ ```
147
+
148
+ Use the `-O` flag to specify the output strategy. For example to generate CHT files:
149
+
150
+ ```shell
151
+ docker run --rm -v "$PWD":/proj --user $(id -u):$(id -g) tricc -i /proj -o /proj -O XLSFormCHTStrategy
152
+ ```
28
153
 
29
154
  ## Nodes
30
155
 
@@ -131,90 +256,8 @@ if not a calculate then relevance will be used unless it is "required" then cond
131
256
  the Rhombus act as an AND between its imputs and its reference BUT it is an OR beween the inputs
132
257
  (input1 OR input2 OR input3) AND reference
133
258
 
134
- ## start nodes
135
-
136
- ### Main start
137
-
138
- the flow required at least 1 main start node, but in case of cdss output strategy , several could be used given that they have a 'process' atrribute
139
-
140
- here is the list of the CPG process, this will be the execution oder too:
141
- - **registration**,
142
- - **triage**,
143
- - **emergency-care**,
144
- - **local-urgent-care**,
145
- - **actue-tertiary-care**,
146
- - **history-and-physical**,
147
- - **diagnostic-testing**,
148
- - **determine-diagnosis**,
149
- - **provide-counseling**,
150
- - **dispense-medications**,
151
- - **monitor-and-follow-up-of-patient**,
152
- - **alerts-reminders-education**,
153
- - **discharge-referral-of-patient**,
154
- - **charge-for-service**,
155
- - **record-and-report**
156
-
157
-
158
259
  # READ Xressource
159
260
  https://jgraph.github.io/drawio-tools/tools/convert.html
160
261
 
161
262
  option can have only incoming edge from images to be placed as option$
162
263
 
163
-
164
- # Note
165
-
166
- ## generation of the expressions
167
-
168
- ### add calcualte:
169
-
170
- - Non or No in an egde will generate a negate node
171
- - save adds a calcualte
172
- - a rhombus will generate a calcualte using the reference (can you the label as a test, either with comparaisin or option selected with [option label])
173
-
174
- ### for calculate
175
-
176
- Then we calculate based on the previous nodes: [get_prev_node_expression]
177
- - if a "fake" calculate (Rhombus, exclusion) then get the underlying expression (should not depend of Calcualte = true) [get_calculation_terms]
178
- - if a Select, manage it as a calculate too (should not depend of Calcualte = true) [get_calculation_terms]
179
- - else get the expression via [get_calculation_terms] [get_prev_node_expression , calculate = False] -> get_node_expression for the prev node
180
-
181
- # Running directly
182
-
183
- `tricc` is technically a python library, but you can run it directly via the [`build.py` script](./tests/build.py).
184
-
185
- ## Running with Docker
186
-
187
- Alternatively, if you prefer to build/run the project with Docker, you can do the following.
188
-
189
- Start by building the Docker image:
190
-
191
- ```shell
192
- git clone https://github.com/SwissTPH/tricc.git
193
- cd tricc
194
-
195
- docker build -t tricc .
196
- ```
197
-
198
- Once you have the image built you can use it to convert local `.drawio` files by mapping the local directory to the `docker run` command. (Note that `--user` is specified to make sure the current host user has write access to the output files.)
199
-
200
- ```shell
201
- docker run --rm -v "$PWD":/proj --user $(id -u):$(id -g) tricc --help
202
- ```
203
-
204
- This command will convert all `.drawio` files in the current directory:
205
-
206
- ```shell
207
- docker run --rm -v "$PWD":/proj --user $(id -u):$(id -g) tricc -i /proj -o /proj
208
- ```
209
-
210
- You can also convert a single file:
211
-
212
- ```shell
213
- docker run --rm -v "$PWD":/proj --user $(id -u):$(id -g) tricc -i /proj/demo.drawio -o /proj
214
- ```
215
-
216
- Use the `-O` flag to specify the output strategy. For example to generate CHT files:
217
-
218
- ```shell
219
- docker run --rm -v "$PWD":/proj --user $(id -u):$(id -g) tricc -i /proj -o /proj -O XLSFormCHTStrategy
220
- ```
@@ -0,0 +1,50 @@
1
+ tests/build.py,sha256=hyfl88bkNdqSqp9U5TKm6jpH6YdKMrCAB29Yr8ZONVk,6559
2
+ tests/test_cql.py,sha256=R6rLrkw4587vvR38XwI3XnuTTYI1ft1XNmBPCxyOif4,5252
3
+ tests/to_ocl.py,sha256=4e-i65K3UM6wHgdVcrZcM9AyL1bahIsXJiZTXhhHgQk,2048
4
+ tricc_oo/__init__.py,sha256=oWCE1ubmC_6iqaWOMgTei4eXVQgV202Ia-tXS1NnW_4,139
5
+ tricc_oo/converters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ tricc_oo/converters/codesystem_to_ocl.py,sha256=Fh7Vk73OsxljZKu1k6H9uzYwz334tpQTMZBjWWbamYE,6151
7
+ tricc_oo/converters/cql_to_operation.py,sha256=PUyV_YpUY98Ox0H_F_CN3UUf_I-BhFZVOcWWKTtwecM,14492
8
+ tricc_oo/converters/datadictionnary.py,sha256=T2HLCBo4Am1p0kFqSH1r0PqbD8AC2IGuWkbvMvSCru0,3658
9
+ tricc_oo/converters/drawio_type_map.py,sha256=UCPiGs7Lw0bigKScmZUnmOhACBz-FiDq92jHkI7RTSQ,9113
10
+ tricc_oo/converters/tricc_to_xls_form.py,sha256=NwBOBy_tuEWd6d0ig9XzIm84dGDmRj-bATPB_D7HcHQ,1999
11
+ tricc_oo/converters/utils.py,sha256=Lc9oOgkuiAHA95rb9s-RCbguhPfkinNcsuwQ1cxKvSc,1675
12
+ tricc_oo/converters/xml_to_tricc.py,sha256=cDoLTwIMHIqyyNqZGwQte9YdX4y5j1Ac6r7M-zuKWZc,39403
13
+ tricc_oo/converters/cql/cqlLexer.py,sha256=8HArbRphcrpnAG4uogJ2rHv4tc1WLzjN0B1uFeYILAc,49141
14
+ tricc_oo/converters/cql/cqlListener.py,sha256=fA7-8DcS2Q69ckwjdg57-OfFHBxjTZFdoSKrtw7Hffc,57538
15
+ tricc_oo/converters/cql/cqlParser.py,sha256=x3KdrwX9nwENSEJ5Ex7_l5NMnu3kWBO0uLdYu4moTq0,414745
16
+ tricc_oo/converters/cql/cqlVisitor.py,sha256=iHuup2S7OGSVWLEcI4H3oecRqgXztC1sKnew_1P2iGY,33880
17
+ tricc_oo/models/__init__.py,sha256=CgS52LLqdDIaXHvZy08hhu_VaYw80OEdfL_llM9ICBA,108
18
+ tricc_oo/models/base.py,sha256=4mkAYAfvtdnTiLpUrttqQgIgfw1q_GkEgbVDKP8Txno,25849
19
+ tricc_oo/models/calculate.py,sha256=uNP0IDUqPQcJq9Co05H8eX5wbR_DikSxuOHxfVE5Dxg,8018
20
+ tricc_oo/models/lang.py,sha256=ZMRwdoPWe01wEDhOM0uRk-6rt3BkoAAZM8mZ61--s3A,2265
21
+ tricc_oo/models/ocl.py,sha256=MybSeB6fgCOUVJ4aektff0vrrTZsyfwZ2Gt_pPBu_FY,8728
22
+ tricc_oo/models/ordered_set.py,sha256=BpXLW8plRAy4te25PIUPvVXPnLPcypvKg3iNPhtPulA,3833
23
+ tricc_oo/models/tricc.py,sha256=R7MtjoTJXc3gtL4sZmFdobcxaWfh4pdVyP_2g-3uMPs,17421
24
+ tricc_oo/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ tricc_oo/parsers/xml.py,sha256=uzkb1y18MHfqVFmZqVh0sKT4cx6u0-NcAT_lV_gHBt8,4208
26
+ tricc_oo/serializers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ tricc_oo/serializers/planuml.py,sha256=t57587-6L3aDncpHh58lS77Zft8yxDE9DPtXx2BeUSU,132
28
+ tricc_oo/serializers/xls_form.py,sha256=iPF-Is8EAGkgwi-I_1Opxr59KM1mhw0kihO9b2KY3U4,21750
29
+ tricc_oo/strategies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ tricc_oo/strategies/input/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ tricc_oo/strategies/input/base_input_strategy.py,sha256=BEODXS74na1QRRcJVQ4cxiD8F7uRqaLyhE3QzKpGVvk,3891
32
+ tricc_oo/strategies/input/drawio.py,sha256=uXAUPhXOeg0Uk_BNqlCqFBW4cWNox4VfH559bj1fhC0,12767
33
+ tricc_oo/strategies/output/base_output_strategy.py,sha256=M9UFR67-_CFoW681bPAeBS1OUGuFtmUbM_rltACI0hk,8798
34
+ tricc_oo/strategies/output/fhir_form.py,sha256=hbL921pe1Doun4IQrJuZ_Sq2fCh98G3grYie5olC4uc,15740
35
+ tricc_oo/strategies/output/html_form.py,sha256=qSleEZOMV_-Z04y-i-ucyd5rgAYWAyjPwMrw0IHtCRM,8604
36
+ tricc_oo/strategies/output/openmrs_form.py,sha256=I0K6hc-ffodnSPJQa3Dr6FbsRVlJw6EfbHge8GawC5U,27190
37
+ tricc_oo/strategies/output/spice.py,sha256=QMeoismVC3PdbvwTK0PtUjWX9jl9780fbQIXn76fMXw,10761
38
+ tricc_oo/strategies/output/xls_form.py,sha256=ofEg6oZlhEytfdLRRWqQKCaewDIKedZ-uVpQl9OiyYw,29787
39
+ tricc_oo/strategies/output/xlsform_cdss.py,sha256=X00Lt5MzV8TX14dR4dFI1MqllI5S1e13bKbeysWM9uA,17435
40
+ tricc_oo/strategies/output/xlsform_cht.py,sha256=jXrgUxs8aKiEE3o7ujABcFqPs12AHrG6HAtOsaNoXgA,22966
41
+ tricc_oo/strategies/output/xlsform_cht_hf.py,sha256=xm6SKirV3nMZvM2w54_zJcXAeAgAkq-EEqGEjnOWv6c,988
42
+ tricc_oo/visitors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
+ tricc_oo/visitors/tricc.py,sha256=Ndg5tnOH3JXYDSlxJwa2FgPVnPeJE4YWmOOFW-FcULQ,107105
44
+ tricc_oo/visitors/utils.py,sha256=j83aAq5s5atXi3OC0jc_uJd54a8XrHHmizeeEbWZQJg,421
45
+ tricc_oo/visitors/xform_pd.py,sha256=ryAnI3V9x3eTmJ2LNsUZfvl0_yfCqo6oBgeSu-WPqaE,9613
46
+ tricc_oo-1.5.24.dist-info/licenses/LICENSE,sha256=Pz2eACSxkhsGfW9_iN60pgy-enjnbGTj8df8O3ebnQQ,16726
47
+ tricc_oo-1.5.24.dist-info/METADATA,sha256=PWTak1ccZ0K_e4CZUOUgw51JHJ8gMQmr7cKiOwhqAys,8577
48
+ tricc_oo-1.5.24.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
49
+ tricc_oo-1.5.24.dist-info/top_level.txt,sha256=NvbfMNAiy9m4b1unBsqpeOQWh4IgA1Xa33BtKA4abxk,15
50
+ tricc_oo-1.5.24.dist-info/RECORD,,