-
Notifications
You must be signed in to change notification settings - Fork 0
/
templates.py
367 lines (310 loc) · 11.9 KB
/
templates.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
#!/usr/bin/env python3
def remove_indentation(multiline_string):
"""
Remove all leading whitespace (spaces and tabs) from each line in a multiline string.
Args:
multiline_string (str): A multiline string with potential leading whitespace.
Returns:
str: The multiline string with leading whitespace removed from each line.
"""
return '\n'.join(line.lstrip() for line in multiline_string.split('\n'))
bash_template_1 = remove_indentation('''#!/bin/bash
#nCladding : {nCladding}
#nCore : {nCore}
#coreRadius : {coreRadius}
#free_wavelength : {wavelength} um
#nBetween : {nBetween}
#numModes : {numModes}
#MEEP_resolution : {MEEP_resolution}
#variant of : {variant_of}
cd {wavesight_dir}
echo "{nCladding},{nCore},{coreRadius},{wavelength},{nBetween},{numModes},{MEEP_resolution},{waveguide_id}" >> sim_log.txt
# Check if this is based on a master waveguide
if ! {master_shortcut}
then
# Check if the memory and time requirements have been already calculated
if [[ -f "{waveguide_dir}/{waveguide_id}.req" ]]
then
echo "Requirements have already been estimated ..."
config_job_id=1
else
echo "Requirements have not been determined, submitting a job for this purpose ..."
# Submit the first array job
sbatch_output=$(sbatch <<EOL
#!/bin/bash
#SBATCH -n {MEEP_num_cores}
#SBATCH --job-name=req_run_{waveguide_id}
#SBATCH --mem={req_run_mem_in_GB}GB
#SBATCH -t {req_run_time_in_hours}:00:00
#SBATCH -o "{waveguide_dir}/{waveguide_id}-req.out"
#SBATCH -e "{waveguide_dir}/{waveguide_id}-req.err"
cd {wavesight_dir}
{python_bin_MEEP} {code_dir}fiber_platform.py --waveguide_sol "waveguide_sol-{waveguide_id}.pkl" --num_time_slices {num_time_slices} --mode_idx 0 --sim_time 0
EOL
)
# get the job id
config_job_id=$(echo "$sbatch_output" | awk '{{print $NF}}')
fi
if [ "$config_job_id" -eq 1 ]
then
#submit the axiliary job with no dependency
echo "Submitting the array job with no dependency ..."
sbatch <<EOL
#!/bin/bash
#SBATCH -n 1
#SBATCH --job-name=buddy_job_{waveguide_id}
#SBATCH --mem=1GB
#SBATCH -t 00:10:00
#SBATCH -o "{waveguide_dir}/{waveguide_id}-buddy.out"
#SBATCH -e "{waveguide_dir}/{waveguide_id}-buddy.err"
cd "{waveguide_dir}"
bash {waveguide_id}-2.sh
EOL
else
#submit the axiliary job with dependency
echo "Submitting the array job with dependency on config job ..."
sbatch --dependency=afterany:$config_job_id <<EOL
#!/bin/bash
#SBATCH -n 1
#SBATCH --job-name=buddy_job_{waveguide_id}
#SBATCH --mem=1GB
#SBATCH -t 00:10:00
#SBATCH -o "{waveguide_dir}/{waveguide_id}-buddy.out"
#SBATCH -e "{waveguide_dir}/{waveguide_id}-buddy.err"
cd {wavesight_dir}
bash {waveguide_id}-2.sh
EOL
fi
else
echo "this is based on an already solved waveguide, no need to submit jobs for mode launching"
cd {wavesight_dir}
bash {waveguide_id}-2.sh
fi
##############################################
''')
bash_template_2 = remove_indentation('''#!/bin/bash
#nCladding : {nCladding}
#nCore : {nCore}
#coreRadius : {coreRadius}
#free_wavelength : {wavelength} um
#nBetween : {nBetween}
#numModes : {numModes}
#MEEP_resolution : {MEEP_resolution}
#variant of : {variant_of}
cd {wavesight_dir}
# Check if the memory and time requirements have been already calculated
if [[ -f "{waveguide_dir}/{waveguide_id}.req" ]]
then
echo "Reading resource requirements ..."
IFS=',' read -r memreq timereq diskreq simtime memreq2 timereq2 < "{waveguide_dir}/{waveguide_id}.req"
else
echo "Requirements have not been determined."
exit 1
fi
echo "sbatch resources: ${{memreq}}GB,${{timereq}},${{diskreq}}MB,${{memreq2}}GB,${{timereq2}}"
# Check if this is based on a master waveguide
if ! {master_shortcut}
then
# Submit the first array job
sbatch_output=$(sbatch <<EOL
#!/bin/bash
#SBATCH -n {MEEP_num_cores}
#SBATCH --job-name=fiber_platform_{waveguide_id}
#SBATCH --mem=${{memreq}}GB
#SBATCH -t ${{timereq}}
#SBATCH --array=1-{num_modes}
#SBATCH -o "{waveguide_dir}/{waveguide_id}-%a.out"
#SBATCH -e "{waveguide_dir}/{waveguide_id}-%a.err"
cd {wavesight_dir}
{python_bin_MEEP} {code_dir}fiber_platform.py --waveguide_sol "waveguide_sol-{waveguide_id}.pkl" --num_time_slices 0 --mode_idx \$SLURM_ARRAY_TASK_ID --sim_time ${{simtime}}
EOL
)
fi
# Check if this is based on a master waveguide
if ! {master_shortcut}
then
# get the job id
array_job_id=$(echo "$sbatch_output" | awk '{{print $NF}}')
#submit the analysis job
sbatch_output_plotter=$(sbatch --dependency=afterany:$array_job_id <<EOL
#!/bin/bash
#SBATCH -n 1
#SBATCH --job-name=fiber_plotter_{waveguide_id}
#SBATCH --mem=${{memreq}}GB
#SBATCH -t ${{timereq}}
#SBATCH -o "{waveguide_dir}/{waveguide_id}-plotter.out"
#SBATCH -e "{waveguide_dir}/{waveguide_id}-plotter.err"
cd {wavesight_dir}
{python_bin} {code_dir}fiber_plotter.py {waveguide_id}
EOL
)
fi
if ! {master_shortcut}
then
# get the job id
plotter_job_id=$(echo "$sbatch_output_plotter" | awk '{{print $NF}}')
# submit the propagator job
sbatch_output_bridge=$(sbatch --dependency=afterany:$plotter_job_id <<EOL
#!/bin/bash
#SBATCH -n 1
#SBATCH --job-name=fiber_bridge_{waveguide_id}
#SBATCH --mem=${{memreq}}GB
#SBATCH -t ${{timereq}}
#SBATCH -o "{waveguide_dir}/{waveguide_id}-bridge.out"
#SBATCH -e "{waveguide_dir}/{waveguide_id}-bridge.err"
cd {wavesight_dir}
{python_bin} {code_dir}fiber_bridge.py {waveguide_id} {EH2_to_EH3} {nProp}
EOL
)
fi
bridge_job_id=$(echo "$sbatch_output_bridge" | awk '{{print $NF}}')
# once the fields have been propagated across the gap, propagate them across the metalens
if ! {master_shortcut}
then
sbatch_output=$(sbatch --dependency=afterany:$bridge_job_id <<EOL
#!/bin/bash
#SBATCH -n {MEEP_num_cores}
#SBATCH --job-name=across_ML_{waveguide_id}
#SBATCH --mem=${{memreq2}}GB
#SBATCH -t ${{timereq2}}
#SBATCH --array=0-{num_modes}
#SBATCH -o "{waveguide_dir}/{waveguide_id}-acrossML-%a.out"
#SBATCH -e "{waveguide_dir}/{waveguide_id}-acrossML-%a.err"
cd {wavesight_dir}
{python_bin_MEEP} {code_dir}across_ml.py {waveguide_id} \$SLURM_ARRAY_TASK_ID
EOL
)
else
sbatch_output=$(sbatch <<EOL
#!/bin/bash
#SBATCH -n {MEEP_num_cores}
#SBATCH --job-name=across_ML_{waveguide_id}
#SBATCH --mem=${{memreq2}}GB
#SBATCH -t ${{timereq2}}
#SBATCH --array=0-{num_modes}
#SBATCH -o "{waveguide_dir}/{waveguide_id}-acrossML-%a.out"
#SBATCH -e "{waveguide_dir}/{waveguide_id}-acrossML-%a.err"
cd {wavesight_dir}
{python_bin_MEEP} {code_dir}across_ml.py {waveguide_id} \$SLURM_ARRAY_TASK_ID
EOL
)
fi
# get the job id
across_job_id=$(echo "$sbatch_output" | awk '{{print $NF}}')
# once the field have been propagated across the metalens, make plots, and propagate them to the final volume
sbatch_output_h4_plot=$(sbatch --dependency=afterany:$across_job_id <<EOL
#!/bin/bash
#SBATCH -n 1
#SBATCH --job-name=EH4-plotter_{waveguide_id}
#SBATCH --mem=8GB
#SBATCH --time=01:00:00
#SBATCH -o "{waveguide_dir}/{waveguide_id}-EH4-plotter.out"
#SBATCH -e "{waveguide_dir}/{waveguide_id}-EH4-plotter.err"
cd {wavesight_dir}
{python_bin} {code_dir}EH4_plotter.py {waveguide_id}
EOL
)
sbatch_output=$(sbatch --dependency=afterany:$across_job_id <<EOL
#!/bin/bash
#SBATCH -n 1
#SBATCH --job-name=EH4_to_EH5_{waveguide_id}
#SBATCH --mem=${{memreq2}}GB
#SBATCH --time=01:00:00
#SBATCH --array=0-4
#SBATCH -o "{waveguide_dir}/{waveguide_id}-EH4_to_EH5-%a.out"
#SBATCH -e "{waveguide_dir}/{waveguide_id}-EH4_to_EH5-%a.err"
cd {wavesight_dir}
{python_bin} {code_dir}EH4_to_EH5.py --waveguide_id {waveguide_id} --zPropindex \$SLURM_ARRAY_TASK_ID
EOL
)
# get the job id
eh4_to_eh5_id=$(echo "$sbatch_output" | awk '{{print $NF}}')
# put the EH5 fields together
sbatch_output=$(sbatch --dependency=afterany:$eh4_to_eh5_id <<EOL
#!/bin/bash
#SBATCH -n 4
#SBATCH --job-name=h5_assembler_{waveguide_id}
#SBATCH --mem=2GB
#SBATCH --output="{waveguide_dir}/{waveguide_id}-h5_assembler.out"
#SBATCH --error="{waveguide_dir}/{waveguide_id}-h5_assembler.err"
#SBATCH --time=00:20:00
cd {wavesight_dir}
{python_bin} {code_dir}EH5_assembly.py {waveguide_id}
EOL
)
h5_assembler_id=$(echo "$sbatch_output" | awk '{{print $NF}}')
# submit the housekeeping job
sbatch --dependency=afterany:$h5_assembler_id <<EOL
#!/bin/bash
#SBATCH --job-name=housekeeping_{waveguide_id}
#SBATCH --output="{waveguide_dir}/{waveguide_id}-housekeeping.out"
#SBATCH --error="{waveguide_dir}/housekeeping.err"
#SBATCH --time=00:01:00
cd {wavesight_dir}
{python_bin} {code_dir}housekeeping.py {waveguide_id}
EOL
''')
config_file = '''{
// The location of the python binary
"python_bin": "~/anaconda/pameep/bin/python",
// Directory where the code is located
"code_dir": "/users/jlizaraz/CEM/wavesight/",
// Whether to use parallel MEEP
"parallel_MEEP": true,
// depth of emitter in crystal host
"emDepth": 25,
// these two following parameters determine the size of the box where Eh5 is calculated
// uncertainty in depth
"emDepth_Δz": 1.6,
// transverse uncertainty in position
"emDepth_Δxy": 1.5,
// if zmin is not provided here, then it is calculated from emDepth and emDepth_Δz
// if zmin is provided here, then zmax also need to be provided
// and these two together then determine the axial range of the box where Eh5 is calculated
// both zmin and zmax assume a coordinate system where the origin is at
// the base of the pillars that create the metasurface
"zmin": 24,
"zmax": 32,
// similarly xymin and xymax determine the transverse range of the box where Eh5 is calculated
// if provided they override the values that are calculated from emDepth_Δxy
"xymin": -3.0,
"xymax": 3.0,
// refractive index of crystal host
"nHost": 2.41,
// free-space wavelength of monochromatic field
"λFree": 0.532,
// ref index space between waveguide and ML
"nBetween": 1.0,
// waveguide parameters
// the radius of the waveguide core
"coreRadius": 2.0,
// ref index of core
"nCore": 1.4607,
// ref index of cladding
"nCladding": 1.4573,
// number of pixels per um
"MEEP_resolution": 20,
// params for metasurface design
// metalens aperture
"mlDiameter": 8.0,
// the height of the cylindrical posts for ML
"post_height":0.8,
// lattice constant of hexagonal lattice
"lattice_const": 0.25,
// number of basis vectors for RCWA
"numG" : 70,
// this is how many post widths are considered for the phase/geometry calculation
"num_post_widths": 30,
// the direction of the linear polarization of the incident field
"linear_polarization_direction": 0.0,
// the minimum diameter of ML cylindrical posts
"MIN_FEATURE_SIZE": 0.05,
// This controls if the launching simulations are automatically scheduled
"autorun": true,
// The amount of memory alloted for the requirement run
"req_run_mem_in_GB": 64,
// Whether to post the progress to Slack
"send_to_slack": true,
"slack_channel": "nvs_and_metalenses",
"show_plot": false
}'''