tricc-oo 1.5.23__py3-none-any.whl → 1.5.25__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.
@@ -12,24 +12,24 @@ import pandas as pd
12
12
  from tricc_oo.converters.utils import clean_name
13
13
  from tricc_oo.models.base import (
14
14
  TriccOperator,
15
- TriccOperation, TriccStatic, TriccReference, TriccNodeType, or_join
15
+ TriccOperation, TriccStatic, TriccReference
16
16
  )
17
17
  from tricc_oo.models.ordered_set import OrderedSet
18
18
  from tricc_oo.models.calculate import (
19
19
  TriccNodeEnd,
20
20
  TriccNodeDisplayCalculateBase,
21
- TriccRhombusMixIn,
22
21
 
23
22
  )
24
23
  from tricc_oo.models.tricc import (
25
24
  TriccNodeCalculateBase,
26
25
  TriccNodeBaseModel,
27
- TriccNodeSelectMultiple,
28
26
  TriccNodeSelectOption,
29
27
  TriccNodeInputModel,
30
- TriccNodeDisplayModel
28
+ TriccNodeDisplayModel,
29
+ TRICC_FALSE_VALUE,
30
+ TRICC_TRUE_VALUE,
31
31
  )
32
- from tricc_oo.converters.tricc_to_xls_form import get_export_name
32
+ from tricc_oo.converters.tricc_to_xls_form import get_export_name, BOOLEAN_MAP
33
33
 
34
34
  from tricc_oo.models.lang import SingletonLangClass
35
35
 
@@ -39,9 +39,9 @@ from tricc_oo.visitors.tricc import (
39
39
  is_ready_to_process,
40
40
  process_reference,
41
41
  get_node_expressions,
42
- TRICC_TRUE_VALUE,
43
- TRICC_FALSE_VALUE,
44
42
  set_last_version_false,
43
+ generate_calculate,
44
+ generate_base,
45
45
  )
