Warning, /swf-testbed/example_agents/daq_workflow_example.smk is written in an unsupported language. File is not indexed.
0001 # EXAMPLE ONLY - NOT USED BY TESTBED
0002 # ====================================
0003 # This Snakemake file demonstrates how a DAQ workflow could be expressed in Snakemake format.
0004 # However, the actual testbed uses SimPy directly for DAQ simulation (see daq_simulator.py).
0005 #
0006 # We explored using Snakemake but decided that SimPy provides better discrete event simulation
0007 # capabilities without requiring a complex Snakemake-to-SimPy translator.
0008 #
0009 # Original description:
0010 # DAQ State Machine Workflow
0011 # This simulates ePIC DAQ state transitions with programmatic STF generation
0012
0013 # Configuration
0014 RUN_NUMBER = "100001"
0015 STF_INTERVAL_SECONDS = 30 # STFs generated every 30 seconds during run/physics
0016
0017 # State 1: no_beam / not_ready (starting state)
0018 rule initial_state:
0019 output:
0020 state="daq_states/01_no_beam_not_ready.json"
0021 params:
0022 duration_minutes=5,
0023 state="no_beam",
0024 substate="not_ready"
0025 shell:
0026 """
0027 echo "DAQ State: no_beam/not_ready - Collider not operating"
0028 mkdir -p daq_states
0029 cat > {output.state} << EOF
0030 {{
0031 "state": "{params.state}",
0032 "substate": "{params.substate}",
0033 "timestamp": "$(date -Iseconds)",
0034 "duration_minutes": {params.duration_minutes},
0035 "description": "Collider not operating"
0036 }}
0037 EOF
0038 sleep 2 # Brief pause for simulation
0039 """
0040
0041 # State 2: beam / not_ready
0042 rule beam_not_ready:
0043 input:
0044 prev_state="daq_states/01_no_beam_not_ready.json"
0045 output:
0046 state="daq_states/02_beam_not_ready.json",
0047 run_imminent="daq_events/run_{run}_imminent.json".format(run=RUN_NUMBER)
0048 params:
0049 duration_minutes=5,
0050 state="beam",
0051 substate="not_ready",
0052 run_number=RUN_NUMBER
0053 shell:
0054 """
0055 echo "DAQ State: beam/not_ready - Beam on, run start imminent"
0056 mkdir -p daq_events
0057
0058 cat > {output.state} << EOF
0059 {{
0060 "state": "{params.state}",
0061 "substate": "{params.substate}",
0062 "timestamp": "$(date -Iseconds)",
0063 "duration_minutes": {params.duration_minutes},
0064 "description": "Beam operating, detector not ready"
0065 }}
0066 EOF
0067
0068 # Broadcast run imminent message
0069 cat > {output.run_imminent} << EOF
0070 {{
0071 "msg_type": "run_imminent",
0072 "run_id": "{params.run_number}",
0073 "timestamp": "$(date -Iseconds)",
0074 "run_conditions": {{
0075 "beam_energy": "5 GeV",
0076 "magnetic_field": "1.5T",
0077 "detector_config": "physics",
0078 "bunch_structure": "216x216"
0079 }}
0080 }}
0081 EOF
0082 sleep 2
0083 """
0084
0085 # State 3: beam / ready
0086 rule beam_ready:
0087 input:
0088 prev_state="daq_states/02_beam_not_ready.json"
0089 output:
0090 state="daq_states/03_beam_ready.json"
0091 params:
0092 duration_minutes=1,
0093 state="beam",
0094 substate="ready"
0095 shell:
0096 """
0097 echo "DAQ State: beam/ready - Ready for physics declaration"
0098 cat > {output.state} << EOF
0099 {{
0100 "state": "{params.state}",
0101 "substate": "{params.substate}",
0102 "timestamp": "$(date -Iseconds)",
0103 "duration_minutes": {params.duration_minutes},
0104 "description": "Collider and detector ready, awaiting physics declaration"
0105 }}
0106 EOF
0107 sleep 2
0108 """
0109
0110 # State 4: run / physics (first period) - triggers run start + STF generation
0111 rule run_physics_1:
0112 input:
0113 prev_state="daq_states/03_beam_ready.json"
0114 output:
0115 state="daq_states/04_run_physics_1.json",
0116 run_start="daq_events/run_{run}_start.json".format(run=RUN_NUMBER),
0117 stf_trigger="daq_triggers/physics_period_1.trigger"
0118 params:
0119 duration_minutes=5,
0120 state="run",
0121 substate="physics",
0122 run_number=RUN_NUMBER,
0123 stf_interval=STF_INTERVAL_SECONDS
0124 shell:
0125 """
0126 echo "DAQ State: run/physics (period 1) - Physics datataking active"
0127 mkdir -p daq_triggers
0128
0129 cat > {output.state} << EOF
0130 {{
0131 "state": "{params.state}",
0132 "substate": "{params.substate}",
0133 "timestamp": "$(date -Iseconds)",
0134 "duration_minutes": {params.duration_minutes},
0135 "description": "Physics datataking period 1",
0136 "stf_generation": true,
0137 "stf_interval_seconds": {params.stf_interval}
0138 }}
0139 EOF
0140
0141 # Broadcast run start
0142 cat > {output.run_start} << EOF
0143 {{
0144 "msg_type": "start_run",
0145 "run_id": "{params.run_number}",
0146 "timestamp": "$(date -Iseconds)",
0147 "state": "{params.state}",
0148 "substate": "{params.substate}"
0149 }}
0150 EOF
0151
0152 # Create trigger for programmatic STF generation (SimPy will use this)
0153 cat > {output.stf_trigger} << EOF
0154 {{
0155 "run_id": "{params.run_number}",
0156 "physics_period": 1,
0157 "start_time": "$(date -Iseconds)",
0158 "duration_minutes": {params.duration_minutes},
0159 "stf_interval_seconds": {params.stf_interval},
0160 "state": "{params.state}",
0161 "substate": "{params.substate}"
0162 }}
0163 EOF
0164 sleep 2
0165 """
0166
0167 # State 5: run / standby
0168 rule run_standby:
0169 input:
0170 prev_state="daq_states/04_run_physics_1.json"
0171 output:
0172 state="daq_states/05_run_standby.json"
0173 params:
0174 duration_seconds=30,
0175 state="run",
0176 substate="standby"
0177 shell:
0178 """
0179 echo "DAQ State: run/standby - Brief standby period"
0180 cat > {output.state} << EOF
0181 {{
0182 "state": "{params.state}",
0183 "substate": "{params.substate}",
0184 "timestamp": "$(date -Iseconds)",
0185 "duration_seconds": {params.duration_seconds},
0186 "description": "Brief standby, no STF generation"
0187 }}
0188 EOF
0189 sleep 2
0190 """
0191
0192 # State 6: run / physics (second period)
0193 rule run_physics_2:
0194 input:
0195 prev_state="daq_states/05_run_standby.json"
0196 output:
0197 state="daq_states/06_run_physics_2.json",
0198 stf_trigger="daq_triggers/physics_period_2.trigger"
0199 params:
0200 duration_minutes=3, # Shorter second period
0201 state="run",
0202 substate="physics",
0203 run_number=RUN_NUMBER,
0204 stf_interval=STF_INTERVAL_SECONDS
0205 shell:
0206 """
0207 echo "DAQ State: run/physics (period 2) - Physics datataking resumed"
0208 cat > {output.state} << EOF
0209 {{
0210 "state": "{params.state}",
0211 "substate": "{params.substate}",
0212 "timestamp": "$(date -Iseconds)",
0213 "duration_minutes": {params.duration_minutes},
0214 "description": "Physics datataking period 2",
0215 "stf_generation": true,
0216 "stf_interval_seconds": {params.stf_interval}
0217 }}
0218 EOF
0219
0220 # Create trigger for second physics period STF generation
0221 cat > {output.stf_trigger} << EOF
0222 {{
0223 "run_id": "{params.run_number}",
0224 "physics_period": 2,
0225 "start_time": "$(date -Iseconds)",
0226 "duration_minutes": {params.duration_minutes},
0227 "stf_interval_seconds": {params.stf_interval},
0228 "state": "{params.state}",
0229 "substate": "{params.substate}"
0230 }}
0231 EOF
0232 sleep 2
0233 """
0234
0235 # State 7: beam / not_ready (run ended)
0236 rule beam_not_ready_end:
0237 input:
0238 prev_state="daq_states/06_run_physics_2.json"
0239 output:
0240 state="daq_states/07_beam_not_ready_end.json",
0241 run_end="daq_events/run_{run}_end.json".format(run=RUN_NUMBER)
0242 params:
0243 duration_minutes=3,
0244 state="beam",
0245 substate="not_ready",
0246 run_number=RUN_NUMBER
0247 shell:
0248 """
0249 echo "DAQ State: beam/not_ready - Run ended, shifters stopped datataking"
0250 cat > {output.state} << EOF
0251 {{
0252 "state": "{params.state}",
0253 "substate": "{params.substate}",
0254 "timestamp": "$(date -Iseconds)",
0255 "duration_minutes": {params.duration_minutes},
0256 "description": "Run ended by shifters"
0257 }}
0258 EOF
0259
0260 # Broadcast run end
0261 cat > {output.run_end} << EOF
0262 {{
0263 "msg_type": "end_run",
0264 "run_id": "{params.run_number}",
0265 "timestamp": "$(date -Iseconds)",
0266 "total_physics_periods": 2
0267 }}
0268 EOF
0269 sleep 2
0270 """
0271
0272 # State 8: no_beam / not_ready (final state)
0273 rule final_state:
0274 input:
0275 prev_state="daq_states/07_beam_not_ready_end.json"
0276 output:
0277 state="daq_states/08_no_beam_not_ready_final.json"
0278 params:
0279 state="no_beam",
0280 substate="not_ready"
0281 shell:
0282 """
0283 echo "DAQ State: no_beam/not_ready - Collider shutdown, cycle complete"
0284 cat > {output.state} << EOF
0285 {{
0286 "state": "{params.state}",
0287 "substate": "{params.substate}",
0288 "timestamp": "$(date -Iseconds)",
0289 "description": "Collider not operating, DAQ cycle complete"
0290 }}
0291 EOF
0292 """
0293
0294 # Complete realistic DAQ cycle
0295 rule all:
0296 input:
0297 "daq_states/08_no_beam_not_ready_final.json"