Support for creating high altitude noctilucent clouds in Advanced Weather/ALS
[fg:toms-fgdata.git] / Nasal / local_weather / weather_tiles.nas
1
2 ########################################################
3 # routines to set up weather tiles
4 # Thorsten Renk, June 2011
5 ########################################################
6
7 # function                      purpose
8 #
9 # tile_start                    to execute jobs common for all tiles on startup
10 # tile_finished                 to execute jobs common for all tiles when tile creation is done
11 # set_NN_tile                   to set a weather tile of type NN
12 # create_NN                     to create the cloud configuration NN
13 # adjust_p                      to make sure pressure variation cannot exceed limits between tiles
14 # calc_geo                      to get local Cartesian geometry for latitude conversion
15 # get_lat                       to get latitude from Cartesian coordinates
16 # get_lon                       to get longitude from Cartesian coordinates
17
18 ####################################
19 # tile setup calls
20 ####################################
21
22 var tile_start = func {
23
24 # set thread lock
25 if (local_weather.thread_flag == 1){setprop(lw~"tmp/thread-status","computing");}
26
27 # set the tile code
28 var current_code = getprop(lw~"tiles/code");
29 var dir_index = getprop(lw~"tiles/tmp/dir-index");      
30 props.globals.getNode(lw~"tiles").getChild("tile",dir_index).getNode("code").setValue(current_code);
31
32 #print(current_code, getprop(lw~"tiles/tmp/code"));
33
34 if (current_code != getprop(lw~"tiles/tmp/code"))
35         {weather_tiles.rnd_store = rand();}
36
37 # generate a handling array for models
38
39 var array = [];
40 append(weather_tile_management.modelArrays,array);
41
42
43 }
44
45 var tile_finished = func {
46
47 var current_code = getprop(lw~"tiles/code");
48
49 setprop(lw~"clouds/placement-index",0);
50 setsize(elat,0); setsize(elon,0); setsize(erad,0);
51
52 var dir_index = getprop(lw~"tiles/tmp/dir-index");      
53 #props.globals.getNode(lw~"tiles").getChild("tile",dir_index).getNode("code").setValue(current_code);
54
55 local_weather.assemble_effect_array();
56
57 # add a noctilucent cloud patch
58
59 var tile_index = getprop("local-weather/tiles/tile-counter");
60  if ((tile_index == 1) and (getprop("environment/create-noctilucent-clouds")==1)) 
61         {
62         alpha = 0.0;
63         var blat = getprop(lw~"tiles/tmp/latitude-deg");
64         var blon = getprop(lw~"tiles/tmp/longitude-deg");
65         create_noctilucent_patch(blat, blon, 272000.0, alpha);
66         }
67
68 # reset lighting
69
70 local_weather.top_shade = 1.0;
71
72 if (local_weather.debug_output_flag == 1) 
73         {print("Finished setting up tile type ",current_code, " in direction ",dir_index);}
74
75 if (local_weather.thread_flag == 1)
76         {setprop(lw~"tmp/thread-status","placing");}
77 else    # without worker threads, tile generation is complete at this point
78         {props.globals.getNode(lw~"tiles").getChild("tile",dir_index).getNode("generated-flag").setValue(2);}
79
80
81 }
82
83
84
85
86
87 ####################################
88 # test tile
89 ####################################
90
91 var set_4_8_stratus_tile = func {
92
93 setprop(lw~"tiles/code","test");
94
95 tile_start();
96
97 var x = 0.0;
98 var y = 0.0;
99 var lat = 0.0;
100 var lon = 0.0;
101
102 var alpha = getprop(lw~"tmp/tile-orientation-deg");
103 var phi = alpha * math.pi/180.0;
104 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
105
106 # get tile center coordinates
107
108 var blat = getprop(lw~"tiles/tmp/latitude-deg");
109 var blon = getprop(lw~"tiles/tmp/longitude-deg");
110 calc_geo(blat);
111
112 # first weather info for tile center (lat, lon, visibility, temperature, dew point, pressure)
113
114 local_weather.set_weather_station(blat, blon, alt_offset, 45000.0, 14.0, 12.0, 29.78);
115
116 #alt_offset = 0.0;
117
118 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
119
120 #var strength = 0.5;
121 #local_weather.create_cumosys(blat,blon, 3000.0, get_n(strength), 20000.0);
122
123 #create_2_8_altocumulus_streaks(blat, blon, 12000+alt_offset, alpha) ;
124 # create_2_8_altocumulus_streaks(blat, blon, 12000+alt_offset, alpha) ;
125 #create_6_8_stratus(blat, blon, 3000+alt_offset, alpha) ;
126 #create_4_8_tstratus_patches(blat, blon, 5000+alt_offset, alpha) ;
127 #create_4_8_sstratus_patches(blat, blon, 5000+alt_offset, alpha) ;
128 #create_4_8_cirrostratus_patches(blat, blon, 5000+alt_offset, alpha) ;
129
130 #create_4_8_cirrocumulus_streaks(blat, blon, 10000.0 + alt_offset, alpha);
131 #create_4_8_alttstratus_streaks(blat, blon, 5000+alt_offset, alpha) ;
132 # create_2_8_cirrocumulus_patches(blat, blon, 13000+alt_offset, alpha) ;
133
134 # create_8_8_nimbus_rain(blat, blon, 3000.0, alpha, 0.3) ;
135 #create_8_8_tstratus(blat, blon, 5000+alt_offset, alpha);
136
137 # create_8_8_cirrostratus(blat, blon, 30000.0, alpha);
138
139 #create_thunderstorm_scenario (blat, blon, 3000.0, alpha);
140 #create_big_thunderstorm (blat, blon, 3000.0, alpha);
141
142 #create_2_8_cirrus(blat, blon, 30000.0, alpha);
143 #create_2_8_cirrus(blat, blon, 20000.0, alpha);
144 # create_4_8_cirrus(blat, blon, 30000.0, alpha);
145
146 # create_2_8_altocumulus_streaks(blat, blon, 12000+alt_offset, alpha) ;
147
148 # create_detailed_stratocumulus_bank(blat, blon, 4000,alpha);
149
150 #create_4_8_tstratus_undulatus(blat, blon, 10000.0, alpha);
151
152 #local_weather.top_shade = 0.9;
153
154 #create_4_8_small_cumulus_alleys(blat, blon, 3000.0, alpha);
155 #create_4_8_cirrostratus_undulatus(blat, blon, 25000.0, alpha);
156
157 #create_2_8_mackarel(blat,blon, 12000.0, alpha);
158 #create_2_8_cirrocumulus_domains(blat, blon, 12000.0, alpha);
159 #create_2_8_altocumulus_perlucidus_domains(blat, blon, 12000.0, alpha);
160 #create_4_8_cirrostratus_mackarel(blat,blon, 25000.0, alpha);
161 #create_2_8_cirrocumulus_domains(blat,blon, 30000.0, alpha);
162
163 #var strength=0.5;
164 #local_weather.create_cumosys(blat,blon, 3000.0, get_n(strength), 20000.0);
165 local_weather.set_atmosphere_ipoint(blat, blon, 45000.0, 3000.0, 45000.0, 0.0, 15000.0, 17000.0, 0.8, 12000.0, 17000.0); 
166
167
168 append(weather_dynamics.tile_convective_altitude,3000.0);
169 append(weather_dynamics.tile_convective_strength,0.0);
170
171
172 tile_finished();
173
174 }
175
176
177 ####################################
178 # high pressure core
179 ####################################
180
181 var set_high_pressure_core_tile = func {
182
183 #set_4_8_stratus_tile ();
184 #return;
185
186 setprop(lw~"tiles/code","high_pressure_core");
187
188 tile_start();
189
190 var x = 0.0;
191 var y = 0.0;
192 var lat = 0.0;
193 var lon = 0.0;
194
195 var alpha = getprop(lw~"tmp/tile-orientation-deg");
196 var phi = alpha * math.pi/180.0;
197 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
198
199 # get tile center coordinates
200
201 var blat = getprop(lw~"tiles/tmp/latitude-deg");
202 var blon = getprop(lw~"tiles/tmp/longitude-deg");
203 calc_geo(blat);
204
205 # get probabilistic values for the weather parameters
206
207 var vis = 25000.0 + rand() * 10000.0;
208 var T = 20.0 + rand() * 10.0;
209 var spread = 14.0 + 8.0 * rand();
210 var D = T - spread;
211 var p = 1025.0 + rand() * 6.0; p = adjust_p(p);
212
213 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
214
215 # and set them at the tile center
216 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
217
218
219
220 var alt = spread * 400;
221 var strength = 0.0;
222
223
224 # bias Cumulus clouds towards smaller sizes due to lack of water vapour and convection
225 local_weather.convective_size_bias = -0.2 - rand() * 0.1;
226
227 var rn = rand();
228
229 if (rand() < small_scale_persistence)
230         {rn = rnd_store;}
231 else
232         {rnd_store = rn;}
233
234 #       rn = 0.01;
235         
236 if (rn > 0.916)
237         {
238         # cloud scenario 1: weak cumulus development and blue thermals
239
240         strength = rand() * 0.05;
241         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
242
243         # generate a few blue thermals
244
245         if (local_weather.generate_thermal_lift_flag !=0)
246                 {
247                 local_weather.generate_thermal_lift_flag = 3;
248                 strength = rand() * 0.4;
249                 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
250                 local_weather.generate_thermal_lift_flag = 2;
251                 }
252
253         # and specify the atmosphere
254         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, 25000.0, 30000.0, 0.95, alt+alt_offset, alt+alt_offset + 2500.0); 
255         }
256 else if (rn > 0.833)
257         {
258         # cloud scenario 2: some Cirrocumulus patches
259         
260         strength = rand() * 0.03;
261         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
262
263         #create_2_8_cirrocumulus(blat, blon, alt + alt_offset + 5000.0, alpha);
264         create_1_8_alttstratus_domains(blat, blon, alt + alt_offset + 5000.0, alpha);   
265         
266         create_2_8_cirrus(blat, blon, alt + alt_offset + 35000.0, alpha);
267
268         # and specify the atmosphere
269         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.1, alt+alt_offset +30000.0, alt+alt_offset + 35000.0, 0.95, alt+alt_offset, alt+alt_offset + 2500.0); 
270         }
271 else if (rn > 0.75)
272         {
273         # cloud scenario 3: Cirrostratus undulatus over weak cumulus
274                 
275         strength = rand() * 0.03;
276         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
277
278         create_4_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 32000.0, alpha);
279
280         # and specify the atmosphere
281         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.15, alt+alt_offset +28000.0, alt+alt_offset + 32000.0, 0.95, alt+alt_offset, alt+alt_offset + 2500.0); 
282
283         }
284 else if (rn > 0.666)
285         {
286         # cloud scenario 4: Cirrocumulus mackerel sky
287
288         strength = rand() * 0.03;
289         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
290
291         ##create_1_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 32000.0, alpha);
292         create_1_8_cirrocumulus_mackerel(blat, blon, alt + alt_offset + 32000.0, alpha);
293         #create_4_8_cirrus_bundle(blat, blon, alt + alt_offset + 32000.0, alpha);
294         
295         
296         # and specify the atmosphere
297         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.25, alt+alt_offset +28000.0, alt+alt_offset + 32000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0); 
298         }
299 else if (rn > 0.5833)
300         {
301         # cloud scenario 5: Cirrus
302
303         create_2_8_cirrus(blat, blon, alt + alt_offset + 35000.0, alpha);
304
305
306         create_1_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 28000.0, alpha);
307
308
309         create_1_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 28000.0, alpha);
310
311         # and specify the atmosphere
312         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +28000.0, alt+alt_offset + 33000.0, 0.95, alt+alt_offset, alt+alt_offset + 2500.0); 
313         }
314 else if (rn > 0.5)
315         {
316         # cloud scenario 6: strong Cirrus cover
317
318         create_4_8_cirrus(blat, blon, alt + alt_offset + 35000.0, alpha);
319         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +28000.0, alt+alt_offset + 33000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0); 
320         }
321 else if (rn > 0.25)
322         {
323         # cloud scenario 7: clear
324
325         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +28000.0, alt+alt_offset + 33000.0, 1.0, alt+alt_offset, alt+alt_offset + 2500.0); 
326         }
327 else if (rn > 0.166)
328         {
329         # cloud scenario 8: Stratiform hazy clouds
330
331         local_weather.top_shade = 0.8;
332         create_2_8_alttstratus_domains(blat, blon, alt+alt_offset, alpha);
333         local_weather.top_shade = 0.9;
334         create_4_8_tstratus_undulatus(blat, blon, alt+alt_offset + 4000, alpha);
335
336         # and specify the atmosphere
337         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.25, alt+alt_offset +24000.0, alt+alt_offset + 26000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0); 
338         
339         }
340 else if (rn > 0.0833)
341         {
342         # cloud scenario 9: Cirrocumulus
343
344         if (rand() > 0.4) # this is very expensive, so don't do it for every tile
345                 {create_2_8_cirrocumulus_domains(blat, blon, alt + alt_offset + 26000.0, alpha);}
346         #else
347         #       {create_2_8_cirrocumulus(blat, blon, alt + alt_offset + 26000.0, alpha);}
348
349         # and specify the atmosphere
350         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.2, alt+alt_offset +24000.0, alt+alt_offset + 26000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0);    
351         
352         }
353 else 
354         {
355         # cloud scenario 10: amorphous Cirrostratus
356
357         strength = rand() * 0.03;
358         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
359
360         create_4_8_cirrus_bundle(blat, blon, alt + alt_offset + 32000.0, alpha);
361         
362         # and specify the atmosphere
363         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.45, alt+alt_offset +28000.0, alt+alt_offset + 32000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0); 
364         
365         }
366
367
368 # store convective altitude and strength
369
370 append(weather_dynamics.tile_convective_altitude,alt);
371 append(weather_dynamics.tile_convective_strength,strength);
372
373
374 tile_finished();
375
376 }
377
378
379 ####################################
380 # high pressure 
381 ####################################
382
383 var set_high_pressure_tile = func {
384
385 setprop(lw~"tiles/code","high_pressure");
386
387 tile_start();
388
389
390 var x = 0.0;
391 var y = 0.0;
392 var lat = 0.0;
393 var lon = 0.0;
394
395 var alpha = getprop(lw~"tmp/tile-orientation-deg");
396 var phi = alpha * math.pi/180.0;
397 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
398
399 # get tile center coordinates
400
401 var blat = getprop(lw~"tiles/tmp/latitude-deg");
402 var blon = getprop(lw~"tiles/tmp/longitude-deg");
403 calc_geo(blat);
404
405 # get probabilistic values for the weather parameters
406
407 var vis = 20000.0 + rand() * 10000.0;
408 var T = 15.0 + rand() * 10.0;
409 var spread = 10.0 + 4.0 * rand();
410 var D = T - spread;
411 var p = 1019.0 + rand() * 6.0; p = adjust_p(p);
412
413 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
414
415 # and set them at the tile center
416 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
417
418
419 var alt = spread * 400;
420 var strength = 0.0;
421
422
423 # print("alt: ",alt, "spread: ", spread, "offset: ", alt_offset);
424
425 var rn = rand();
426
427 if (rand() < small_scale_persistence)
428         {rn = rnd_store;}
429 else
430         {rnd_store = rn;}
431
432 # daily modulation - layers are more pronounced during morning and evening and dissolve during the day
433         
434 var t = getprop("sim/time/utc/day-seconds");
435 t = t + getprop("sim/time/local-offset");
436 var sec_to_rad = 2.0 * math.pi/86400;
437 var t_factor1 = 0.5 * (1.0-math.cos((t * sec_to_rad)));         
438         
439 #rn = 0.01;
440
441 if (rn > 0.9)
442         {
443         # cloud scenario 1: possible Cirrus over Cumulus
444         strength = 0.2 + rand() * 0.4;
445         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
446
447         # one or two Cirrus clouds
448
449         x = 2000.0 + rand() * 16000.0;
450         y = 2.0 * (rand()-0.5) * 18000;
451         var path = local_weather.select_cloud_model("Cirrus", "small");
452         compat_layer.create_cloud(path, blat + get_lat(x,y,phi), blon+get_lon(x,y,phi),  alt + alt_offset + 25000.0 + rand() * 5000.0,alpha);
453         
454         if (rand() > 0.5)
455                 {
456                 x = -2000.0 - rand() * 16000.0;
457                 y = 2.0 * (rand()-0.5) * 18000;
458                 var path = local_weather.select_cloud_model("Cirrus", "small");
459                 compat_layer.create_cloud(path, blat + get_lat(x,y,phi), blon+get_lon(x,y,phi),  alt + alt_offset +25000.0 + rand() * 5000.0,alpha);
460                 }       
461
462         # and specify the atmosphere
463         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +28000.0, alt+alt_offset + 30000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); 
464
465         }
466 else if (rn > 0.8)
467         {
468         # cloud scenario 2: Cirrostratus over weak Cumulus
469
470         strength = 0.2 + rand() * 0.2;
471         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
472
473         #create_2_8_cirrostratus(blat, blon, alt+alt_offset+25000.0, alpha);
474         create_2_8_cirrostratus_mackerel(blat, blon, alt+alt_offset+25000.0, alpha);
475
476         # and specify the atmosphere
477         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.2, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0); 
478         }
479
480 else if (rn > 0.7)
481         {
482         # cloud scenario 3: Cirrocumulus sheet over Cumulus
483
484         strength = 0.2 + rand() * 0.2;
485         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
486         
487         x = 2.0 * (rand()-0.5) * 5000;
488         y = 2.0 * (rand()-0.5) * 5000;
489
490
491         var path = local_weather.select_cloud_model("Cirrocumulus", "large");
492         compat_layer.create_cloud(path, blat + get_lat(x,y,phi), blon+get_lon(x,y,phi),  alt + alt_offset +24000,alpha);
493
494
495         # and specify the atmosphere
496         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 24000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); 
497
498         }
499 else if (rn > 0.6)
500         {
501         # cloud scenario 4: Cirrostratus undulatus over weak Cumulus
502
503         strength = 0.15 + rand() * 0.15;
504         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
505
506         if (rand()>0.5)
507                 {
508                 create_4_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 25000.0, alpha);
509                 }
510         else
511                 {
512                 create_4_8_cirrus_bundle(blat, blon, alt + alt_offset + 25000.0, alpha);
513                 }
514
515         # and specify the atmosphere
516         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.35, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); 
517         }
518 else if (rn > 0.5)
519         {
520         # cloud scenario 5: some scattered Altocumuli over Cumulus
521
522         strength = 0.25 + rand() * 0.1;
523         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
524
525         create_1_8_altocumulus_scattered(blat, blon, alt+alt_offset+10000.0, alpha);    
526
527         create_1_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 25000.0, alpha);
528
529         # and specify the atmosphere
530         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0); 
531         }
532 else if (rn > 0.4)
533         {
534         # cloud scenario 6: Cirrocumulus over Cumulus   
535         strength = 0.2 + rand() * 0.1;
536         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
537         
538         if (rand() > 0.6) # this is very expensive, so don't do it for every tile
539                 {create_2_8_cirrocumulus_domains(blat, blon, alt + alt_offset + 26000.0, alpha);}
540         else
541                 {create_1_8_alttstratus_domains(blat, blon, alt + alt_offset + 26000.0, alpha);}
542
543         # and specify the atmosphere
544         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.3, alt+alt_offset +24000.0, alt+alt_offset + 26000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); 
545         }
546 else if (rn > 0.3)
547         {
548         # cloud scenario 7: just Cumulus
549
550         strength = 0.3 + rand() * 0.2;
551         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
552
553         # and specify the atmosphere
554         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); 
555         }
556 else if (rn > 0.2)
557         {
558         # cloud scenario 8: Altocumulus Perlucidus over Cumulus
559
560         strength = 0.2 + rand() * 0.1;
561         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
562
563
564         if (rand()>0.5* t_factor1)
565                 {create_2_8_altocumulus_perlucidus_domains(blat, blon, alt + alt_offset + 12000.0, alpha);}
566
567         # and specify the atmosphere
568         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0); 
569         }
570 else if (rn > 0.1)
571         {
572         # cloud scenario 9: Thin Stratus over Cumulus
573
574         strength = 0.2 + rand() * 0.1;
575         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
576         
577         if (rand()>0.5* t_factor1)
578                 {create_2_8_alttstratus_domains(blat, blon, alt + alt_offset + 12000.0, alpha);}
579
580         # and specify the atmosphere
581         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); 
582         }
583 else 
584         {
585         # cloud scenario 10: Mackerel Cirrocumulus
586
587         strength = 0.3 + rand() * 0.1;
588         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
589         
590         if(rand() > 0.6)
591                 {create_1_8_cirrocumulus_mackerel(blat, blon, alt + alt_offset + 20000.0, alpha);}
592
593         # and specify the atmosphere
594         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0); 
595         }
596         
597
598
599 # store convective altitude and strength
600
601 append(weather_dynamics.tile_convective_altitude,alt);
602 append(weather_dynamics.tile_convective_strength,strength);
603
604
605 tile_finished();
606
607 }
608
609
610 ####################################
611 # high pressure border
612 ####################################
613
614 var set_high_pressure_border_tile = func {
615
616 setprop(lw~"tiles/code","high_pressure_border");
617
618 tile_start();
619
620 var x = 0.0;
621 var y = 0.0;
622 var lat = 0.0;
623 var lon = 0.0;
624
625 var alpha = getprop(lw~"tmp/tile-orientation-deg");
626 var phi = alpha * math.pi/180.0;
627 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
628
629 # get tile center coordinates
630
631 var blat = getprop(lw~"tiles/tmp/latitude-deg");
632 var blon = getprop(lw~"tiles/tmp/longitude-deg");
633 calc_geo(blat);
634
635 # get probabilistic values for the weather parameters
636
637 var vis = 15000.0 + rand() * 7000.0;
638 var T = 12.0 + rand() * 10.0;
639 var spread = 7.0 + 4.0 * rand();
640 var D = T - spread;
641 var p = 1013.0 + rand() * 6.0; p = adjust_p(p);
642
643 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
644
645 # and set them at the tile center
646 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
647
648
649 # now a random selection of different possible cloud configuration scenarios
650
651 var alt = spread * 400;
652 var strength = 0.0;
653
654 var rn = rand();
655
656
657
658 if (rand() < small_scale_persistence)
659         {rn = rnd_store;}
660 else
661         {rnd_store = rn;}
662
663
664 #rn = 0.85;
665
666 if (rn > 0.9)
667         {
668         # cloud scenario 1: Altocumulus patch over weak Cumulus
669         strength = 0.1 + rand() * 0.1;
670         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
671
672         #x = 2.0 * (rand()-0.5) * 5000;
673         #y = 2.0 * (rand()-0.5) * 5000;
674         #local_weather.create_streak("Altocumulus",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 12000.0+alt+alt_offset,1500.0,30,1000.0,0.2,1200.0,30,1000.0,0.2,1200.0,alpha ,1.0);
675         
676         create_2_8_altocumulus_domains(blat, blon, alt+alt_offset +12000.0, alpha);
677
678         # and specify the atmosphere
679         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); 
680
681         }
682 else if (rn > 0.8)
683         {
684         # cloud scenario 2: Perlucidus variations
685         strength = 0.1 + rand() * 0.15;
686         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
687
688         #x = 2.0 * (rand()-0.5) * 10000;
689         #y = 2.0 * (rand()-0.5) * 10000;
690         #local_weather.create_streak("Altocumulus",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 12000.0+alt+alt_offset,1500.0,25,700.0,0.2,800.0,10,700.0,0.2,800.0,alpha ,1.4);
691         #x = 2.0 * (rand()-0.5) * 10000;
692         #y = 2.0 * (rand()-0.5) * 10000;
693         #local_weather.create_streak("Altocumulus",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 12000.0+alt+alt_offset,1500.0,22,750.0,0.2,1000.0,8,750.0,0.2,1000.0,alpha ,1.1);
694
695         if (rand() > 0.6)
696                 {create_2_8_perlucidus_mackerel(blat, blon, alt+alt_offset +12000.0, alpha);}
697         else
698                 {create_2_8_sstratus_hires_bundle(blat, blon, alt+alt_offset +12000.0, alpha);}
699         
700         # and specify the atmosphere
701         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); 
702
703         }
704 else if (rn > 0.7)
705         {
706         # cloud scenario 3: Cirrus
707
708         strength = 0.1 + rand() * 0.1;
709         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
710
711         create_2_8_cirrus(blat, blon, alt + 28000.0 + alt_offset, alpha);
712
713         # and specify the atmosphere
714         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 22000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); 
715
716         }
717 else if (rn > 0.6)
718         {
719         # cloud scenario 4: thin Stratus streaks
720
721         strength = 0.7 + rand() * 0.3;
722         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
723
724         #create_4_8_alttstratus_streaks(blat, blon, alt+alt_offset +10000.0, alpha);
725         create_4_8_alttstratus_domains(blat, blon, alt+alt_offset +10000.0, alpha);
726
727         # and specify the atmosphere
728         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +10000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0); 
729
730         }
731 else if (rn > 0.5)
732         {
733         # cloud scenario 5: scattered Altocumulus perlucidus
734
735         strength = 0.4 + rand() * 0.2;
736         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
737
738         var size_offset = 0.5 * m_to_ft * local_weather.cloud_vertical_size_map["Stratus_structured"];
739
740         #local_weather.create_streak("Stratus (structured)",blat, blon, alt+6000.0+alt_offset+size_offset,1000.0,18,0.0,0.3,20000.0,18,0.0,0.3,20000.0,0.0,1.0);
741         create_4_8_sstratus_domains(blat, blon, alt+alt_offset+size_offset +6000.0, alpha);
742         #create_2_8_sstratus_hires_bundle(blat, blon, alt+alt_offset+size_offset +6000.0, alpha);
743         
744         # and specify the atmosphere
745         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.2, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0); 
746
747         }
748 else if (rn > 0.4)
749         {
750         # cloud scenario 6: Cirrocumulus sheets
751
752         strength = 0.2 + rand() * 0.2;
753         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
754         
755
756         for (var i = 0; i < 2; i = i + 1)
757                 {
758                 x = 2.0 * (rand()-0.5) * 10000;
759                 y = -6000 + i * 12000 + 2.0 * (rand()-0.5) * 1000;
760
761                 var beta = rand() * 90;
762                 var alt_variation = rand() * 2000;
763
764                 var path = local_weather.select_cloud_model("Cirrocumulus", "large");
765                 compat_layer.create_cloud(path, blat + get_lat(x,y,phi), blon+get_lon(x,y,phi),  alt + alt_offset +20000+ alt_variation,alpha+ beta);
766                 }
767
768         # and specify the atmosphere
769         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); 
770         }
771 else if (rn > 0.3)
772         {
773         # cloud scenario 7: Thin Cirrocumulus sheets over weak Cumulus
774
775         strength = 0.05 + rand() * 0.1;
776         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
777         
778         #create_4_8_cirrocumulus_streaks(blat, blon, alt + 6000.0 + alt_offset, alpha);
779         create_4_8_alttstratus_domains(blat, blon, alt + 6000.0 + alt_offset, alpha);
780         
781         # and specify the atmosphere
782         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.25, alt+alt_offset +6000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0); 
783
784         }
785 else if (rn > 0.2)
786         {
787         # cloud scenario 8: Altocumulus perlucidus
788         
789         create_4_8_altocumulus_perlucidus(blat, blon, alt + 10000.0 + alt_offset, alpha);
790
791         create_2_8_cirrus(blat, blon, alt + 30000.0 + alt_offset, alpha);
792
793         # and specify the atmosphere
794         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.25, alt+alt_offset +26000.0, alt+alt_offset + 30000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); 
795
796         }
797 else if (rn > 0.1)
798         {
799         # cloud scenario 9: Cumulus, Altocumulus and Cirrus
800
801         strength = 0.3 + rand() * 0.15;
802         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
803
804         create_1_8_altocumulus_scattered(blat, blon, alt + 12000.0 + alt_offset, alpha);
805         create_2_8_altocumulus_streaks(blat, blon, alt + 12000.0 + alt_offset, alpha);
806
807         create_2_8_cirrus(blat, blon, alt + 30000.0 + alt_offset, alpha);
808
809         # and specify the atmosphere
810         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +26000.0, alt+alt_offset + 30000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0); 
811         }
812 else if (rn > 0.0)
813         {
814         # cloud scenario 10: Cumulus alleys and Cirrus
815
816         create_4_8_cumulus_alleys(blat, blon, alt+ alt_offset, alpha);
817         create_4_8_cirrus(blat, blon, alt + alt_offset + 35000.0, alpha);
818
819         # and specify the atmosphere
820         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.1, alt+alt_offset +30000.0, alt+alt_offset + 35000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0); 
821         }
822
823
824 # store convective altitude and strength
825
826 append(weather_dynamics.tile_convective_altitude,alt);
827 append(weather_dynamics.tile_convective_strength,strength);
828
829
830 tile_finished();
831
832 }
833
834 ####################################
835 # low pressure border
836 ####################################
837
838 var set_low_pressure_border_tile = func {
839
840 setprop(lw~"tiles/code","low_pressure_border");
841
842 tile_start();
843
844 var x = 0.0;
845 var y = 0.0;
846 var lat = 0.0;
847 var lon = 0.0;
848
849 var alpha = getprop(lw~"tmp/tile-orientation-deg");
850 var phi = alpha * math.pi/180.0;
851
852
853 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
854
855
856 # get tile center coordinates
857
858 var blat = getprop(lw~"tiles/tmp/latitude-deg");
859 var blon = getprop(lw~"tiles/tmp/longitude-deg");
860 calc_geo(blat);
861
862 # get probabilistic values for the weather parameters
863
864 var vis = 8000.0 + rand() * 8000.0;
865 var T = 10.0 + rand() * 10.0;
866 var spread = 6.0 + 2.0 * rand();
867 var D = T - spread;
868 var p = 1007.0 + rand() * 6.0; p = adjust_p(p);
869
870 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
871
872 # and set them at the tile center
873 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
874
875 # altitude for the lowest layer
876 var alt = spread * 400.0;
877 var strength = 0.0;
878
879 # bias Cumulus clouds towards larger sizes due to lots of water vapour
880 local_weather.convective_size_bias = 0.2 + rand() * 0.2;
881
882 # now a random selection of different possible cloud configuration scenarios
883
884 var rn = rand();
885
886 if (rand() < small_scale_persistence)
887         {rn = rnd_store;}
888 else
889         {rnd_store = rn;}
890
891 #rn = 0.01;
892
893 if (rn > 0.9)
894         {
895         # cloud scenario 1: low Stratocumulus, thin streaks above
896
897         strength = 0.05 + rand() * 0.1;
898         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
899
900         create_detailed_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
901
902         create_2_8_alttstratus_domains(blat, blon, alt+alt_offset+4000.0,alpha);
903
904         # and specify the atmosphere
905         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0); 
906
907         }
908 else if (rn > 0.8)
909         {
910         # cloud scenario 2: weak Cumulus, Stratus undulatus above
911
912         strength = 0.2 + rand() * 0.2;
913         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
914         
915         #create_6_8_tstratus_undulatus(blat, blon, alt+alt_offset+4000.0,alpha);
916         create_6_8_tstratus_mackerel(blat, blon, alt+alt_offset+4000.0,alpha);
917
918         create_2_8_alttstratus_domains(blat, blon, alt+alt_offset+7000.0,alpha);
919
920         # and specify the atmosphere
921         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0); 
922         }
923 else if (rn > 0.7)
924         {
925         # cloud scenario 3: Stratocumulus banks with patches above
926
927         create_detailed_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
928         create_detailed_small_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
929
930         create_4_8_alttstratus_domains(blat, blon, alt+alt_offset+4000.0,alpha);
931
932         # and specify the atmosphere
933         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.7, alt+alt_offset, alt+alt_offset + 2500.0); 
934         }
935 else if (rn > 0.6)
936         {
937         # cloud scenario 4: structured Stratus
938         
939         alt = alt + local_weather.cloud_vertical_size_map["Stratus"] * 0.5 * m_to_ft;
940         create_4_8_sstratus_patches(blat, blon, alt+alt_offset,alpha);
941
942         create_2_8_alttstratus_domains(blat, blon, alt+alt_offset+7000.0,alpha);
943         # and specify the atmosphere
944         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.25, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.7, alt+alt_offset, alt+alt_offset + 2500.0); 
945         }
946 else if (rn > 0.5)
947         {
948         # cloud scenario 5: Stratus blending with Cumulus with Cirrocumulus above
949         
950         strength = 0.1 + rand() * 0.1;
951         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
952
953         #create_4_8_tstratus_patches(blat, blon, alt+alt_offset,alpha);
954         create_4_8_tstratus_domains(blat, blon, alt+alt_offset,alpha);
955
956         #create_4_8_cirrocumulus_undulatus(blat, blon, alt+alt_offset + 12000.0,alpha);
957         create_2_8_perlucidus_mackerel(blat, blon, alt+alt_offset + 12000.0,alpha);
958         
959         # and specify the atmosphere
960         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.15, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0); 
961         }
962 else if (rn > 0.4)
963         {
964         # cloud scenario 6: small Stratocumulus banks
965         
966         create_detailed_small_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
967         create_detailed_small_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
968
969         #create_4_8_tstratus_patches(blat, blon, alt+alt_offset,alpha);
970         create_4_8_tstratus_domains(blat, blon, alt+alt_offset,alpha);
971         
972         create_2_8_cirrostratus(blat, blon, alt+alt_offset + 25000.0,alpha);
973         
974         # and specify the atmosphere
975         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.3, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0); 
976         }
977 else if (rn > 0.3)
978         {
979         # cloud scenario 7: blended structured and unstructured Stratiform clouds
980
981         #create_4_8_tstratus_patches(blat, blon, alt+alt_offset,alpha);
982         create_4_8_tstratus_domains(blat, blon, alt+alt_offset,alpha);
983         
984         create_4_8_sstratus_patches(blat, blon, alt+alt_offset,alpha);
985
986         create_2_8_cirrostratus(blat, blon, alt+alt_offset + 25000.0,alpha);
987
988         # and specify the atmosphere
989         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.2, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0); 
990         }
991 else if (rn > 0.2)
992         {
993         # cloud scenario 8: Cumulus alleys beneath a high dense stratus cover
994         
995         local_weather.top_shade = 0.7;
996         create_4_8_cumulus_alleys(blat, blon, alt+ alt_offset, alpha);
997
998         local_weather.top_shade = 1.0;
999         #create_6_8_tstratus_undulatus(blat, blon, alt+alt_offset + 6000.0,alpha);
1000         create_6_8_tstratus_mackerel(blat, blon, alt+alt_offset + 6000.0,alpha);
1001
1002         # and specify the atmosphere
1003         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.5, alt+alt_offset +5500.0, alt+alt_offset + 6500.0, 0.65, alt+alt_offset + 6000.0, alt+alt_offset + 7500.0); 
1004         }
1005 else if (rn > 0.1)
1006         {
1007         # cloud scenario 9: weak Cumulus benath a high dense stratus cover
1008         
1009         local_weather.top_shade = 0.6;
1010
1011         strength = 0.2 + rand() * 0.2;
1012         #local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1013
1014         var n = int(3000 * strength) * 0.2;
1015         local_weather.cumulus_exclusion_layer(blat, blon, alt+alt_offset, n, 20000.0, 20000.0, alpha, 0.3,1.4 , size(elat), elat, elon, erad);
1016
1017         local_weather.top_shade = 1.0;
1018         create_6_8_stratus(blat, blon, alt+alt_offset + 8000.0,alpha);
1019
1020         create_1_8_cirrus_bundle(blat, blon, alt+alt_offset + 34000.0,alpha);
1021         
1022         # and specify the atmosphere
1023         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset + 8000.0, vis + 15000.0, 0.7, alt+alt_offset +7500.0, alt+alt_offset + 8500.0, 0.65, alt+alt_offset + 8000.0, alt+alt_offset + 9500.0); 
1024         }
1025 else
1026         {
1027         # cloud scenario 10: broken structured Stratus cover
1028
1029         
1030         create_4_8_sstratus_bundle(blat, blon, alt+alt_offset,alpha);
1031
1032         #create_2_8_cirrostratus(blat, blon, alt+alt_offset + 25000.0,alpha);
1033
1034         # and specify the atmosphere
1035         local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.2, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0); 
1036         }
1037
1038
1039
1040
1041 # store convective altitude and strength
1042
1043 append(weather_dynamics.tile_convective_altitude,alt);
1044 append(weather_dynamics.tile_convective_strength,strength);
1045
1046 tile_finished();
1047
1048 }
1049
1050 ####################################
1051 # low pressure 
1052 ####################################
1053
1054 var set_low_pressure_tile = func {
1055
1056 setprop(lw~"tiles/code","low_pressure");
1057
1058 tile_start();
1059
1060 var x = 0.0;
1061 var y = 0.0;
1062 var lat = 0.0;
1063 var lon = 0.0;
1064
1065 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1066 var phi = alpha * math.pi/180.0;
1067
1068
1069 if (local_weather.presampling_flag == 0)
1070         {var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
1071 else
1072         {var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
1073
1074 # get tile center coordinates
1075
1076 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1077 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1078 calc_geo(blat);
1079
1080 # get probabilistic values for the weather parameters
1081
1082 var vis = 8000.0 + rand() * 5000.0;
1083 var T = 5.0 + rand() * 10.0;
1084 var spread = 5.0 + 2.0 * rand();
1085 var D = T - spread;
1086 var p = 1001.0 + rand() * 6.0; p = adjust_p(p);
1087
1088 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1089
1090 # and set them at the tile center
1091 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
1092
1093 # altitude for the lowest layer
1094 var alt = spread * 400.0;
1095 var strength = 0.0;
1096
1097 var rn = rand();
1098
1099
1100
1101 if (rand() < small_scale_persistence)
1102         {rn = rnd_store;}
1103 else
1104         {rnd_store = rn;}
1105
1106
1107 if (rn > 0.8)
1108         {
1109
1110         # cloud scenario 1: two patches of Nimbostratus with precipitation
1111         # overhead broken stratus layers
1112         # cloud count 1050
1113
1114         x = 2.0 * (rand()-0.5) * 11000.0;
1115         y = 2.0 * (rand()-0.5) * 11000.0;
1116         var beta = rand() * 360.0;
1117
1118         var alt_eff = alt;
1119         if (local_weather.hardcoded_clouds_flag == 1) {alt_eff = alt_eff - 3000.0;}
1120
1121         local_weather.create_layer("Nimbus", blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt_eff+alt_offset, 500.0, 12000.0, 7000.0, beta, 1.0, 0.2, 1, 1.0);
1122         local_weather.create_effect_volume(2, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 10000.0, 6000.0, beta, 0.0, alt + alt_offset, 5000.0, 0.3, -1, -1, -1,0,-1 );
1123         local_weather.create_effect_volume(2, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 9000.0, 5000.0, beta, 0.0, alt+alt_offset-300.0, 1500.0, 0.5, -1, -1, -1,0,-1 );
1124
1125         x = 2.0 * (rand()-0.5) * 11000.0;
1126         y = 2.0 * (rand()-0.5) * 11000.0;
1127         var beta = rand() * 360.0;
1128
1129         local_weather.create_layer("Nimbus", blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt_eff+alt_offset, 500.0, 10000.0, 6000.0, beta, 1.0, 0.2, 1, 1.0);
1130         local_weather.create_effect_volume(2, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 9000.0, 5000.0, beta, 0.0, alt + alt_offset, 5000.0, 0.3, -1, -1, -1,0 ,-1);
1131         local_weather.create_effect_volume(2, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 8000.0, 4000.0, beta, 0.0, alt+alt_offset-300.0, 1500.0, 0.5, -1, -1, -1,0,-1 );
1132
1133         #create_4_8_sstratus_undulatus(blat, blon, alt+alt_offset +3000.0, alpha);
1134         create_4_8_sstratus_bundle(blat, blon, alt+alt_offset +3000.0, alpha);
1135
1136         create_2_8_tstratus(blat, blon, alt+alt_offset +6000.0, alpha);
1137
1138         # and specify the atmosphere
1139         local_weather.set_atmosphere_ipoint(blat, blon, vis + 17000.0, alt+alt_offset, vis + 22000.0, 0.2, alt+alt_offset +15000.0, alt+alt_offset + 20000.0, 0.7, alt+alt_offset, alt+alt_offset + 2500.0); 
1140         }
1141 else if (rn >0.6)
1142         {
1143         # cloud scenario 2: 8/8 Stratus with light precipitation
1144         # above broken cover
1145         # cloud count 1180
1146
1147         alt = alt + local_weather.cloud_vertical_size_map["Stratus"] * 0.5 * m_to_ft;
1148         create_8_8_stratus(blat, blon, alt+alt_offset,alpha);
1149         local_weather.create_effect_volume(3, blat, blon, 18000.0, 18000.0, 0.0, 0.0, 1800.0, 8000.0, -1, -1, -1, -1, 0,-1);
1150         local_weather.create_effect_volume(3, blat, blon, 14000.0, 14000.0, 0.0, 0.0, 1500.0, 6000.0, 0.1, -1, -1, -1,0,-1 );
1151         create_2_8_sstratus_bundle(blat, blon, alt+alt_offset+3000,alpha);
1152
1153         # and specify the atmosphere
1154         local_weather.set_atmosphere_ipoint(blat, blon, vis + 17000.0, alt+alt_offset, vis + 25000.0, 0.3, alt+alt_offset +15000.0, alt+alt_offset + 20000.0, 0.6, alt+alt_offset, alt+alt_offset + 2500.0); 
1155
1156         }
1157 else if (rn >0.4)
1158         {
1159         # cloud scenario 3: multiple broken layers
1160         # cloud count 1350
1161
1162         alt = alt + local_weather.cloud_vertical_size_map["Stratus"] * 0.5 * m_to_ft;
1163         create_4_8_stratus(blat, blon, alt+alt_offset,alpha);
1164         create_4_8_stratus_patches(blat, blon, alt+alt_offset+3000,alpha);
1165         create_4_8_sstratus_bundle(blat, blon, alt+alt_offset+6000,alpha);
1166         create_2_8_tstratus(blat, blon, alt+alt_offset+8000,alpha);
1167
1168         # and specify the atmosphere
1169         local_weather.set_atmosphere_ipoint(blat, blon, vis + 17000.0, alt+alt_offset, vis + 25000.0, 0.35, alt+alt_offset +10000.0, alt+alt_offset + 20000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0); 
1170         }
1171 else if (rn >0.2)
1172         {
1173         # cloud scenario 4: a low 6/8 layer and some clouds above
1174         # cloud count 650
1175
1176         alt = alt + local_weather.cloud_vertical_size_map["Stratus"] * 0.5 * m_to_ft;
1177         create_6_8_stratus(blat, blon, alt+alt_offset,alpha);
1178         create_2_8_sstratus_bundle(blat, blon, alt+alt_offset+6000,alpha);
1179
1180         # and specify the atmosphere
1181         local_weather.set_atmosphere_ipoint(blat, blon, vis + 15000.0, alt+alt_offset, vis + 24000.0, 0.2, alt+alt_offset +15000.0, alt+alt_offset + 22000.0, 0.7 - rand() * 0.1, alt+alt_offset, alt+alt_offset + 2500.0); 
1182         }
1183 else if (rn >0.0)
1184         {
1185         # cloud scenario 5: a low 8/8 layer without rain
1186         
1187         alt = alt + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft;
1188         create_8_8_nimbus_rain(blat, blon, alt+alt_offset, alpha,0.0);
1189
1190         if (rand() > 0.5)
1191                 {
1192                 create_2_8_cirrus(blat, blon, alt+alt_offset + 28000.0,alpha);
1193                 }               
1194
1195         # and specify the atmosphere
1196         local_weather.set_atmosphere_ipoint(blat, blon, vis + 15000.0, alt+alt_offset, vis + 24000.0, 0.05, alt+alt_offset +5000.0, alt+alt_offset + 8000.0, 0.55, alt+alt_offset, alt+alt_offset + 2500.0); 
1197         }       
1198 # store convective altitude and strength
1199
1200 append(weather_dynamics.tile_convective_altitude,alt);
1201 append(weather_dynamics.tile_convective_strength,strength);
1202
1203 tile_finished();
1204
1205 }
1206
1207
1208 ####################################
1209 # low pressure core
1210 ####################################
1211
1212 var set_low_pressure_core_tile = func {
1213
1214 setprop(lw~"tiles/code","low_pressure_core");
1215
1216 tile_start();
1217
1218 var x = 0.0;
1219 var y = 0.0;
1220 var lat = 0.0;
1221 var lon = 0.0;
1222
1223 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1224 var phi = alpha * math.pi/180.0;
1225
1226 if (local_weather.presampling_flag == 0)
1227         {var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
1228 else
1229         {var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
1230
1231 # get tile center coordinates
1232
1233 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1234 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1235 calc_geo(blat);
1236
1237 # get probabilistic values for the weather parameters
1238
1239 var vis = 5000.0 + rand() * 5000.0;
1240 var T = 3.0 + rand() * 7.0;
1241 var spread = 4.5 + 1.0 * rand();
1242 var D = T - spread;
1243 var p = 995.0 + rand() * 6.0; p = adjust_p(p);
1244
1245 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1246
1247 # and set them at the tile center
1248 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
1249
1250
1251 # set a closed Nimbostratus layer
1252
1253 var alt = spread * 400.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft;
1254 var strength = 0.0;
1255
1256 #var alt = 3000.0;
1257
1258 create_8_8_nimbus_rain(blat, blon, alt+alt_offset, alpha,0.4 + rand()*0.2);
1259
1260
1261 # and some broken Stratus cover above
1262
1263 var rn = rand();
1264
1265 if (rand() < small_scale_persistence)
1266         {rn = rnd_store;}
1267 else
1268         {rnd_store = rn;}
1269
1270 if (rn > 0.5){create_4_8_stratus_patches(blat, blon, alt+alt_offset+3000.0, alpha);}
1271 else {create_4_8_stratus(blat, blon, alt+alt_offset+3000.0, alpha);}
1272
1273
1274 local_weather.set_atmosphere_ipoint(blat, blon, vis + 20000.0, alt+alt_offset, vis + 25000.0, 0.0, alt+alt_offset +15000.0, alt+alt_offset + 22000.0, 0.6, alt+alt_offset, alt+alt_offset + 3000.0); 
1275
1276 # store convective altitude and strength
1277
1278 append(weather_dynamics.tile_convective_altitude,alt);
1279 append(weather_dynamics.tile_convective_strength,strength);
1280
1281 tile_finished();
1282
1283 }
1284
1285
1286 ####################################
1287 # cold sector
1288 ####################################
1289
1290 var set_cold_sector_tile = func {
1291
1292 setprop(lw~"tiles/code","cold_sector");
1293
1294 tile_start();
1295
1296 var x = 0.0;
1297 var y = 0.0;
1298 var lat = 0.0;
1299 var lon = 0.0;
1300
1301 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1302 var phi = alpha * math.pi/180.0;
1303 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
1304
1305 # get tile center coordinates
1306
1307 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1308 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1309 calc_geo(blat);
1310
1311 # get probabilistic values for the weather parameters
1312
1313 var vis = 40000.0 + rand() * 15000.0;
1314 var T = 8.0 + rand() * 8.0;
1315 var spread = 7.0 + 3.0 * rand();
1316 var D = T - spread;
1317 var p = 1005.0 + rand() * 10.0; p = adjust_p(p);
1318
1319 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1320
1321 # and set them at the tile center
1322 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
1323
1324 # altitude for the lowest layer
1325 var alt = spread * 400.0;
1326 var strength = 0.0;
1327
1328 # bias Cumulus clouds towards larger sizes due to strong convection
1329 local_weather.convective_size_bias = 0.3 + rand() * 0.1;
1330
1331 var rn = rand();
1332
1333 if (rand() < small_scale_persistence)
1334         {rn = rnd_store;}
1335 else
1336         {rnd_store = rn;}
1337
1338 #rn = 0.1;
1339
1340 if (rn > 0.5)
1341         {
1342         # cloud scenario 1: strong Cumulus development
1343         strength = 0.6 + rand() * 0.1;
1344         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1345
1346         # and specify the atmosphere
1347         local_weather.set_atmosphere_ipoint(blat, blon, vis + 8000.0, alt+alt_offset, vis + 18000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0); 
1348         }
1349
1350 else if (rn > 0.0)
1351         {
1352         # cloud scenario 2: Cirrocumulus sheets over Cumulus
1353
1354         strength = 0.5 + rand() * 0.1;
1355         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1356         
1357         for (var i = 0; i < 2; i = i + 1)
1358                 {
1359                 x = 2.0 * (rand()-0.5) * 10000;
1360                 y = -6000 + i * 12000 + 2.0 * (rand()-0.5) * 1000;
1361
1362                 var beta = rand() * 90;
1363                 var alt_variation = rand() * 2000;
1364
1365                 var path = local_weather.select_cloud_model("Cirrocumulus", "large");
1366                 compat_layer.create_cloud(path, blat + get_lat(x,y,phi), blon+get_lon(x,y,phi),  alt + alt_offset +20000+ alt_variation,alpha+ beta);
1367                 }
1368
1369         # and specify the atmosphere
1370         local_weather.set_atmosphere_ipoint(blat, blon, vis + 8000.0, alt+alt_offset, vis + 18000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0); 
1371
1372         }
1373
1374 #local_weather.create_effect_volume(3, blat, blon, 20000.0, 7000.0, alpha, 0.0, 80000.0, -1, -1, -1, -1, 15.0, -3,-1);
1375
1376 # store convective altitude and strength
1377
1378 append(weather_dynamics.tile_convective_altitude,alt);
1379 append(weather_dynamics.tile_convective_strength,strength);
1380
1381 tile_finished();
1382
1383 }
1384
1385
1386 ####################################
1387 # Warm sector
1388 ####################################
1389
1390 var set_warm_sector_tile = func {
1391
1392 setprop(lw~"tiles/code","warm_sector");
1393
1394 tile_start();
1395
1396 var x = 0.0;
1397 var y = 0.0;
1398 var lat = 0.0;
1399 var lon = 0.0;
1400
1401 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1402 var phi = alpha * math.pi/180.0;
1403 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
1404
1405 # get tile center coordinates
1406
1407 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1408 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1409 calc_geo(blat);
1410
1411 # get probabilistic values for the weather parameters
1412
1413 var vis = 8000.0 + rand() * 5000.0;
1414 var T = 16.0 + rand() * 10.0;
1415 var spread = 6.0 + 3.0 * rand();
1416 var D = T - spread;
1417 var p = 1005.0 + rand() * 10.0; p = adjust_p(p);
1418
1419 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1420
1421 # and set them at the tile center
1422 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
1423
1424 # altitude for the lowest layer
1425 var alt = spread * 400.0;
1426 var strength = 0.0;
1427
1428 # bias Cumulus clouds towards larger sizes due to lots of water vapour
1429 local_weather.convective_size_bias = 0.1 + rand() * 0.1;
1430
1431
1432 var rn = rand();
1433
1434 if (rand() < small_scale_persistence)
1435         {rn = rnd_store;}
1436 else
1437         {rnd_store = rn;}
1438
1439 if (rn > 0.8)
1440         {
1441         # cloud scenario 1: weak Cumulus development, some Cirrostratus
1442         strength = 0.3 + rand() * 0.2;
1443         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1444         create_4_8_cirrostratus_patches(blat, blon, alt+alt_offset+25000.0, alpha);
1445
1446         # and specify the atmosphere
1447         local_weather.set_atmosphere_ipoint(blat, blon, vis + 1000.0, alt+alt_offset, vis + 3000.0, 0.3, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0); 
1448         }
1449 else if (rn > 0.6)      
1450         {
1451         # cloud scenario 2: weak Cumulus development under Altostratus streaks
1452         strength = 0.1 + rand() * 0.1;
1453         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1454
1455         var size_offset = 0.5 * m_to_ft * local_weather.cloud_vertical_size_map["Stratus_structured"];
1456
1457         create_2_8_sstratus_bundle(blat, blon, alt+alt_offset + size_offset + 2000.0, alpha);
1458         create_2_8_sstratus_hires_bundle(blat, blon, alt+alt_offset + size_offset + 4000.0, alpha);
1459
1460         # and specify the atmosphere
1461         local_weather.set_atmosphere_ipoint(blat, blon, vis + 1000.0, alt+alt_offset, vis + 3000.0, 0.2, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0); 
1462         }
1463 else if (rn > 0.4)      
1464         {
1465         # cloud scenario 3: Cirrocumulus bank
1466         strength = 0.05 + rand() * 0.05;
1467         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1468
1469         var size_offset = 0.5 * m_to_ft * local_weather.cloud_vertical_size_map["Cirrocumulus"];
1470
1471         create_4_8_cirrocumulus_bank(blat, blon, alt+alt_offset + size_offset + 7000.0, alpha);
1472
1473         # and specify the atmosphere
1474         local_weather.set_atmosphere_ipoint(blat, blon, vis + 1000.0, alt+alt_offset, vis + 3000.0, 0.35, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0); 
1475         }
1476 else if (rn > 0.2)      
1477         {
1478         # cloud scenario 4: Cirrocumulus undulatus
1479         strength = 0.05 + rand() * 0.05;
1480         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1481
1482         var size_offset = 0.5 * m_to_ft * local_weather.cloud_vertical_size_map["Cirrocumulus"];
1483
1484         #create_4_8_cirrocumulus_undulatus(blat, blon, alt+alt_offset + size_offset + 6000.0, alpha);
1485         create_2_8_perlucidus_mackerel(blat, blon, alt+alt_offset + size_offset + 6000.0, alpha);
1486         
1487         # and specify the atmosphere
1488         local_weather.set_atmosphere_ipoint(blat, blon, vis + 1000.0, alt+alt_offset, vis + 3000.0, 0.2, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.72, alt+alt_offset, alt+alt_offset + 2500.0); 
1489         }
1490
1491 else if (rn > 0.0)
1492         {
1493         # cloud scenario 5: weak Cumulus development under scattered Altostratus 
1494
1495         strength = 0.15 + rand() * 0.15;
1496         local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);    
1497
1498         var size_offset = 0.5 * m_to_ft * local_weather.cloud_vertical_size_map["Stratus_structured"];
1499         
1500         local_weather.create_streak("Stratus (structured)",blat, blon, alt+4000.0+alt_offset+size_offset,1000.0,14,0.0,0.3,20000.0,14,0.0,0.3,20000.0,0.0,1.0);
1501
1502         # and specify the atmosphere
1503         local_weather.set_atmosphere_ipoint(blat, blon, vis + 2000.0, alt+alt_offset, vis + 4000.0, 0.15, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.73, alt+alt_offset, alt+alt_offset + 2500.0); 
1504
1505         }
1506
1507 # store convective altitude and strength
1508
1509 append(weather_dynamics.tile_convective_altitude,alt);
1510 append(weather_dynamics.tile_convective_strength,strength);
1511
1512 tile_finished();
1513
1514 }
1515
1516
1517
1518 ####################################
1519 # Tropical weather
1520 ####################################
1521
1522 var set_tropical_weather_tile = func {
1523
1524 setprop(lw~"tiles/code","tropical_weather");
1525
1526 tile_start();
1527
1528 var x = 0.0;
1529 var y = 0.0;
1530 var lat = 0.0;
1531 var lon = 0.0;
1532
1533 var sec_to_rad = 2.0 * math.pi/86400; # conversion factor for sinusoidal dependence on daytime
1534
1535 # get the local time of the day in seconds
1536
1537 var t = getprop("sim/time/utc/day-seconds");
1538 t = t + getprop("sim/time/local-offset");
1539
1540 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1541 var phi = alpha * math.pi/180.0;
1542 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
1543
1544 # get tile center coordinates
1545
1546 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1547 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1548 calc_geo(blat);
1549
1550 # get probabilistic values for the weather parameters
1551
1552 var vis = 9000.0 + rand() * 10000.0;
1553 var T = 20.0 + rand() * 15.0;
1554 var spread = 8.0 + 2.0 * rand();
1555 var D = T - spread;
1556 var p = 970 + rand() * 10.0; p = adjust_p(p);
1557
1558 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1559
1560 # first weather info for tile center (lat, lon, visibility, temperature, dew point, pressure)
1561
1562 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
1563
1564 # altitude for the lowest layer
1565 var alt = spread * 400.0;
1566 var strength = 0.0;
1567
1568 # bias Cumulus clouds towards larger sizes due to lots of water vapour
1569 local_weather.convective_size_bias = 0.3 + rand() * 0.3;
1570
1571 # tropical weather has a strong daily variation, call thunderstorm only in the correct afternoon time window
1572
1573 var t_factor = 0.5 * (1.0-math.cos((t * sec_to_rad)-0.9)); 
1574
1575 var rn = rand();
1576
1577
1578 if (rn > (t_factor * t_factor * t_factor * t_factor)) # call a normal convective cloud system
1579 {
1580 strength = 1.0 + rand() * 0.2;
1581 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1582
1583 # and specify the atmosphere
1584 local_weather.set_atmosphere_ipoint(blat, blon, vis + 15000.0, alt+alt_offset, vis + 20000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.7, alt+alt_offset, alt+alt_offset + 2500.0); 
1585 }
1586
1587 else 
1588 {
1589
1590 # a random selection of different possible thunderstorm cloud configuration scenarios
1591
1592 rn = rand();
1593
1594 if (rand() < small_scale_persistence)
1595         {rn = rnd_store;}
1596 else
1597         {rnd_store = rn;}
1598
1599 if (rn > 0.2)
1600         {
1601         # cloud scenario 1: 1-2 medium sized storms
1602
1603         x = 2.0 * (rand()-0.5) * 12000;
1604         y = 2.0 * (rand()-0.5) * 12000;
1605
1606         if (rand() > 0.6)
1607                 {create_medium_thunderstorm(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt+alt_offset, alpha);}
1608         else    
1609                 {create_small_thunderstorm(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt+alt_offset, alpha);}
1610
1611         if (rand() > 0.5) # we do a second thunderstorm
1612                 {
1613                 x = 2.0 * (rand()-0.5) * 12000;
1614                 y = 2.0 * (rand()-0.5) * 12000;
1615                 if (rand() > 0.8)
1616                         {create_medium_thunderstorm(blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset, alpha);}
1617                 else
1618                         {create_small_thunderstorm(blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset, alpha);}
1619                 }
1620
1621         # and specify the atmosphere
1622         local_weather.set_atmosphere_ipoint(blat, blon, vis + 12000.0, alt+alt_offset, vis + 20000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.65, alt+alt_offset, alt+alt_offset + 2500.0); 
1623         }
1624 else if (rn > 0.0)
1625         {
1626         # cloud scenario 2: Single big storm
1627
1628         x = 2.0 * (rand()-0.5) * 12000;
1629         y = 2.0 * (rand()-0.5) * 12000;
1630
1631         create_big_thunderstorm(blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset, alpha);
1632
1633         # and specify the atmosphere
1634         local_weather.set_atmosphere_ipoint(blat, blon, vis + 12000.0, alt+alt_offset, vis + 20000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.65, alt+alt_offset, alt+alt_offset + 2500.0); 
1635         }
1636
1637
1638 # the convective layer
1639
1640 var strength = 0.5 * t_factor;
1641 var n = int(4000 * strength) * 0.2;
1642 local_weather.cumulus_exclusion_layer(blat, blon, alt+alt_offset, n, 20000.0, 20000.0, alpha, 0.3,1.4 , size(elat), elat, elon, erad);
1643 local_weather.cumulus_exclusion_layer(blat, blon, alt+alt_offset, n, 20000.0, 20000.0, alpha, 1.9,2.5 , size(elat), elat, elon, erad);
1644
1645 # some turbulence in the convection layer
1646
1647 local_weather.create_effect_volume(3, blat, blon, 20000.0, 20000.0, alpha, 0.0, alt+3000.0+alt_offset, -1, -1, -1, 0.4, -1,0 ,-1);
1648
1649 } # end thundercloud placement
1650
1651 # store convective altitude and strength
1652
1653 append(weather_dynamics.tile_convective_altitude,alt);
1654 append(weather_dynamics.tile_convective_strength,strength);
1655
1656 tile_finished();
1657
1658 }
1659
1660
1661
1662
1663 ####################################
1664 # Thunderstorms
1665 ####################################
1666
1667 var set_thunderstorms_tile = func {
1668
1669 setprop(lw~"tiles/code","thunderstorms");
1670
1671 tile_start();
1672
1673 var x = 0.0;
1674 var y = 0.0;
1675 var lat = 0.0;
1676 var lon = 0.0;
1677
1678
1679 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1680 var phi = alpha * math.pi/180.0;
1681 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
1682
1683 # get tile center coordinates
1684
1685 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1686 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1687 calc_geo(blat);
1688
1689 # get probabilistic values for the weather parameters
1690
1691 var vis = 9000.0 + rand() * 10000.0;
1692 var T = 10.0 + rand() * 15.0;
1693 var spread = 6.0 + 2.0 * rand();
1694 var D = T - spread;
1695 var p = 1000 + rand() * 10.0; p = adjust_p(p);
1696
1697 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1698
1699 # first weather info for tile center (lat, lon, visibility, temperature, dew point, pressure)
1700
1701 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
1702
1703 # altitude for the lowest layer
1704 var alt = spread * 400.0;
1705 var strength = 0.0;
1706
1707 # bias Cumulus clouds towards larger sizes due to lots of water vapour
1708 local_weather.convective_size_bias = 0.3 + rand() * 0.3;
1709
1710
1711 # and specify the atmosphere
1712         local_weather.set_atmosphere_ipoint(blat, blon, vis + 12000.0, alt+alt_offset, vis + 20000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0); 
1713
1714 var rn = rand();
1715
1716
1717 if (rand() < small_scale_persistence)
1718         {rn = rnd_store;}
1719 else
1720         {rnd_store = rn;}
1721
1722 create_thunderstorm_scenario (blat, blon, alt + alt_offset, alpha);
1723
1724 # store convective altitude and strength
1725
1726 append(weather_dynamics.tile_convective_altitude,alt);
1727 append(weather_dynamics.tile_convective_strength,strength);
1728
1729 tile_finished();
1730
1731 }
1732
1733
1734
1735
1736
1737 ####################################
1738 # Coldfront
1739 ####################################
1740
1741
1742 var set_coldfront_tile = func {
1743
1744 setprop(lw~"tiles/code","coldfront");
1745
1746 tile_start();
1747
1748 var x = 0.0;
1749 var y = 0.0;
1750 var lat = 0.0;
1751 var lon = 0.0;
1752
1753
1754
1755 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1756 var phi = alpha * math.pi/180.0;
1757 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
1758
1759 # get tile center coordinates
1760
1761 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1762 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1763 calc_geo(blat);
1764
1765 # get probabilistic values for the weather parameters
1766
1767 var vis = 20000.0 + rand() * 10000.0;
1768 var T = 20.0 + rand() * 8.0;
1769 var spread = 8.0 + 2.0 * rand();
1770 var D = T - spread;
1771 var p = 1005 + rand() * 10.0; p = adjust_p(p);
1772
1773 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1774
1775 # first weather info for tile  (lat, lon, visibility, temperature, dew point, pressure)
1776
1777 # after the front
1778
1779 x = 15000.0; y = 15000.0;
1780 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T-3.0, D-3.0, p * hp_to_inhg);
1781
1782 x = -15000.0; y = 15000.0;
1783 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T-3.0, D-3.0, p * hp_to_inhg);
1784
1785 # before the front
1786
1787 x = 15000.0; y = -15000.0;
1788 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis*0.7, T+3.0, D+3.0, (p-2.0) * hp_to_inhg);
1789
1790 x = -15000.0; y = -15000.0;
1791 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis*0.7, T+3.0, D+3.0, (p-2.0) * hp_to_inhg);
1792
1793 # altitude for the lowest layer
1794 var alt = spread * 400.0;
1795 var strength = 0.0;
1796
1797 # thunderstorms first
1798
1799 for (var i =0; i < 3; i=i+1)
1800         {
1801         x = 2.0 * (rand()-0.5) * 15000;
1802         y = 2.0 * (rand()-0.5) * 2000 + 5000.0;
1803         if (rand() > 0.7)
1804                 {create_medium_thunderstorm(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt+alt_offset, alpha);}
1805         else    
1806                 {create_small_thunderstorm(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt+alt_offset, alpha);}
1807         }
1808
1809 # next the dense cloud layer underneath the thunderstorms
1810
1811 x = 0.0;
1812 y = 5000.0;
1813
1814 var strength = 0.3;
1815 var n = int(4000 * strength) * 0.2;
1816 local_weather.cumulus_exclusion_layer(blat+get_lat(x,y,phi), blon+ get_lon(x,y,phi), alt+alt_offset, n, 20000.0, 10000.0, alpha, 1.5,2.5 , size(elat), elat, elon, erad);
1817
1818 # then leading and traling Cumulus
1819
1820 x = 0.0;
1821 y = 15500.0;
1822
1823 strength = 1.0;
1824 n = int(4000 * strength) * 0.15;
1825 local_weather.cumulus_exclusion_layer(blat+get_lat(x,y,phi), blon+ get_lon(x,y,phi), alt+alt_offset, n, 20000.0, 2000.0, alpha, 0.5,1.8 , size(elat), elat, elon, erad);
1826
1827 x = 0.0;
1828 y = -5500.0;
1829
1830 strength = 1.0;
1831 n = int(4000 * strength) * 0.15;
1832 local_weather.cumulus_exclusion_layer(blat+get_lat(x,y,phi), blon+ get_lon(x,y,phi), alt+alt_offset, n, 20000.0, 2000.0, alpha, 0.5,1.8 , size(elat), elat, elon, erad);
1833
1834 # finally some thin stratus underneath the Cumulus
1835
1836 x = 0.0;
1837 y = 13000.0;
1838 local_weather.create_streak("Stratus (thin)",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset,0.0,20,2000.0,0.2,1200.0,3,1500.0,0.2,1200.0,alpha,1.0);
1839
1840
1841 x = 0.0;
1842 y = -3000.0;
1843 local_weather.create_streak("Stratus (thin)",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset,0.0,20,2000.0,0.2,1200.0,3,1500.0,0.2,1200.0,alpha,1.0);
1844
1845
1846 # some turbulence in the convection layer
1847
1848 x=0.0; y = 5000.0;
1849 local_weather.create_effect_volume(3, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 20000.0, 11000.0, alpha, 0.0, alt+3000.0+alt_offset, -1, -1, -1, 0.4, -1,0 ,-1);
1850
1851 # some rain and reduced visibility in its core 
1852
1853 x=0.0; y = 5000.0;
1854 local_weather.create_effect_volume(3, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 20000.0, 8000.0, alpha, 0.0, alt+alt_offset, 10000.0, 0.1, -1, -1, -1,0,-1 );
1855
1856 # and specify the atmosphere
1857 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 20000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.6, alt+alt_offset, alt+alt_offset + 2500.0); 
1858
1859 # store convective altitude and strength
1860
1861 append(weather_dynamics.tile_convective_altitude,alt);
1862 append(weather_dynamics.tile_convective_strength,strength);
1863
1864 tile_finished();
1865
1866 }
1867
1868
1869 ####################################
1870 # Warmfront 1
1871 ####################################
1872
1873
1874 var set_warmfront1_tile = func {
1875
1876 setprop(lw~"tiles/code","warmfront1");
1877
1878 tile_start();
1879
1880 var x = 0.0;
1881 var y = 0.0;
1882 var lat = 0.0;
1883 var lon = 0.0;
1884
1885
1886
1887 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1888 var phi = alpha * math.pi/180.0;
1889
1890 if (local_weather.presampling_flag == 0)
1891         {var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
1892 else
1893         {var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
1894
1895 # get tile center coordinates
1896
1897 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1898 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1899 calc_geo(blat);
1900
1901 # get probabilistic values for the weather parameters
1902
1903 var vis = 20000.0 + rand() * 5000.0;
1904 var T = 10.0 + rand() * 8.0;
1905 var spread = 9.0 + 4.0 * rand();
1906 var D = T - spread;
1907 var p = 1005 + rand() * 10.0; p = adjust_p(p);
1908
1909 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1910
1911 # first weather info for tile  (lat, lon, visibility, temperature, dew point, pressure)
1912
1913 # after the front
1914
1915 x = 15000.0; y = 15000.0;
1916 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
1917
1918 x = -15000.0; y = 15000.0;
1919 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
1920
1921 # before the front
1922
1923 x = 15000.0; y = -15000.0;
1924 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
1925
1926 x = -15000.0; y = -15000.0;
1927 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
1928
1929 # altitude for the lowest layer
1930 var alt = spread * 400.0;
1931
1932 # some weak Cumulus development
1933
1934 var strength = 0.1 + rand() * 0.1;
1935 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1936
1937
1938 # high Cirrus leading
1939
1940 x = 2.0 * (rand()-0.5) * 1000;
1941 y = 2.0 * (rand()-0.5) * 1000 - 9000.0; 
1942         
1943
1944 local_weather.create_streak("Cirrus",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 25000.0+alt+alt_offset,1500.0,3,11000.0,0.0, 3000.0, 2,11000.0,0.0,3000.0,alpha ,1.0);
1945
1946
1947 # followed by random patches of Cirrostratus
1948
1949 for (var i=0; i<6; i=i+1)
1950         {
1951         var x = 2.0 * (rand()-0.5) * 15000;
1952         var y = 2.0 * (rand()-0.5) * 10000 + 10000;
1953         var beta = (rand() -0.5) * 180.0;
1954         var alt_shift = 0.0;
1955         if (local_weather.hardcoded_clouds_flag == 1) {alt_shift = local_weather.offset_map["Cirrostratus"];}
1956
1957         local_weather.create_streak("Cirrostratus",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 18000 + alt + alt_offset - alt_shift,300.0,4,2300.0,0.2,600.0,4,2300.0,0.2,600.0,alpha+beta,1.0);
1958
1959         }
1960
1961 # and specify the atmosphere
1962 local_weather.set_atmosphere_ipoint(blat, blon, vis + 8000.0, alt+alt_offset, vis + 10000.0, rand() * 0.1, alt+alt_offset +18000.0, alt+alt_offset + 22000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0); 
1963
1964 # store convective altitude and strength
1965
1966 append(weather_dynamics.tile_convective_altitude,alt);
1967 append(weather_dynamics.tile_convective_strength,strength);
1968
1969 tile_finished();
1970
1971 }
1972
1973
1974 ####################################
1975 # Warmfront 2
1976 ####################################
1977
1978
1979 var set_warmfront2_tile = func {
1980
1981 setprop(lw~"tiles/code","warmfront2");
1982
1983 tile_start();
1984
1985 var x = 0.0;
1986 var y = 0.0;
1987 var lat = 0.0;
1988 var lon = 0.0;
1989
1990
1991
1992 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1993 var phi = alpha * math.pi/180.0;
1994
1995 if (local_weather.presampling_flag == 0)
1996         {var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
1997 else
1998         {var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
1999
2000 # get tile center coordinates
2001
2002 var blat = getprop(lw~"tiles/tmp/latitude-deg");
2003 var blon = getprop(lw~"tiles/tmp/longitude-deg");
2004 calc_geo(blat);
2005
2006 # get probabilistic values for the weather parameters
2007
2008 var vis = 15000.0 + rand() * 5000.0;
2009 var T = 13.0 + rand() * 8.0;
2010 var spread = 8.0 + 2.0 * rand();
2011 var D = T - spread;
2012 var p = 1005 + rand() * 10.0; p = adjust_p(p);
2013
2014 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
2015
2016 # first weather info for tile  (lat, lon, visibility, temperature, dew point, pressure)
2017
2018 # after the front
2019
2020 x = 15000.0; y = 15000.0;
2021 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
2022
2023 x = -15000.0; y = 15000.0;
2024 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
2025
2026 # before the front
2027
2028 x = 15000.0; y = -15000.0;
2029 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
2030
2031 x = -15000.0; y = -15000.0;
2032 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
2033
2034 # altitude for the lowest layer
2035 var alt = spread * 400.0;
2036 var strength = 0.0;
2037
2038 # followed by random patches of Cirrostratus
2039
2040 var alt_shift = 0.0;
2041 if (local_weather.hardcoded_clouds_flag == 1) {alt_shift = local_weather.offset_map["Cirrostratus"];}
2042
2043 for (var i=0; i<3; i=i+1)
2044         {
2045         var x = 2.0 * (rand()-0.5) * 18000;
2046         var y = 2.0 * (rand()-0.5) * 5000 - 15000;
2047         var beta = (rand() -0.5) * 180.0;
2048         local_weather.create_streak("Cirrostratus",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 15000 + alt + alt_offset - alt_shift,300.0,4,2300.0,0.2,600.0,4,2300.0,0.2,600.0,alpha+beta,1.0);
2049
2050         }
2051
2052 # patches of thin Altostratus
2053
2054 for (var i=0; i<14; i=i+1)
2055         {
2056         var x = 2.0 * (rand()-0.5) * 18000;
2057         var y = 2.0 * (rand()-0.5) * 9000 - 10000.0;
2058         var beta = (rand() -0.5) * 180.0;
2059         local_weather.create_streak("Stratus (thin)",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset +12000.0,300.0,4,950.0,0.2,500.0,6,950.0,0.2,500.0,alpha+beta,1.0);
2060
2061         }
2062
2063 # patches of structured Stratus
2064
2065 for (var i=0; i<10; i=i+1)
2066         {
2067         var x = 2.0 * (rand()-0.5) * 9000;
2068         var y = 2.0 * (rand()-0.5) * 9000 + 2000;
2069         var beta = (rand() -0.5) * 180.0;
2070         local_weather.create_streak("Stratus (structured)",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset+9000.0,300.0,5,900.0,0.2,500.0,7,900.0,0.2,500.0,alpha+beta,1.0);
2071
2072         }
2073
2074
2075 # merging with a broken Stratus layer
2076
2077 var x = 0.0;
2078 var y = 8000.0;
2079
2080 local_weather.create_streak("Stratus",blat +get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset +5000.0,1000.0,30,0.0,0.2,20000.0,10,0.0,0.2,12000.0,alpha,1.0);
2081
2082
2083 # and specify the atmosphere
2084 local_weather.set_atmosphere_ipoint(blat, blon, vis + 6000.0, alt+alt_offset, vis + 8000.0, 0.15 + rand() * 0.15, alt+alt_offset +17000.0, alt+alt_offset + 21000.0, 0.7, alt+alt_offset, alt+alt_offset + 2500.0); 
2085
2086 # store convective altitude and strength
2087
2088 append(weather_dynamics.tile_convective_altitude,alt);
2089 append(weather_dynamics.tile_convective_strength,strength);
2090
2091 tile_finished();
2092
2093 }
2094
2095
2096 ####################################
2097 # Warmfront 3
2098 ####################################
2099
2100
2101 var set_warmfront3_tile = func {
2102
2103 setprop(lw~"tiles/code","warmfront3");
2104
2105 tile_start();
2106
2107 var x = 0.0;
2108 var y = 0.0;
2109 var lat = 0.0;
2110 var lon = 0.0;
2111
2112
2113
2114 var alpha = getprop(lw~"tmp/tile-orientation-deg");
2115 var phi = alpha * math.pi/180.0;
2116
2117 if (local_weather.presampling_flag == 0)
2118         {var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
2119 else
2120         {var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
2121
2122 # get tile center coordinates
2123
2124 var blat = getprop(lw~"tiles/tmp/latitude-deg");
2125 var blon = getprop(lw~"tiles/tmp/longitude-deg");
2126 calc_geo(blat);
2127
2128 # get probabilistic values for the weather parameters
2129
2130 var vis = 12000.0 + rand() * 3000.0;
2131 var T = 15.0 + rand() * 7.0;
2132 var spread = 7.0 + 2.0 * rand();
2133 var D = T - spread;
2134 var p = 1005 + rand() * 10.0; p = adjust_p(p);
2135
2136 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
2137
2138 # first weather info for tile  (lat, lon, visibility, temperature, dew point, pressure)
2139
2140 # after the front
2141
2142 x = 15000.0; y = 15000.0;
2143 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
2144
2145 x = -15000.0; y = 15000.0;
2146 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
2147
2148 # before the front
2149
2150 x = 15000.0; y = -15000.0;
2151 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
2152
2153 x = -15000.0; y = -15000.0;
2154 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
2155
2156 # altitude for the lowest layer
2157 var alt = spread * 400.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft;
2158 var strength = 0.0;
2159
2160 # closed Stratus layer
2161
2162 var x = 0.0;
2163 var y = -8000.0;
2164
2165 local_weather.create_streak("Stratus",blat +get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset +1000.0,500.0,32,1250.0,0.2,400.0,20,1250.0,0.2,400.0,alpha,1.0);
2166
2167
2168
2169
2170
2171 # merging with a Nimbostratus layer
2172
2173 var x = 0.0;
2174 var y = 8000.0;
2175
2176 local_weather.create_streak("Nimbus",blat +get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset,500.0,32,1250.0,0.0,200.0,20,1250.0,0.0,200.0,alpha,1.0);
2177
2178
2179
2180 # some rain beneath the stratus
2181
2182 x=0.0; y = -10000.0;
2183 local_weather.create_effect_volume(3, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 20000.0, 10000.0, alpha, 0.0, alt+alt_offset+1000, vis * 0.7, 0.1, -1, -1, -1,0 ,-1);
2184
2185 # heavier rain beneath the Nimbostratus
2186
2187 x=0.0; y = 10000.0;
2188 local_weather.create_effect_volume(3, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 20000.0, 10000.0, alpha, 0.0, alt+alt_offset, vis * 0.5, 0.3, -1, -1, -1,0,-1 );
2189
2190
2191 # and specify the atmosphere
2192 local_weather.set_atmosphere_ipoint(blat, blon, vis + 6000.0, alt+alt_offset, vis + 8000.0, 0.05 + rand() * 0.05, alt+alt_offset +16000.0, alt+alt_offset + 20000.0, 0.6, alt+alt_offset, alt+alt_offset + 2500.0); 
2193
2194
2195 # store convective altitude and strength
2196
2197 append(weather_dynamics.tile_convective_altitude,alt);
2198 append(weather_dynamics.tile_convective_strength,strength);
2199
2200 tile_finished();
2201
2202 }
2203
2204
2205 ####################################
2206 # Warmfront 4
2207 ####################################
2208
2209
2210 var set_warmfront4_tile = func {
2211
2212 setprop(lw~"tiles/code","warmfront4");
2213
2214 tile_start();
2215
2216 var x = 0.0;
2217 var y = 0.0;
2218 var lat = 0.0;
2219 var lon = 0.0;
2220
2221
2222
2223 var alpha = getprop(lw~"tmp/tile-orientation-deg");
2224 var phi = alpha * math.pi/180.0;
2225
2226 if (local_weather.presampling_flag == 0)
2227         {var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
2228 else
2229         {var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
2230
2231 # get tile center coordinates
2232
2233 var blat = getprop(lw~"tiles/tmp/latitude-deg");
2234 var blon = getprop(lw~"tiles/tmp/longitude-deg");
2235 calc_geo(blat);
2236
2237 # get probabilistic values for the weather parameters
2238
2239 var vis = 12000.0 + rand() * 3000.0;
2240 var T = 17.0 + rand() * 6.0;
2241 var spread = 5.0 + 2.0 * rand();
2242 var D = T - spread;
2243 var p = 1005 + rand() * 10.0; p = adjust_p(p);
2244
2245 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
2246
2247 # first weather info for tile  (lat, lon, visibility, temperature, dew point, pressure)
2248
2249 # after the front
2250
2251 x = 15000.0; y = 15000.0;
2252 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
2253
2254 x = -15000.0; y = 15000.0;
2255 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
2256
2257 # before the front
2258
2259 x = 15000.0; y = -15000.0;
2260 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
2261
2262 x = -15000.0; y = -15000.0;
2263 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
2264
2265 # altitude for the lowest layer
2266 var alt = spread * 400.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft;
2267 var strength = 0.0;
2268
2269 # low Nimbostratus layer
2270
2271 var x = 0.0;
2272 var y = -5000.0;
2273
2274 local_weather.create_streak("Nimbus",blat +get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset,500.0,32,1250.0,0.0,200.0,24,1250.0,0.0,200.0,alpha,1.0);
2275
2276
2277 # a little patchy structured Stratus above for effect
2278
2279 create_2_8_sstratus(blat, blon, alt+alt_offset+3000.0, alpha); 
2280
2281 # eventually breaking up
2282
2283 var x = 0.0;
2284 var y = 14000.0;
2285
2286 local_weather.create_streak("Nimbus",blat +get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset,500.0,25,1600.0,0.2,200.0,9,1400.0,0.3,200.0,alpha,1.0);
2287
2288
2289
2290 # rain beneath the Nimbostratus
2291
2292 x=0.0; y = -5000.0;
2293 local_weather.create_effect_volume(3, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 20000.0, 15000.0, alpha, 0.0, alt+alt_offset, vis * 0.5, 0.3, -1, -1, -1,0 ,-1);
2294
2295
2296 # and specify the atmosphere
2297 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 12000.0, 0.1, alt+alt_offset +16000.0, alt+alt_offset + 20000.0, 0.5, alt+alt_offset, alt+alt_offset + 2500.0); 
2298
2299 # store convective altitude and strength
2300
2301 append(weather_dynamics.tile_convective_altitude,alt);
2302 append(weather_dynamics.tile_convective_strength,strength);
2303
2304 tile_finished();
2305
2306 }
2307
2308
2309
2310 ####################################
2311 # METAR
2312 ####################################
2313
2314 var set_METAR_tile = func {
2315
2316
2317 setprop(lw~"tiles/code","METAR"); 
2318
2319 tile_start();
2320
2321 var x = 0.0;
2322 var y = 0.0;
2323 var lat = 0.0;
2324 var lon = 0.0;
2325
2326
2327
2328 var alpha = getprop("/environment/metar/base-wind-dir-deg");
2329 var phi = alpha * math.pi/180.0;
2330
2331 # it seems more recent Flightgear versions have absolute altitude
2332 # var metar_alt_offset = 700.0 + getprop("/environment/metar/station-elevation-ft");
2333 var metar_alt_offset = 700.0;
2334
2335 # print("metar_alt_offset", metar_alt_offset);
2336
2337 # get the local time of the day in seconds
2338
2339 var t = getprop("sim/time/utc/day-seconds");
2340 t = t + getprop("sim/time/local-offset");
2341
2342 # get tile center coordinates
2343
2344 var blat = getprop(lw~"tiles/tmp/latitude-deg");
2345 var blon = getprop(lw~"tiles/tmp/longitude-deg");
2346 calc_geo(blat);
2347
2348 var rain_norm = getprop("/environment/metar/rain-norm");
2349 var snow_norm = getprop("/environment/metar/snow-norm");
2350 var p = inhg_to_hp * getprop("/environment/metar/pressure-sea-level-inhg");
2351
2352 # now get the cloud layer info
2353
2354 var layers = props.globals.getNode("/environment/metar/clouds", 1).getChildren("layer");
2355 var n_layers = size(layers); # the system initializes with  4 layers, but who knows...
2356 var n = 0; # start with lowest layer
2357
2358 # now determine the nature of the lowest layer
2359
2360 var cumulus_flag = 1; # default assumption - the lowest layer is cumulus 
2361 var thunderstorm_flag = 0;
2362 var cover_low = 8 - 2 * layers[0].getNode("coverage-type").getValue(); # conversion to oktas
2363 var alt_low = layers[0].getNode("elevation-ft").getValue();
2364
2365 # print("alt_low: ", alt_low);
2366
2367 if ((alt_low < 0.0) or (cover_low ==0)) # we have to guess a value for the convective altitude for the visibility model
2368         {alt_low = 8000.0;}
2369
2370 # first check a few obvious criteria
2371
2372 if (cover_low == 8) {cumulus_flag = 0;} # overcast sky is unlikely to be Cumulus, and we can't render it anyway
2373 if ((rain_norm > 0.0) or (snow_norm > 0.0)) {cumulus_flag = 0;} # Cumulus usually doesn't rain
2374 if (alt_low > 7000.0) {cumulus_flag = 0;} # Cumulus are low altitude clouds
2375
2376 # now try matching time evolution of cumuli
2377
2378 if ((cover_low == 5) or (cover_low == 6) or (cover_low == 7)) # broken
2379         {
2380         if ((t < 39600) or (t > 68400)) {cumulus_flag = 0;} # not before 11:00 and not after 19:00
2381         }
2382
2383 if ((cover_low == 3) or (cover_low == 4)) # scattered
2384         {
2385         if ((t < 32400) or (t > 75600)) {cumulus_flag = 0;} # not before 9:00 and not after 21:00
2386         }
2387
2388 # now see if there is a layer shading convective development
2389
2390 var coverage_above = 8 - 2 * layers[1].getNode("coverage-type").getValue(); 
2391 var coverage_above2 = 8 - 2 * layers[2].getNode("coverage-type").getValue(); 
2392
2393 if (coverage_above2 > coverage_above)
2394         {coverage_above = coverage_above2;}
2395
2396 if (coverage_above > 6) {cumulus_flag = 0;} # no Cumulus with strong layer above
2397
2398 # never do Cumulus when there's a thunderstorm
2399 if (getprop(lw~"METAR/thunderstorm-flag") ==1) {cumulus_flag = 0; thunderstorm_flag = 1;} 
2400
2401 # if cumulus_flag is still 1 at this point, the lowest layer is Cumulus
2402 # see if we need to adjust its strength 
2403
2404 if ((cumulus_flag == 1) and (cover_low > 0))
2405         {
2406         if ((cover_low < 4) and (t > 39600) and (t < 68400)) {var strength = 0.4;}
2407         if ((cover_low < 2) and (t > 39600) and (t < 68400)) {var strength = 0.2;}
2408         else {var strength = 1.0;}
2409         local_weather.create_cumosys(blat,blon, alt_low+metar_alt_offset,get_n(strength), 20000.0);
2410         n = n + 1; # do not start parsing with lowest layer
2411         }       
2412 else    
2413         {var strength = 0.0;}
2414
2415
2416 # if thunderstorm_flag is 1, we do the lowest layer as thunderstorm scenario, somewhat ignoring the coverage info
2417
2418 if (thunderstorm_flag == 1)
2419         {
2420         create_thunderstorm_scenario(blat, blon, alt_low+metar_alt_offset, alpha);
2421         n = n + 1; # do not start parsing with lowest layer
2422         }
2423
2424
2425 for (var i = n; i <n_layers; i=i+1)
2426         {
2427         var altitude = layers[i].getNode("elevation-ft").getValue();
2428         # print("altitude: ",altitude);
2429         var cover = 8 - 2 * layers[i].getNode("coverage-type").getValue();
2430
2431         if (cover == -2) {break;} # a clear cover layer indicates we are done
2432
2433         if (n > 0) { rain_norm = 0.0; snow_norm = 0.0;} # rain and snow fall only from the lowest layer
2434
2435         if (altitude < 9000.0) # draw Nimbostratus or Stratus models
2436                 {       
2437                 if (cover == 8) 
2438                         {
2439                         if ((altitude < 2000) or (rain_norm > 0.3))
2440                                 {create_8_8_nimbus_rain(blat, blon, altitude+metar_alt_offset, alpha, rain_norm);}
2441                         else 
2442                                 {create_8_8_stratus_rain(blat, blon, altitude+metar_alt_offset, alpha, rain_norm);}
2443                         }
2444                 else if ((cover < 8) and (cover > 4))
2445                         {
2446                         if (cumulus_flag == 1)
2447                                 {
2448                                 create_4_8_sstratus_patches(blat, blon, altitude+metar_alt_offset, alpha);
2449                                 }
2450                         else
2451                                 {
2452                                 if ((rain_norm > 0.1) and (altitude < 5000.0))
2453                                         {       
2454                                         create_6_8_nimbus_rain(blat, blon, altitude+metar_alt_offset, alpha, rain_norm);
2455                                         }
2456                                 else if (rain_norm > 0.0)
2457                                         {
2458                                         create_6_8_stratus_rain(blat, blon, altitude+metar_alt_offset, alpha, rain_norm);
2459                                         }
2460                                 else
2461                                         {
2462                                         if ((p > 1010.0) and (i == 0)) # the lowest layer may be Stratocumulus
2463                                                 {
2464                                                 create_6_8_stratocumulus(blat, blon, altitude+metar_alt_offset, alpha);
2465                                                 }
2466                                         else
2467                                                 {
2468                                                 if (rand() > 0.5)                                       
2469                                                         {create_6_8_stratus(blat, blon, altitude+metar_alt_offset, alpha);}
2470                                                 else
2471                                                         {create_6_8_stratus_undulatus(blat, blon, altitude+metar_alt_offset, alpha);}
2472                                                 }
2473                                         }
2474                                 }
2475                         }
2476                 else if ((cover == 3) or (cover == 4))
2477                         {
2478                         if ((p > 1010.0) and (i == 0)) # the lowest layer may be Stratocumulus          
2479                                 {
2480                                 create_4_8_stratocumulus(blat, blon, altitude+metar_alt_offset, alpha);
2481                                 }
2482                         else
2483                                 {
2484                                 var rn = rand();
2485                                 if (rn > 0.8)
2486                                         {create_4_8_stratus(blat, blon, altitude+metar_alt_offset, alpha);}
2487                                 else if (rn > 0.6)
2488                                         {create_4_8_stratus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
2489                                 else if (rn > 0.4)
2490                                         {create_4_8_sstratus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
2491                                 else if (rn > 0.2)
2492                                         {create_4_8_sstratus_bundle(blat, blon, altitude+metar_alt_offset, alpha);}
2493                                 else if (rn > 0.0)
2494                                         {create_4_8_sstratus_undulatus(blat, blon, altitude+metar_alt_offset, alpha);}
2495                                 }
2496                         }
2497                 else 
2498                         {
2499                         if (cumulus_flag == 0)
2500                                 {
2501                                 var rn = rand();
2502                                 if (rn > 0.3)
2503                                         {create_2_8_stratus(blat, blon, altitude+metar_alt_offset, alpha);}
2504                                 else if (rn > 0.6)
2505                                         {create_2_8_sstratus_bundle(blat, blon, altitude+metar_alt_offset, alpha);}
2506                                 else
2507                                         {create_2_8_sstratus_hires_bundle(blat, blon, altitude+metar_alt_offset, alpha);}
2508                                 }
2509                         else 
2510                                 {
2511                                 create_2_8_altocumulus_streaks(blat, blon, altitude+metar_alt_offset, alpha);
2512                                 }
2513                         }
2514                 } # end if altitude
2515         else if ((altitude > 9000.0) and (altitude < 20000.0)) # select thin cloud layers
2516                 {
2517                 if (cover == 8) 
2518                         {
2519                         if (altitude < 14000.0)
2520                                 {create_8_8_tstratus(blat, blon, altitude+metar_alt_offset, alpha);}
2521                         else
2522                                 {create_8_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
2523                         }
2524                 else if (cover > 4)
2525                         {
2526                         if (altitude < 14000.0)
2527                                 {create_6_8_tstratus_mackerel(blat, blon, altitude+metar_alt_offset, alpha);}
2528                         else
2529                                 {create_6_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
2530                         }
2531                 else if (cover > 2)
2532                         {
2533                         var rn = rand();
2534                         if (rn > 0.75)
2535                                 {create_4_8_tstratus_domains(blat, blon, altitude+metar_alt_offset, alpha);}
2536                         else if (rn > 0.5)
2537                                 {create_4_8_alttstratus_domains(blat, blon, altitude+metar_alt_offset, alpha);}
2538                         else if (rn > 0.25)
2539                                 {create_4_8_alttstratus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
2540                         else if (rn > 0.0)
2541                                 {create_4_8_tstratus_undulatus(blat, blon, altitude+metar_alt_offset, alpha);}
2542                         }
2543                 else
2544                         {
2545                         if (altitude < 14000.0)
2546                                 {       
2547                                 var rn = rand();
2548                                 if (rn > 0.75)                  
2549                                         {create_2_8_tstratus(blat, blon, altitude+metar_alt_offset, alpha);}
2550                                 else if (rn > 0.5)
2551                                         {create_2_8_sstratus_bundle(blat, blon, altitude+metar_alt_offset, alpha);}
2552                                 else if (rn > 0.25)
2553                                         {create_2_8_altocumulus_perlucidus_domains(blat, blon, altitude+metar_alt_offset, alpha);}
2554                                 else if (rn > 0.0)
2555                                         {create_2_8_alttstratus_domains(blat, blon, altitude+metar_alt_offset, alpha);} 
2556                                 }
2557                         else 
2558                                 {
2559                                 var rn = rand();
2560                                 if (rn > 0.9)
2561                                         {create_2_8_cirrocumulus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
2562                                 if (rn > 0.4)
2563                                         {create_1_8_alttstratus_domains(blat, blon, altitude+metar_alt_offset, alpha);}
2564                                 else if (rn > 0.0)
2565                                         {create_2_8_alttstratus_domains(blat, blon, altitude+metar_alt_offset, alpha);} 
2566
2567                                 }
2568                         }
2569                 } # end if altitude
2570         else
2571                 {
2572                 if (cover == 8) 
2573                         {create_8_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
2574                 else if (cover > 4)
2575                         {create_6_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
2576                 else if (cover > 2)
2577                         {
2578                         var rn = rand();
2579                         if (rn > 0.5)
2580                                 {create_4_8_cirrostratus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
2581                         else
2582                                 {create_4_8_cirrostratus_undulatus(blat, blon, altitude+metar_alt_offset, alpha);}
2583                         }
2584                 else
2585                         {
2586                         var rn = rand();
2587                         if (rn > 0.5)
2588                                 {create_2_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
2589                         else
2590                                 {create_1_8_cirrocumulus(blat, blon, altitude+metar_alt_offset, alpha);}
2591
2592                         }
2593
2594                         
2595                 }
2596         } # end for
2597         
2598
2599
2600 # store convective altitude and strength
2601
2602 append(weather_dynamics.tile_convective_altitude,alt_low);
2603 append(weather_dynamics.tile_convective_strength,strength);
2604
2605 tile_finished();
2606 }
2607
2608
2609
2610 ####################################
2611 # METAR station setup
2612 ####################################
2613
2614 var set_METAR_weather_station = func {
2615
2616
2617 # get the METAR position info
2618
2619         var station_lat = getprop("/environment/metar/station-latitude-deg");
2620         var station_lon = getprop("/environment/metar/station-longitude-deg");
2621         var metar_alt_offset = 700.0 + getprop("/environment/metar/station-elevation-ft");
2622
2623
2624         
2625         # get the weather parameters
2626
2627         var vis = getprop("/environment/metar/max-visibility-m");
2628         var T = getprop("/environment/metar/temperature-sea-level-degc");
2629         var D = getprop("/environment/metar/dewpoint-sea-level-degc");
2630         var p = getprop("/environment/metar/pressure-sea-level-inhg");
2631         var rain_norm = getprop("/environment/metar/rain-norm");
2632         var snow_norm = getprop("/environment/metar/snow-norm");
2633
2634         var windspeed = getprop("/environment/metar/base-wind-speed-kt");
2635         var wind_range_from = getprop("/environment/metar/base-wind-range-from");
2636         var wind_range_to = getprop("/environment/metar/base-wind-range-to");
2637
2638         var gust_strength = getprop("/environment/metar/gust-wind-speed-kt");
2639         var alpha = getprop("/environment/metar/base-wind-dir-deg");
2640
2641
2642         # some METAR report just above max. visibility, if so we guess visibility based on pressure
2643
2644         var is_visibility_max = 0;
2645
2646         if (vis == 9999) {is_visibility_max = 1;}
2647
2648         if ((vis > 16093) and (vis < 16094)) # that's 10 nm
2649                 {is_visibility_max = 1;}
2650
2651         if (is_visibility_max == 1) 
2652                         {
2653                         if (p * inhg_to_hp < 1000.0) {vis = 10000.0 + 5000 * rand();}   
2654                         else if (p * inhg_to_hp < 1010.0) {vis = 15000.0 + 7000 * rand();}
2655                         else if (p * inhg_to_hp < 1020.0) {vis = 22000.0 + 14000.0 * rand();}
2656                         else {vis = 30000.0 + 15000.0 * rand();}
2657
2658                         if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
2659                         }
2660
2661
2662
2663         # set the station
2664         local_weather.set_weather_station(station_lat, station_lon, metar_alt_offset, vis, T, D, p);
2665
2666
2667         # get cloud layer info for lighting
2668
2669         var coverage1 = 8 - 2 * getprop("/environment/metar/clouds/layer[0]/coverage-type");    
2670         var layer_alt1 = getprop("/environment/metar/clouds/layer[0]/elevation-ft");    
2671
2672         var coverage2 = 8 - 2 * getprop("/environment/metar/clouds/layer[1]/coverage-type");    
2673         var layer_alt2 = getprop("/environment/metar/clouds/layer[1]/elevation-ft");    
2674
2675         var coverage3 = 8 - 2 * getprop("/environment/metar/clouds/layer[2]/coverage-type");    
2676         var layer_alt3 = getprop("/environment/metar/clouds/layer[2]/elevation-ft");
2677
2678         var coverage4 = 8 - 2 * getprop("/environment/metar/clouds/layer[3]/coverage-type");    
2679         var layer_alt4 = getprop("/environment/metar/clouds/layer[3]/elevation-ft");            
2680
2681
2682         # determine the altitude of the main shading layer
2683
2684         # default assumption - the lowest layer shades
2685         var alt_shade = layer_alt1; var coverage_shade = coverage1; var coverage_mult = 1.0;
2686
2687         # if a higher layer is more opaque, it determines the shading unless it is a thin layer
2688         if ((coverage2 >= coverage1) and (layer_alt2 < 14000.0))
2689                 {alt_shade = layer_alt2; coverage_shade = coverage2; coverage_mult = 0.9;}
2690
2691         if ((coverage3 >= coverage1) and (coverage3 >= coverage2) and (layer_alt3 < 14000.0))
2692                 {alt_shade = layer_alt3; coverage_shade = coverage3; coverage_mult = 0.8;}
2693
2694         # determine the amount of shading
2695
2696         # default assumption: no clouds
2697         var shade = 1.0;
2698
2699         if (coverage_shade < 1) # clear sky, we need to specify an altitude for the model
2700                 {shade = 0.9; alt_shade = 9000.0;}
2701         else if (coverage_shade < 3)
2702                 {shade = 0.85;}
2703         else if (coverage_shade < 5)
2704                 {shade = 0.8;}
2705         else if (coverage_shade < 8)
2706                 {shade = 0.75;}
2707         else if (coverage_shade == 8)
2708                 {shade = 0.7;}
2709
2710         shade = shade * coverage_mult;
2711
2712         # see if we have any high-altitude clouds
2713
2714         var ovcst = 0.0; var ovcst_alt = 20000.0;
2715
2716         if (layer_alt1 > 20000.0)
2717                 {ovcst_alt = layer_alt1; ovcst = ovcst + rand() * 0.1;}
2718         if (layer_alt2 > 20000.0)
2719                 {ovcst_alt = layer_alt2; ovcst = ovcst + rand() * 0.1;}
2720         if (layer_alt3 > 20000.0)
2721                 {ovcst_alt = layer_alt3; ovcst = ovcst + rand() * 0.1;}
2722         if (layer_alt4 > 20000.0)
2723                 {ovcst_alt = layer_alt4; ovcst = ovcst + rand() * 0.1;}
2724                 
2725                 
2726         # and specify the atmosphere - currently default only
2727         local_weather.set_atmosphere_ipoint(station_lat, station_lon, vis + 10000.0, metar_alt_offset + alt_shade, vis + 20000.0, ovcst, ovcst_alt+metar_alt_offset - 5000.0, ovcst_alt+metar_alt_offset, shade, layer_alt1+metar_alt_offset, alt_shade+metar_alt_offset + 2500.0); 
2728
2729         # if we use aloft interpolated winds with METAR, also set a new wind interpolation point
2730         
2731         if ((local_weather.wind_model_flag == 5) and (getprop(lw~"tiles/tile-counter") !=1))
2732                 {
2733                 # if zero winds are reported, we do not rotate the tile to face north but use the last value
2734         
2735                 if ((alpha == 0.0) and (windspeed == 0.0))
2736                         {
2737                         alpha = getprop(lw~"tmp/tile-orientation-deg"); 
2738                         var phi = alpha * math.pi/180.0;
2739                         }
2740
2741
2742                 var boundary_correction = 1.0/local_weather.get_slowdown_fraction();
2743                 local_weather.set_wind_ipoint_metar(station_lat, station_lon, alpha, boundary_correction * windspeed);
2744                 }
2745
2746         # also compute and set gust wind info
2747
2748         var gust_angvar = 0.5 * weather_tile_management.relangle(wind_range_from, wind_range_to);
2749         
2750         if ((gust_strength > 0.0) or (gust_angvar > 0.0))
2751                 {
2752                 var gust_relative_strength = (gust_strength - windspeed)/windspeed;
2753                 setprop(lw~"tmp/gust-frequency-hz", 0.2 + rand()*0.8);
2754                 }
2755         else
2756                 {
2757                 var gust_relative_strength = 0.0;
2758                 setprop(lw~"tmp/gust-frequency-hz", 0.0);
2759                 }
2760
2761
2762         setprop(lw~"tmp/gust-relative-strength", gust_relative_strength);
2763         setprop(lw~"tmp/gust-angular-variation-deg", gust_angvar);
2764         
2765
2766         # and mark that we have used this station
2767         setprop(lw~"METAR/station-id",getprop("/environment/metar/station-id"));
2768
2769
2770 }
2771
2772
2773 ####################################
2774 # mid-level cloud setup calls
2775 ####################################
2776
2777
2778
2779 var create_8_8_tstratus = func (lat, lon, alt, alpha) {
2780
2781 if (local_weather.hardcoded_clouds_flag == 1) 
2782         {
2783         alt = alt - local_weather.offset_map["Stratus_thin"];
2784         
2785 local_weather.create_streak("Stratus (thin)",lat, lon, alt,500.0,40,1000.0,0.0,400.0,40,1000.0,0.0,400.0,alpha,1.0);
2786         }
2787 else
2788         {
2789         local_weather.create_streak("Stratus (thin)",lat, lon, alt,500.0,32,1250.0,0.0,400.0,32,1250.0,0.0,400.0,alpha,1.0);
2790         }
2791 }
2792
2793 var create_8_8_cirrostratus = func (lat, lon, alt, alpha) {
2794
2795 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Cirrostratus"];}
2796
2797 local_weather.create_streak("Cirrostratus",lat,lon,alt,500.0,30,1300.0,0.0,400.0,30,1300.0,0.0,400.0,alpha,1.0);
2798 }
2799
2800 var create_8_8_nimbus = func (lat, lon, alt, alpha) {
2801
2802
2803 local_weather.create_streak("Nimbus",lat, lon, alt,500.0,32,1250.0,0.0,200.0,32,1250.0,0.0,200.0,alpha,1.0);
2804
2805
2806 }
2807
2808 var create_8_8_nimbus_var1 = func (lat, lon, alt, alpha) {
2809
2810 if (local_weather.hardcoded_clouds_flag == 1) {var alt_eff = alt - local_weather.offset_map["Nimbus"]; }
2811
2812 var phi = alpha * math.pi/180.0;
2813
2814 local_weather.create_streak("Nimbus",lat, lon, alt_eff,500.0,35,1150.0,0.0,200.0,35,1150.0,0.0,200.0,alpha,1.0);
2815
2816 for (var i = 0; i < 3; i=i+1)
2817         {
2818         var x = -15000.0 + 30000.0 * rand();
2819         var y = -15000.0 + 30000.0 * rand();
2820         local_weather.create_streak("Stratocumulus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt+600.0,200.0,11,1100.0,0.1,800.0,8,1100.0,0.1,800.0,alpha,1.4);
2821
2822         }
2823 }
2824
2825 var create_8_8_nimbus_var2 = func (lat, lon, alt, alpha) {
2826
2827 if (local_weather.hardcoded_clouds_flag == 1) {var alt_eff = alt - local_weather.offset_map["Nimbus"]; }
2828
2829 var phi = alpha * math.pi/180.0;
2830
2831 local_weather.create_streak("Nimbus",lat, lon, alt_eff,500.0,35,1150.0,0.0,200.0,35,1150.0,0.0,200.0,alpha,1.0);
2832
2833 for (var i=0; i<8; i=i+1)
2834         {
2835         var x = 2.0 * (rand()-0.5) * 18000;
2836         var y = 2.0 * (rand()-0.5) * 18000;
2837         var beta = (rand() -0.5) * 180.0;
2838         local_weather.create_streak("Stratus (structured)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt+1200.0,300.0,5,900.0,0.2,500.0,7,900.0,0.2,500.0,alpha+beta,1.0);
2839
2840         }
2841
2842 }
2843
2844
2845 var create_8_8_nimbus_var3 = func (lat, lon, alt, alpha) {
2846
2847 if (local_weather.hardcoded_clouds_flag == 1) {var alt_eff = alt - local_weather.offset_map["Nimbus"]; }
2848
2849 var phi = alpha * math.pi/180.0;
2850
2851
2852 local_weather.create_streak("Nimbus",lat, lon, alt_eff,500.0,35,1150.0,0.0,200.0,35,1150.0,0.0,200.0,alpha,1.0);
2853
2854 for (var i=0; i<6; i=i+1)
2855         {
2856         var x = 2.0 * (rand()-0.5) * 18000;
2857         var y = 2.0 * (rand()-0.5) * 18000;
2858         var beta = (rand() -0.5) * 180.0;
2859         local_weather.create_streak("Stratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt+1600.0,300.0,6,1200.0,0.2,700.0,6,1200.0,0.2,700.0,alpha+beta,1.0);
2860         }
2861
2862 }
2863
2864 var create_8_8_nimbus_rain = func (lat, lon, alt, alpha, rain) {
2865
2866 if (local_weather.hardcoded_clouds_flag == 1) {var alt_eff = alt - local_weather.offset_map["Nimbus"]; }
2867
2868 if (local_weather.detailed_clouds_flag == 0)
2869         {local_weather.create_streak("Nimbus",lat, lon, alt,500.0,32,1250.0,0.0,200.0,32,1250.0,0.0,200.0,alpha,1.0);}
2870 else
2871         {
2872         #print(local_weather.offset_map["Nimbus"]);
2873         var rn = rand();
2874         if (rn > 0.66) {create_8_8_nimbus_var1(lat, lon, alt, alpha);}
2875         else if (rn > 0.33) {create_8_8_nimbus_var2(lat, lon, alt, alpha);}
2876         else {create_8_8_nimbus_var3(lat, lon, alt, alpha);}
2877         }
2878         # some ragged cloud fringes to avoid hard lines
2879         var phi = alpha * math.pi/180.0;
2880         var x = -15000.0 +rand() *30000.0; 
2881         var y = 24000.0;
2882         local_weather.create_streak("Nimbus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt_eff,500.0,12,1310.0,0.2,500.0,4,1310.0,0.0,1500.0,alpha,1.0);
2883         
2884         x=-15000.0 +rand() *30000.0; ; y=-24000.0;
2885         local_weather.create_streak("Nimbus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt_eff,500.0,12,1310.0,0.2,500.0,4,1310.0,0.0,1500.0,alpha,1.0);
2886
2887         x=24000.0; y=-15000.0 +rand() *30000.0; 
2888         local_weather.create_streak("Nimbus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt_eff,500.0,4,1310.0,0.0,1500.0,12,1310.0,0.2,500.0,alpha,1.0);
2889         
2890         x=-24000.0; y=-15000.0 +rand() *30000.0; 
2891         local_weather.create_streak("Nimbus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt_eff,500.0,4,1310.0,0.0,1500.0,12,1310.0,0.2,500.0,alpha,1.0);
2892         
2893 if (rain > 0.1)
2894         {
2895         local_weather.create_effect_volume(3, lat, lon, 20000.0, 20000.0, alpha, 0.0, alt+900.0, 500.0 + (1.0 - 0.5 * rain) * 5500.0, 0.5 * rain , -1, -1, -1,0 ,0.95);
2896         local_weather.create_effect_volume(3, lat , lon, 16000.0, 16000.0, alpha, 0.0, alt - 300.0, 500.0 + (1.0-rain) * 5500.0, rain, -1, -1, -1,0 ,0.9);
2897         }
2898 else
2899         {
2900         local_weather.create_effect_volume(3, lat, lon, 20000.0, 20000.0, alpha, alt, alt+900.0, 2000.0, -1 , -1, -1, -1,0 ,-1);
2901         local_weather.create_effect_volume(3, lat, lon, 20000.0, 20000.0, alpha, 0.0, alt, -1, rain , -1, -1, -1,0 ,0.9);
2902         }
2903
2904 }
2905
2906 var create_8_8_stratus = func (lat, lon, alt, alpha) {
2907
2908 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus"];}
2909
2910 local_weather.create_streak("Stratus",lat, lon, alt,500.0,32,1250.0,0.0,400.0,32,1250.0,0.0,400.0,alpha,1.0);
2911 }
2912
2913
2914 var create_8_8_stratus_rain = func (lat, lon, alt, alpha, rain) {
2915
2916
2917 create_8_8_stratus(lat, lon, alt, alpha);
2918
2919
2920 if (rain > 0.1) 
2921         {
2922         local_weather.create_effect_volume(3, lat, lon, 20000.0, 20000.0, alpha, 0.0, alt, 500.0 + (1.0 - 0.5 * rain) * 5500.0, 0.5 * rain , -1, -1, -1,0 ,-1);
2923         local_weather.create_effect_volume(3, lat , lon, 16000.0, 16000.0, alpha, 0.0, alt - 300.0, 500.0 + (1.0-rain) * 5500.0, rain, -1, -1, -1,0 ,0.9);
2924         }
2925 else
2926         {
2927         local_weather.create_effect_volume(3, lat, lon, 20000.0, 20000.0, alpha, 0.0, alt, -1, rain , -1, -1, -1,0 ,0.9);
2928         }
2929 }
2930
2931
2932 var create_6_8_stratus = func (lat, lon, alt, alpha) {
2933
2934 if (local_weather.hardcoded_clouds_flag == 1) 
2935         {
2936         alt = alt - local_weather.offset_map["Stratus"];
2937         
2938         for (var i = 0; i < 20; i = i + 1)
2939                 {
2940                 var phi = alpha * math.pi/180.0;
2941                 var x = 2.0 * (rand()-0.5) * 18000;
2942                 var y = 2.0 * (rand()-0.5) * 18000;
2943
2944                 local_weather.create_streak("Stratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,500.0,5,2300.0,0.2,500.0,5,2300.0,0.2,500.0,alpha,1.0);
2945                 }
2946
2947         }
2948 else
2949         {local_weather.create_streak("Stratus",lat, lon, alt,500.0,20,0.0,0.2,20000.0,20,0.0,0.2,20000.0,alpha,1.0);}
2950 }
2951
2952
2953
2954
2955 var create_6_8_nimbus_rain = func (lat, lon, alt, alpha, rain) {
2956
2957 var phi = alpha * math.pi/180.0;
2958
2959 var alt_cloud = alt;
2960
2961 if (local_weather.hardcoded_clouds_flag == 1) {alt_cloud = alt_cloud - 3000.0;}
2962
2963 for (var i = 0; i < 3; i = i + 1)
2964         {
2965         var x = 2.0 * (rand()-0.5) * 2000.0 + i * 12000.0 - 12000.0;
2966         var y = 2.0 * (rand()-0.5) * 12000.0;
2967         var beta = rand() * 360.0;
2968
2969         local_weather.create_layer("Nimbus", lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt_cloud, 500.0, 12000.0, 7000.0, beta, 1.0, 0.2, 1, 1.0);
2970
2971         if (rain > 0.1)
2972                 {
2973                 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 10000.0, 6000.0, beta, 0.0, alt+900, 500.0 + (1.0-0.5*rain) * 5500.0, 0.5 * rain, -1, -1, -1,0,0.95 );
2974                 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 9000.0, 5000.0, beta, 0.0, alt-300.0, 500.0 + (1.0-rain) * 5500.0, rain, -1, -1, -1,0,0.8);
2975                 }
2976         else
2977                 {
2978                 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 10000.0, 6000.0, beta, 0.0, alt, -1, rain, -1, -1, -1,0, 0.8 );
2979                 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 10000.0, 6000.0, beta, alt-1500.0, alt+900.0, 2000.0, -1, -1, -1, -1,0, 0.8 );
2980                 }
2981         }
2982
2983
2984 }
2985
2986
2987 var create_6_8_stratus_rain = func (lat, lon, alt, alpha, rain) {
2988
2989 var phi = alpha * math.pi/180.0;
2990
2991 var alt_cloud = alt;
2992
2993 if (local_weather.hardcoded_clouds_flag == 1) {alt_cloud = alt_cloud - local_weather.offset_map["Stratus"];}
2994
2995 for (var i = 0; i < 3; i = i + 1)
2996         {
2997         var x = 2.0 * (rand()-0.5) * 2000.0 + i * 12000.0 - 12000.0;
2998         var y = 2.0 * (rand()-0.5) * 12000.0;
2999         var beta = rand() * 360.0;
3000
3001         local_weather.create_layer("Stratus", lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt_cloud, 500.0, 12000.0, 7000.0, beta, 1.0, 0.2, 0, 0.0);
3002
3003         if (rain > 0.1)
3004                 {
3005                 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 10000.0, 6000.0, beta, 0.0, alt, 500.0 + (1.0-0.5*rain) * 5500.0, 0.5 * rain, -1, -1, -1,0,0.95 );
3006                 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 9000.0, 5000.0, beta, 0.0, alt-300.0, 500.0 + (1.0-rain) * 5500.0, rain, -1, -1, -1,0,0.8);
3007                 }
3008         else
3009                 {
3010                 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 10000.0, 6000.0, beta, 0.0, alt, -1, rain, -1, -1, -1,0, 0.8 );
3011                 }
3012         }
3013
3014
3015 }
3016
3017
3018 var create_6_8_stratus_undulatus = func (lat, lon, alt, alpha) {
3019
3020 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus"];}
3021
3022 local_weather.create_undulatus("Stratus",lat, lon, alt,300.0,10,4000.0,0.1,400.0,50,800.0,0.1,100.0, 1000.0, alpha,1.0);
3023 }
3024
3025 var create_6_8_tstratus_undulatus = func (lat, lon, alt, alpha) {
3026
3027 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus_thin"];}
3028
3029 local_weather.create_undulatus("Stratus (thin)",lat, lon, alt,300.0,10,4000.0,0.1,400.0,50,800.0,0.1,100.0, 1000.0, alpha,1.0);
3030 }
3031
3032 var create_6_8_tstratus_mackerel = func (lat, lon, alt, alpha) {
3033
3034 var phi = alpha * math.pi/180.0;
3035
3036 var x = 2.0 * (rand()-0.5) * 3000;
3037 var y = 2.0 * (rand()-0.5) * 3000; 
3038
3039 var arg = {};
3040
3041 arg.cloud_spacing = 900.0;
3042 arg.undulatus_spacing = 4200.0;
3043 arg.undulatus_slant = 0.4;
3044 arg.undulatus_amplitude = 2000.0;
3045 arg.aspect = 0.5;
3046 arg.Dx = 100.0;
3047 arg.Dy = 100.0;
3048 arg.xsize = 35000.0 + rand() * 10000.0;
3049 arg.ysize = 35000.0 + rand() * 10000.0;
3050 arg.blat = lat + get_lat(x,y,phi);
3051 arg.blon = lon + get_lon(x,y,phi);
3052 arg.balt = alt;
3053 arg.alt_var = 0.0;
3054 arg.dir = alpha;
3055 arg.size_bias = 0.5;
3056 arg.type = "Stratus (thin)";
3057
3058 local_weather.create_adv_undulatus(arg);
3059 }
3060
3061
3062
3063 var create_6_8_cirrostratus = func (lat, lon, alt, alpha) {
3064
3065 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Cirrostratus"];}
3066
3067 local_weather.create_streak("Cirrostratus",lat,lon,alt,500.0,24,1500.0,0.0,900.0,24,1500.0,0.0,900.0,alpha,1.0);
3068 }
3069
3070
3071 var create_6_8_stratocumulus = func (lat, lon, alt, alpha) {
3072
3073 if (local_weather.detailed_clouds_flag == 1)
3074         {
3075         for (var i=0; i< 2; i=i+1)
3076                 {
3077                 var phi = alpha * math.pi/180.0;
3078                 var x = 2.0 * (rand()-0.5) * 4000;
3079                 var y = 2.0 * (rand()-0.5) * 4000;
3080                 var beta = rand() * 360.0;
3081                 create_detailed_stratocumulus_bank(lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt, alpha+beta);
3082                 }
3083         }
3084 else
3085         {
3086         create_stratocumulus_bank(lat, lon, alt, alpha);
3087         create_stratocumulus_bank(lat, lon, alt, alpha);
3088         }
3089
3090 }
3091
3092
3093 var create_4_8_stratus = func (lat, lon, alt, alpha) {
3094
3095 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus"];}
3096
3097 var phi = alpha * math.pi/180.0;
3098 var x = 2.0 * (rand()-0.5) * 15000;
3099 var y = 2.0 * (rand()-0.5) * 15000;
3100 var beta = rand() * 360.0;
3101
3102 local_weather.create_streak("Stratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,500.0,20,1200.0,0.3,400.0,12,1200.0,0.3,400.0,beta,1.2);
3103
3104
3105 var x = 2.0 * (rand()-0.5) * 15000;
3106 var y = 2.0 * (rand()-0.5) * 15000;
3107 var beta = rand() * 360.0;
3108
3109 local_weather.create_streak("Stratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,500.0,18,1000.0,0.3,400.0,10,1000.0,0.3,400.0,beta,1.5);
3110
3111
3112 var x = 2.0 * (rand()-0.5) * 15000;
3113 var y = 2.0 * (rand()-0.5) * 15000;
3114 var beta = rand() * 360.0;
3115
3116 local_weather.create_streak("Stratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,500.0,15,1000.0,0.3,400.0,18,1000.0,0.3,400.0,beta,2.0);
3117
3118 }
3119
3120 var create_4_8_stratus_patches = func (lat, lon, alt, alpha) {
3121
3122 var phi = alpha * math.pi/180.0;
3123
3124 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus"];}
3125
3126 for (var i=0; i<16; i=i+1)
3127         {
3128         var x = 2.0 * (rand()-0.5) * 18000;
3129         var y = 2.0 * (rand()-0.5) * 18000;
3130         var beta = (rand() -0.5) * 180.0;
3131         local_weather.create_streak("Stratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,300.0,4,950.0,0.2,500.0,6,950.0,0.2,500.0,alpha+beta,1.0);
3132
3133         }
3134
3135 }
3136
3137 var create_4_8_tstratus_patches = func (lat, lon, alt, alpha) {
3138
3139 var phi = alpha * math.pi/180.0;
3140
3141 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus_thin"];}
3142
3143 for (var i=0; i<22; i=i+1)
3144         {
3145         var x = 2.0 * (rand()-0.5) * 18000;
3146         var y = 2.0 * (rand()-0.5) * 18000;
3147         var beta = (rand() -0.5) * 180.0;
3148
3149         var m = int(3 + rand() * 3);
3150         var n = int(3 + rand() * 5);
3151
3152         local_weather.create_streak("Stratus (thin)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,300.0,m,1000.0,0.2,500.0,n,1000.0,0.2,500.0,alpha+beta,1.0);
3153
3154         }
3155 }
3156
3157
3158 var create_4_8_tstratus_domains = func (lat, lon, alt, alpha) {
3159
3160 var arg = {};
3161
3162 arg.xsize = 36000.0;
3163 arg.ysize = 36000.0;
3164 arg.min_domain_size_x = 5000.0;
3165 arg.max_domain_size_x = 24000.0;
3166 arg.min_domain_size_y = 5000.0;
3167 arg.max_domain_size_y = 24000.0;
3168 arg.node_fraction = 0.0;
3169 arg.halo_fraction = 0.4;
3170 arg.n_domains = 12;
3171 arg.n = 30;
3172 arg.blat = lat;
3173 arg.blon = lon;
3174 arg.balt = alt;
3175 arg.alt_var = 0.0;
3176 arg.dir = alpha;
3177 arg.type = "Stratus (thin)";
3178 arg.subtype = "large";
3179 arg.ntype = "Altocumulus perlucidus";
3180 arg.nsubtype = "large";
3181 arg.htype = "Stratus (thin)";
3182 arg.hsubtype = "small";
3183
3184 local_weather.create_domains(arg);
3185 }
3186
3187
3188 var create_4_8_sstratus_patches = func (lat, lon, alt, alpha) {
3189
3190 var phi = alpha * math.pi/180.0;
3191
3192 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus_structured"];}
3193
3194 for (var i=0; i<22; i=i+1)
3195         {
3196         var x = 2.0 * (rand()-0.5) * 18000;
3197         var y = 2.0 * (rand()-0.5) * 18000;
3198         var beta = (rand() -0.5) * 180.0;
3199         var m = int(3 + rand() * 5);
3200         var n = int(3 + rand() * 5);
3201         local_weather.create_streak("Stratus (structured)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,300.0,m,1000.0,0.2,500.0,n,1000.0,0.2,500.0,alpha+beta,1.0);
3202
3203         }
3204
3205 }
3206
3207
3208 var create_4_8_cirrostratus_patches = func (lat, lon, alt, alpha) {
3209
3210 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Cirrostratus"];}
3211
3212 var phi = alpha * math.pi/180.0;
3213
3214 for (var i=0; i<6; i=i+1)
3215         {
3216         var x = 2.0 * (rand()-0.5) * 12000;
3217         var y = 2.0 * (rand()-0.5) * 12000;
3218         var beta = (rand() -0.5) * 180.0;
3219         local_weather.create_streak("Cirrostratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,300.0,4,2500.0,0.2,600.0,4,2500.0,0.2,600.0,alpha+beta,1.0);
3220
3221         }
3222
3223 }
3224
3225 var create_4_8_cirrostratus_undulatus = func (lat, lon, alt, alpha) {
3226
3227 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Cirrostratus"];}
3228
3229 local_weather.create_undulatus("Cirrostratus",lat, lon, alt,300.0,5,8000.0,0.1,400.0,40,1000.0,0.1,100.0, 1500.0, alpha,1.0);
3230 }
3231
3232
3233 var create_4_8_stratus_undulatus = func (lat, lon, alt, alpha) {
3234
3235 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus"];}
3236
3237 var phi = alpha * math.pi/180.0;
3238 var x = 2.0 * (rand()-0.5) * 5000;
3239 var y = 2.0 * (rand()-0.5) * 5000;
3240 var tri = 1.5 + 1.5*rand();
3241 var beta = (rand() -0.5) * 60.0;
3242
3243 local_weather.create_streak("Stratus",lat+get_lat(x,y+4000,phi), lon+get_lon(x,y+4000,phi), alt,500.0,10,800.0,0.25,400.0,12,2800.0,0.15,600.0,alpha+90.0+beta,tri);
3244
3245 local_weather.create_streak("Stratus",lat+get_lat(x,y-4000,phi), lon+get_lon(x,y-4000,phi), alt,500.0,10,800.0,0.25,400.0,12,2800.0,0.15,600.0,alpha+270.0+beta,tri);
3246
3247 }
3248
3249 var create_4_8_tstratus_undulatus = func (lat, lon, alt, alpha) {
3250
3251 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus_thin"];}
3252
3253 var phi = alpha * math.pi/180.0;
3254 var x = 2.0 * (rand()-0.5) * 5000;
3255 var y = 2.0 * (rand()-0.5) * 5000;
3256 var tri = 1.5 + 1.5*rand();
3257 var beta = (rand() -0.5) * 60.0;
3258
3259 local_weather.create_streak("Stratus (thin)",lat+get_lat(x,y+4000,phi), lon+get_lon(x,y+4000,phi), alt,500.0,10,800.0,0.25,400.0,12,2800.0,0.15,600.0,alpha+90.0+beta,tri);
3260
3261 local_weather.create_streak("Stratus (thin)",lat+get_lat(x,y-4000,phi), lon+get_lon(x,y-4000,phi), alt,500.0,10,800.0,0.25,400.0,12,2800.0,0.15,600.0,alpha+270.0+beta,tri);
3262
3263 }
3264
3265 var create_4_8_sstratus_undulatus = func (lat, lon, alt, alpha) {
3266
3267 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus_structured"];}
3268
3269 var phi = alpha * math.pi/180.0;
3270 var x = 2.0 * (rand()-0.5) * 5000;
3271 var y = 2.0 * (rand()-0.5) * 5000;
3272 var tri = 1 + 1.5*rand();
3273 var beta = (rand() -0.5) * 60.0;
3274
3275 local_weather.create_streak("Stratus (structured)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,500.0,20,900.0,0.25,400.0,12,2800.0,0.15,600.0,alpha+90.0+beta,tri);
3276
3277 }
3278
3279
3280 var create_4_8_cirrocumulus_bank = func (lat, lon, alt, alpha) {
3281
3282 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 300.0;}