46
46
  from tricc_oo.serializers.xls_form import (
47
47
  CHOICE_MAP,
@@ -49,7 +49,6 @@ from tricc_oo.serializers.xls_form import (
49
49
  end_group,
50
50
  generate_xls_form_export,
51
51
  start_group,
52
- BOOLEAN_MAP,
53
52
  )
54
53
  from tricc_oo.strategies.output.base_output_strategy import BaseOutPutStrategy
55
54
 
@@ -104,13 +103,13 @@ class XLSFormStrategy(BaseOutPutStrategy):
104
103
  return str(expression)
105
104
 
106
105
  def generate_base(self, node, **kwargs):
107
- return self.generate_xls_form_condition(node, **kwargs)
106
+ return generate_base(node, **kwargs)
108
107
 
109
108
  def generate_relevance(self, node, **kwargs):
110
109
  return self.generate_xls_form_relevance(node, **kwargs)
111
110
 
112
111
  def generate_calculate(self, node, **kwargs):
113
- return self.generate_xls_form_calculate(node, **kwargs)
112
+ return generate_calculate(node, **kwargs)
114
113
 
115
114
  def __init__(self, project, output_path):
116
115
  super().__init__(project, output_path)
@@ -131,6 +130,31 @@ class XLSFormStrategy(BaseOutPutStrategy):
131
130
  def generate_export(self, node, **kwargs):
132
131
  return generate_xls_form_export(self, node, **kwargs)
133
132
 
133
+ def inject_version(self):
134
+ # Add hidden version field using ODK's jr:version()
135
+ empty = langs.get_trads("", force_dict=True)
136
+ self.df_survey.loc[len(self.df_survey)] = [
137
+ "hidden",
138
+ "version",
139
+ *list(empty.values()), # label
140
+ *list(empty.values()), # hint
141
+ *list(empty.values()), # help
142
+ "", # default
143
+ "hidden", # appearance
144
+ "", # constraint
145
+ *list(empty.values()), # constraint_message
146
+ "", # relevance
147
+ "", # disabled
148
+ "", # required
149
+ *list(empty.values()), # required_message
150
+ "", # read only
151
+ "jr:version()", # calculation
152
+ "", # trigger
153
+ "", # repeat_count
154
+ "", # image
155
+ "", # choice_filter
156
+ ]
157
+
134
158
  def export(self, start_pages, version):
135
159
  if start_pages["main"].root.form_id is not None:
136
160
  form_id = str(start_pages["main"].root.form_id)
@@ -158,10 +182,10 @@ class XLSFormStrategy(BaseOutPutStrategy):
158
182
  if not os.path.exists(self.output_path):
159
183
  os.makedirs(self.output_path)
160
184
 
185
+ self.inject_version()
186
+
161
187
  # create a Pandas Excel writer using XlsxWriter as the engine
162
188
  writer = pd.ExcelWriter(newpath, engine="xlsxwriter")
163
- if len(self.df_survey[self.df_survey["name"] == "version"]):
164
- self.df_survey.loc[self.df_survey["name"] == "version", "label"] = f"v{version}"
165
189
  self.df_survey.to_excel(writer, sheet_name="survey", index=False)
166
190
  self.df_choice.to_excel(writer, sheet_name="choices", index=False)
167
191
  df_settings.to_excel(writer, sheet_name="settings", index=False)
@@ -688,91 +712,30 @@ class XLSFormStrategy(BaseOutPutStrategy):
688
712
  return True
689
713
  return False
690
714
 
691
- # function update the select node in the XLSFORM format
692
- # @param left part
693
- # @param right part
694
- def generate_xls_form_condition(self, node, processed_nodes, stashed_nodes, calculates, **kwargs):
695
- if is_ready_to_process(node, processed_nodes, strict=False) and process_reference(
696
- node,
697
- processed_nodes,
698
- calculates,
699
- replace_reference=False,
700
- codesystems=kwargs.get("codesystems", None),
701
- ):
702
- if node not in processed_nodes:
703
- if issubclass(node.__class__, TriccRhombusMixIn) and isinstance(node.reference, str):
704
- logger.warning("node {} still using the reference string".format(node.get_name()))
705
- if issubclass(node.__class__, TriccNodeInputModel):
706
- # we don't overright if define in the diagram
707
- if node.constraint is None:
708
- if isinstance(node, TriccNodeSelectMultiple):
709
- node.constraint = or_join(
710
- [
711
- TriccOperation(
712
- TriccOperator.EQUAL,
713
- ["$this", TriccStatic("opt_none")],
714
- ),
715
- TriccOperation(
716
- TriccOperator.NOT,
717
- [
718
- TriccOperation(
719
- TriccOperator.SELECTED,
720
- ["$this", TriccStatic("opt_none")],
721
- )
722
- ],
723
- ),
724
- ]
725
- ) # '.=\'opt_none\' or not(selected(.,\'opt_none\'))'
726
- node.constraint_message = "**None** cannot be selected together with choice."
727
- elif node.tricc_type in (
728
- TriccNodeType.integer,
729
- TriccNodeType.decimal,
730
- ):
731
- constraints = []
732
- constraints_min = ""
733
- constraints_max = ""
734
- if node.min is not None and node.min != "":
735
- constraints.append(TriccOperation(TriccOperator.MORE_OR_EQUAL, ["$this", node.min]))
736
- constraints_min = "The minimun value is {0}.".format(node.min)
737
- if node.max is not None and node.max != "":
738
- constraints.append(TriccOperation(TriccOperator.LESS_OR_EQUAL, ["$this", node.max]))
739
- constraints_max = "The maximum value is {0}.".format(node.max)
740
- if len(constraints) > 1:
741
- node.constraint = TriccOperation(TriccOperator.AND, constraints)
742
- node.constraint_message = (constraints_min + " " + constraints_max).strip()
743
- elif len(constraints) == 1:
744
- node.constraint = constraints[0]
745
- node.constraint_message = (constraints_min + " " + constraints_max).strip()
746
- # continue walk
747
- return True
748
- return False
749
-
750
- # function transform an object to XLSFORM value
751
- # @param r reference to be translated
752
715
  def get_tricc_operation_operand(self, r, coalesce_fallback="''"):
716
+ # function transform an object to XLSFORM value
717
+ # @param r reference to be translated
753
718
  if isinstance(r, TriccOperation):
754
719
  return self.get_tricc_operation_expression(r)
755
720
  elif isinstance(r, TriccReference):
756
721
  logger.warning(f"reference `{r.value}` still used in a calculate")
757
722
  return f"${{{get_export_name(r.value)}}}"
758
723
  elif isinstance(r, TriccStatic):
759
- if isinstance(r.value, bool): # or r.value in ('true', 'false')
760
- return BOOLEAN_MAP[str(TRICC_TRUE_VALUE)] if r.value else BOOLEAN_MAP[str(TRICC_FALSE_VALUE)]
761
- if r.value == TRICC_TRUE_VALUE:
724
+ return get_export_name(r)
725
+ elif isinstance(r, str):
726
+ if r == TRICC_TRUE_VALUE:
762
727
  return BOOLEAN_MAP[str(TRICC_TRUE_VALUE)]
763
- if r.value == TRICC_FALSE_VALUE:
728
+ elif r == TRICC_FALSE_VALUE:
764
729
  return BOOLEAN_MAP[str(TRICC_FALSE_VALUE)]
765
- if isinstance(r.value, str):
766
- return f"'{r.value}'"
730
+ elif isinstance(r, str):
731
+ return f"'{r}'"
767
732
  else:
768
- return str(r.value)
769
- elif isinstance(r, str):
770
- return f"{r}"
733
+ return str(r)
771
734
  elif isinstance(r, (int, float)):
772
735
  return str(r)
773
736
  elif isinstance(r, TriccNodeSelectOption):
774
- logger.warning(f"select option {r.get_name()} from {r.select.get_name()} was used as a reference")
775
- return f"'{r.name}'"
737
+ logger.debug(f"select option {r.get_name()} from {r.select.get_name()} was used as a reference")
738
+ return get_export_name(r)
776
739
  elif issubclass(r.__class__, TriccNodeInputModel):
777
740
  return f"coalesce(${{{get_export_name(r)}}},{coalesce_fallback})"
778
741
  elif issubclass(r.__class__, TriccNodeBaseModel):
@@ -31,6 +31,8 @@ class XLSFormCHTStrategy(XLSFormCDSSStrategy):
31
31
 
32
32
  self.df_survey = pd.concat([cht_input_df, self.df_survey, self.get_cht_summary()], ignore_index=True)
33
33
 
34
+ self.inject_version()
35
+
34
36
  def get_cht_input(self, start_pages, **kwargs):
35
37
  empty = langs.get_trads("", force_dict=True)
36
38
  df_input = pd.DataFrame(columns=SURVEY_MAP.keys())
@@ -620,8 +622,6 @@ class XLSFormCHTStrategy(XLSFormCDSSStrategy):
620
622
  }
621
623
  df_settings = pd.DataFrame(settings, index=indx)
622
624
  df_settings.head()
623
- if len(self.df_survey[self.df_survey["name"] == "version"]):
624
- self.df_survey.loc[self.df_survey["name"] == "version", "label"] = f"v{version}"
625
625
  # create a Pandas Excel writer using XlsxWriter as the engine
626
626
  writer = pd.ExcelWriter(newpath, engine="xlsxwriter")
627
627
  self.df_survey.to_excel(writer, sheet_name="survey", index=False)
@@ -6,7 +6,7 @@ import base64
6
6
 
7
7
  from tricc_oo.converters.utils import generate_id
8
8
  from tricc_oo.models.base import (
9
- TriccBaseModel,
9
+ TriccBaseModel, TriccNodeType,
10
10
  TriccOperator, TriccOperation, TriccStatic, TriccReference, not_clean,
11
11
  and_join, or_join, clean_or_list, nand_join, TriccEdge
12
12
  )
@@ -34,6 +34,7 @@ from tricc_oo.models.calculate import (
34
34
  from tricc_oo.models.tricc import (
35
35
  TriccNodeCalculateBase, TriccNodeActivity, TriccNodeBaseModel, TriccNodeNumber,
36
36
  TriccNodeSelectMultiple,
37
+ TriccNodeSelectOne,
37
38
  TriccNodeSelectOption,
38
39
  TriccNodeSelectYesNo,
39
40
  TriccNodeInputModel,
@@ -43,6 +44,8 @@ from tricc_oo.models.tricc import (
43
44
  TriccNodeDisplayModel,
44
45
  TriccNodeMainStart,
45
46
  TriccNodeAcceptDiagnostic,
47
+ TRICC_FALSE_VALUE,
48
+ TRICC_TRUE_VALUE,
46
49
  )
47
50
  from tricc_oo.visitors.utils import PROCESSES
48
51
  from tricc_oo.converters.cql_to_operation import transform_cql_to_operation
@@ -52,9 +55,6 @@ from tricc_oo.converters.tricc_to_xls_form import get_list_names, get_export_nam
52
55
  logger = logging.getLogger("default")
53
56
  ONE_QUESTION_AT_A_TIME = False
54
57
 
55
- TRICC_TRUE_VALUE = "true"
56
- TRICC_FALSE_VALUE = "false"
57
-
58
58
 
59
59
  def merge_node(from_node, to_node):
60
60
  if from_node.activity != to_node.activity:
@@ -217,7 +217,7 @@ def merge_expression(expression, last_version):
217
217
  return expression
218
218
 
219
219
 
220
- def process_calculate(
220
+ def load_calculate(
221
221
  node, processed_nodes, stashed_nodes, calculates, used_calculates, warn=False, process=None, **kwargs
222
222
  ):
223
223
  # used_calculates dict[name, Dict[id, node]]
@@ -892,7 +892,7 @@ def add_used_calculate(node, prev_node, calculates, used_calculates, processed_n
892
892
  used_calculates[prev_node.name][max_version.id] = max_version
893
893
  else:
894
894
  logger.debug(
895
- "process_calculate_version_requirement: failed for {0} , prev Node {1} ".format(
895
+ "load_calculate_version_requirement: failed for {0} , prev Node {1} ".format(
896
896
  node.get_name(), prev_node.get_name()
897
897
  )
898
898
  )
@@ -2503,17 +2503,127 @@ def get_required_node_expression(node):
2503
2503
 
2504
2504
  # Get a selected option
2505
2505
  def get_selected_option_expression(option_node, negate):
2506
+ if isinstance(option_node.select, TriccNodeSelectOne):
2507
+ return get_selected_option_expression_single(option_node, negate)
2508
+ else:
2509
+ return get_selected_option_expression_multiple(option_node, negate)
2510
+
2511
+
2512
+ def get_selected_option_expression_single(option_node, negate):
2513
+
2514
+ if not negate:
2515
+ return TriccOperation(TriccOperator.EQUAL, [option_node.select, option_node])
2506
2516
 
2507
- selected = TriccOperation(TriccOperator.SELECTED, [option_node.select, TriccStatic(option_node.name)])
2517
+
2518
+ def get_selected_option_expression_multiple(option_node, negate):
2519
+
2520
+ selected = TriccOperation(TriccOperator.SELECTED, [option_node.select, option_node])
2508
2521
 
2509
2522
  if negate:
2510
2523
  return TriccOperation(
2511
2524
  operator=TriccOperator.AND,
2512
2525
  resource=[
2513
2526
  TriccOperation(operator=TriccOperator.NOT, resource=[selected]),
2514
- TriccOperation(operator=TriccOperator.NATIVE, resource=["count-selected", option_node.select]),
2527
+ TriccOperation(operator=TriccOperator.ISNOTNULL, resource=[option_node.select]),
2515
2528
  ],
2516
2529
  )
2517
2530
 
2518
2531
  else:
2519
2532
  return selected
2533
+
2534
+
2535
+ def generate_calculate(node, processed_nodes, **kwargs):
2536
+ # For calculations, set calculate in questionOptions
2537
+ # Check if node is ready to be processed (similar to XLS form strategy)
2538
+ if not is_ready_to_process(node, processed_nodes, strict=True):
2539
+ return False
2540
+
2541
+ # Process references to ensure dependencies are handled
2542
+ if not process_reference(
2543
+ node, processed_nodes, {}, replace_reference=True, codesystems=kwargs.get("codesystems", None)
2544
+ ):
2545
+ return False
2546
+
2547
+ if node not in processed_nodes:
2548
+ if kwargs.get("warn", True):
2549
+ logger.debug("generation of calculate for node {}".format(node.get_name()))
2550
+ if (
2551
+ hasattr(node, "expression")
2552
+ and (node.expression is None)
2553
+ and issubclass(node.__class__, TriccNodeCalculateBase)
2554
+ ):
2555
+ node.expression = get_node_expressions(
2556
+ node, processed_nodes, process=kwargs.get("process", "main ")
2557
+ )
2558
+ # continue walk
2559
+ if issubclass(
2560
+ node.__class__,
2561
+ (
2562
+ TriccNodeDisplayModel,
2563
+ TriccNodeDisplayCalculateBase,
2564
+ TriccNodeEnd,
2565
+ ),
2566
+ ):
2567
+ set_last_version_false(node, processed_nodes)
2568
+ return True
2569
+
2570
+
2571
+ def generate_base(node, processed_nodes, **kwargs):
2572
+ # Generate question for OpenMRS O3 schema
2573
+ # Handle activity nodes by processing their inner content
2574
+ # Check if node is ready to be processed (similar to XLS form strategy)
2575
+ if not is_ready_to_process(node, processed_nodes, strict=False):
2576
+ return False
2577
+
2578
+ # Process references to ensure dependencies are handled
2579
+ if not process_reference(
2580
+ node, processed_nodes, {}, replace_reference=False, codesystems=kwargs.get("codesystems", None)
2581
+ ):
2582
+ return False
2583
+ if node not in processed_nodes:
2584
+ if issubclass(node.__class__, TriccRhombusMixIn) and isinstance(node.reference, str):
2585
+ logger.warning("node {} still using the reference string".format(node.get_name()))
2586
+ if issubclass(node.__class__, TriccNodeInputModel):
2587
+ # we don't overright if define in the diagram
2588
+ if node.constraint is None:
2589
+ if isinstance(node, TriccNodeSelectMultiple):
2590
+ node.constraint = or_join(
2591
+ [
2592
+ TriccOperation(
2593
+ TriccOperator.EQUAL,
2594
+ ["$this", TriccStatic("opt_none")],
2595
+ ),
2596
+ TriccOperation(
2597
+ TriccOperator.NOT,
2598
+ [
2599
+ TriccOperation(
2600
+ TriccOperator.SELECTED,
2601
+ ["$this", TriccStatic("opt_none")],
2602
+ )
2603
+ ],
2604
+ ),
2605
+ ]
2606
+ ) # '.=\'opt_none\' or not(selected(.,\'opt_none\'))'
2607
+ node.constraint_message = "**None** cannot be selected together with choice."
2608
+ elif node.tricc_type in (
2609
+ TriccNodeType.integer,
2610
+ TriccNodeType.decimal,
2611
+ ):
2612
+ constraints = []
2613
+ constraints_min = ""
2614
+ constraints_max = ""
2615
+ if node.min is not None and node.min != "":
2616
+ constraints.append(TriccOperation(TriccOperator.MORE_OR_EQUAL, ["$this", node.min]))
2617
+ constraints_min = "The minimun value is {0}.".format(node.min)
2618
+ if node.max is not None and node.max != "":
2619
+ constraints.append(TriccOperation(TriccOperator.LESS_OR_EQUAL, ["$this", node.max]))
2620
+ constraints_max = "The maximum value is {0}.".format(node.max)
2621
+ if len(constraints) > 1:
2622
+ node.constraint = TriccOperation(TriccOperator.AND, constraints)
2623
+ node.constraint_message = (constraints_min + " " + constraints_max).strip()
2624
+ elif len(constraints) == 1:
2625
+ node.constraint = constraints[0]
2626
+ node.constraint_message = (constraints_min + " " + constraints_max).strip()
2627
+ # continue walk
2628
+ return True
2629
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tricc-oo
3
- Version: 1.5.23
3
+ Version: 1.5.25
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
@@ -26,7 +26,130 @@ Requires-Dist: beautifulsoup4
26
26
  Requires-Dist: ocldev
27
27
  Dynamic: license-file
28
28
 
29
- # 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
+ ```
30
153
 
31
154
  ## Nodes
32
155
 
@@ -133,90 +256,8 @@ if not a calculate then relevance will be used unless it is "required" then cond
133
256
  the Rhombus act as an AND between its imputs and its reference BUT it is an OR beween the inputs
134
257
  (input1 OR input2 OR input3) AND reference
135
258
 
136
- ## start nodes
137
-
138
- ### Main start
139
-
140
- 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
141
-
142
- here is the list of the CPG process, this will be the execution oder too:
143
- - **registration**,
144
- - **triage**,
145
- - **emergency-care**,
146
- - **local-urgent-care**,
147
- - **actue-tertiary-care**,
148
- - **history-and-physical**,
149
- - **diagnostic-testing**,
150
- - **determine-diagnosis**,
151
- - **provide-counseling**,
152
- - **dispense-medications**,
153
- - **monitor-and-follow-up-of-patient**,
154
- - **alerts-reminders-education**,
155
- - **discharge-referral-of-patient**,
156
- - **charge-for-service**,
157
- - **record-and-report**
158
-
159
-
160
259
  # READ Xressource
161
260
  https://jgraph.github.io/drawio-tools/tools/convert.html
162
261
 
163
262
  option can have only incoming edge from images to be placed as option$
164
263
 
165
-
166
- # Note
167
-
168
- ## generation of the expressions
169
-
170
- ### add calcualte:
171
-
172
- - Non or No in an egde will generate a negate node
173
- - save adds a calcualte
174
- - 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])
175
-
176
- ### for calculate
177
-
178
- Then we calculate based on the previous nodes: [get_prev_node_expression]
179
- - if a "fake" calculate (Rhombus, exclusion) then get the underlying expression (should not depend of Calcualte = true) [get_calculation_terms]
180
- - if a Select, manage it as a calculate too (should not depend of Calcualte = true) [get_calculation_terms]
181
- - else get the expression via [get_calculation_terms] [get_prev_node_expression , calculate = False] -> get_node_expression for the prev node
182
-
183
- # Running directly
184
-
185
- `tricc` is technically a python library, but you can run it directly via the [`build.py` script](./tests/build.py).
186
-
187
- ## Running with Docker
188
-
189
- Alternatively, if you prefer to build/run the project with Docker, you can do the following.
190
-
191
- Start by building the Docker image:
192
-
193
- ```shell
194
- git clone https://github.com/SwissTPH/tricc.git
195
- cd tricc
196
-
197
- docker build -t tricc .
198
- ```
199
-
200
- 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.)
201
-
202
- ```shell
203
- docker run --rm -v "$PWD":/proj --user $(id -u):$(id -g) tricc --help
204
- ```
205
-
206
- This command will convert all `.drawio` files in the current directory:
207
-
208
- ```shell
209
- docker run --rm -v "$PWD":/proj --user $(id -u):$(id -g) tricc -i /proj -o /proj
210
- ```
211
-
212
- You can also convert a single file:
213
-
214
- ```shell
215
- docker run --rm -v "$PWD":/proj --user $(id -u):$(id -g) tricc -i /proj/demo.drawio -o /proj
216
- ```
217
-
218
- Use the `-O` flag to specify the output strategy. For example to generate CHT files:
219
-
220
- ```shell
221
- docker run --rm -v "$PWD":/proj --user $(id -u):$(id -g) tricc -i /proj -o /proj -O XLSFormCHTStrategy
222
- ```