1 """!@brief Create namelists, monitor wrf simulations, generate filenames.
3 @details This module contains classes that manipulate WRF namelists in
4 complex ways, and predict the resulting output and input filenames
5 regardless of whatever crazy timesteps are requested. This module
6 also contains a class, ExternalWRFTask, that can monitor a running WRF
7 simulation, providing a list of output and input files, and check
8 whether the simulation has completed, failed or is still running.
12 import fractions,math,re,datetime,os
17 from produtil.run import bigexe, checkrun, mpirun, mpi, runstr, batchexe
27 __all__=[
'default_wrf_outname',
'WRFDomain',
'WRFSimulation',
'ExternalWRFTask']
32 """!default wrf output filename patterns
34 Generate a reasonable default wrf outname input value for the
35 specified stream. Presently, these match the WRF defaults. These
36 do not have to match the WRF defaults since we always specify the
37 outname for all streams.
38 @param stream the stream
39 @returns the wrf output filename pattern, including <date> and
40 <domain> if relevant"""
42 return 'wrfout_d<domain>_<date>'
44 return 'wrf%s_d<domain>_<date>' % (stream,)
45 elif stream==
'restart':
46 return 'wrfrst_d<domain>_<date>'
47 elif stream==
'bdy' or stream==
'input':
48 return 'wrf%s_d<domain>' % (stream,)
49 elif stream==
'geo_nmm':
50 return '%s_d<domain>' % (stream,)
51 elif stream==
'inputout':
52 return 'wrfinput_d<domain>_<date>'
53 elif stream==
'bdyout':
54 return 'wrfbdy_d<domain>'
56 return '%s_d<domain>_<date>'%(stream,)
66 _wrf_namelist_order=
partial_ordering([
'time_control',
'fdda',
'domains',
'physics',
'dynamics',
'bdy_control',
'namelist_quilt',
'logging'],6)
75 'start_year',
'start_month',
'start_day',
'start_hour',
'start_minute',
76 'start_second',
'end_year',
'end_month',
'end_day',
'end_hour',
77 'end_minute',
'end_second',
'interval_seconds',
'history_interval',
78 'auxhist1_interval',
'auxhist2_interval',
79 'auxhist3_interval',
'history_end',
'auxhist2_end',
'auxhist1_outname',
80 'auxhist2_outname',
'auxhist3_outname',
'frames_per_outfile',
81 'frames_per_auxhist1',
'frames_per_auxhist2',
'frames_per_auxhist3',
82 'analysis',
'anl_outname',
'restart',
'restart_interval',
83 'reset_simulation_start',
'io_form_input',
'io_form_history',
84 'io_form_restart',
'io_form_boundary',
'io_form_auxinput1',
85 'io_form_auxhist1',
'io_form_auxhist2',
'io_form_auxhist3',
86 'auxinput1_inname',
'debug_level',
'tg_reset_stream',
87 'override_restart_timers']),
89 'time_step',
'time_step_fract_num',
'time_step_fract_den',
90 'max_dom',
's_we',
'e_we',
's_sn',
'e_sn',
's_vert',
'e_vert',
'dx',
91 'dy',
'grid_id',
'tile_sz_x',
'tile_sz_y',
'numtiles',
'nproc_x',
92 'nproc_y',
'parent_id',
'parent_grid_ratio',
93 'parent_time_step_ratio',
'i_parent_start',
'j_parent_start',
94 'feedback',
'num_moves',
'num_metgrid_levels',
'p_top_requested',
95 'ptsgm',
'eta_levels',
'use_prep_hybrid',
96 'num_metgrid_soil_levels']),
98 'num_soil_layers',
'mp_physics',
'ra_lw_physics',
'ra_sw_physics',
99 'sf_sfclay_physics',
'sf_surface_physics',
'bl_pbl_physics',
100 'cu_physics',
'mommix',
'var_ric',
'coef_ric_l',
'coef_ric_s',
102 'sfenth',
'nrads',
'nradl',
'nphs',
'ncnvc',
'ntrack',
'gfs_alpha',
103 'sas_pgcon',
'sas_mass_flux',
'co2tf',
'vortex_tracker',
104 'nomove_freq',
'tg_option',
'ntornado']),
106 [
'non_hydrostatic',
'euler_adv',
'wp',
'coac',
'codamp',
107 'terrain_smoothing']),
110 [
'poll_servers',
'nio_tasks_per_group',
'nio_groups']),
112 [
'compute_tasks_silent',
'io_servers_silent',
'stderr_logging'])
118 """!A domain in a WRF simulation
120 This subclass of WRFDomainsBase adds needed details that let it
121 provide information about a domain in a WRF simulation. It can
122 predict output and input filenames based on timesteps and
123 start/end times. It can do complex manipulations of the WRF
124 namelist. Most functionality should be accessed via the
125 WRFSimulation, after a WRFDomain is created.
127 Note that after you provide a WRFDomain to a WRFSimulation, the
128 WRFSimulation makes its own copy of that WRFDomain. The original
129 is unmodified. That means that if you want details on the
130 namelist and output files added by the WRFSimultion, you must
131 obtain its copy of the WRFDomain like so:
134 moad=WRFDomain(conf,'moad')
135 storm1outer=WRFDomain(conf,'storm1outer')
136 storm1inner=WRFDomain(conf,'storm1inner')
137 wrf=WRFSimulation(conf,'wrf',moad,conf.cycle,
138 conf.cycle+hwrf.numerics.to_timedelta(fcstlen*3600))
139 wrf.add(storm1outer,moad)
140 wrf.add(storm1inner,storm1outer)
141 wrf.add_output('history',step=3600*3,end=9*3600)
143 sim_storm1outer=wrf[storm1outer]
144 sim_storm1inner=wrf[storm1inner]
147 In this example, the sim_moad, sim_storm1inner and sim_storm1outer
148 will be new objects, contained within the WRFSimulation named
149 "wrf". They will contain additional information about the
150 WRFDomain that is not in the original moad, storm1inner and
174 def __init__(self,conf,section,name=None,copy=None):
175 """!WRFDomain constructor
177 Creates a new WRFDomain based on the information in a section
178 of the HWRFConfig object conf. The domain's name is in
179 "name." The "copy" argument should never be specified: it is
180 used by self.copy for deep copies of a WRFDomain."""
191 self.
nl=copy.nl.copy()
194 (copy._start,copy._end,copy._dt,copy.nestlevel,copy.parent )
196 (copy.dx,copy.dy,copy.nocolons)
197 for (n,o)
in copy._output.iteritems():
201 self.
name=str(section)
202 def add_hifreq(self):
203 self.
add_output(
'hifreq',outname=
'hifreq_d<domain>.htcf')
209 self.nl.nl_del(
'time_control',
'frames_per_hifreq')
210 self.nl.nl_del(
'time_control',
'hifreq_interval')
212 """!Returns the nesting ratio between this domain and the MOAD."""
216 return self.parent.moad_ratio()*self.nl.nl_get(
217 'domains',
'parent_grid_ratio')
219 """!Returns the timestep for this domain."""
225 dt=property(getdt,
None,
None,
'The timestep for this domain.')
228 """!A string description of this domain"""
229 return '<WRFDomain name=%s>'%(str(self.
name),)
230 def _nl_subsetter(self,s,v):
233 This will be used in the future to ensure users do not specify
234 namelist options that should be automatically configured."""
241 """!Returns a deep copy of this object
243 Returns a deep copy of this object. The copy has its own data
244 structures, so modifying the copy will not modify the
248 """!Sets start and end times and timestep
250 Sets this WRFDomain's idea of the simulation start and end
252 @param start the start time of the domain
253 @param end the end time of the domain
254 @param timestep the domain's timestep"""
255 WRFDomainBase.set_timing(self,start,end,timestep)
258 for n
in (
'year',
'month',
'day',
'hour',
'minute',
'second'):
259 self.nl.nl_set(
'time_control',
'start_'+n,getattr(ts,n))
260 self.nl.nl_set(
'time_control',
'end_'+n,getattr(te,n))
262 """!Returns the WRF grid id."""
263 return self.nl.nl_get(
'domains',
'grid_id')
265 """!Is this the outermost domain?
267 Returns True if this is the WRF Mother of All Domains (MOAD)
268 and False otherwise. The MOAD is the outermost domain."""
274 """!The number of grid cells the X direction."""
275 return self.nl.nl_get(
'domains',
'e_we')
278 """!The number of grid cells the Y direction."""
279 return self.nl.nl_get(
'domains',
'e_sn')
282 """!The number of grid cells the Z direction."""
283 return self.nl.nl_get(
'domains',
'e_vert')
285 """!Internal helper function that initializes variables common to all domains
287 Initializes domain variables that are needed by all domains.
288 This is called as a helper function to the other domain
289 initialization variables."""
292 s(
'domains',
's_we',1)
293 s(
'domains',
's_sn',1)
294 s(
'domains',
's_vert',1)
295 s(
'domains',
'e_we',t(
'nx'))
296 s(
'domains',
'e_sn',t(
'ny'))
297 s(
'domains',
'grid_id',int(grid_id))
299 """!Called by WRFSimulation to initialize this as the outermost domain
301 Do not call this function directly. It is called by the
302 WRFSimulation to initialize the domain as the Mother Of All
304 @param simstart the simulation start time
305 @param simend the simulation end time
306 @param simdt the outermost domain timestep
307 @param eta_levels the NMM eta levels"""
308 WRFDomainBase.init_as_moad(self,simstart,simend,simdt,eta_levels)
312 (i,n,d)=split_fraction(simdt)
313 nz=t(
'nz',len(eta_levels))
314 if len(eta_levels)!=nz:
315 raise WRFError(
'nz and len(eta_levels) mismatch: %d vs %d'
316 %(int(nz),len(eta_levels)))
317 s(
'domains',
'e_vert',nz)
319 s(
'domains',
'dx',self.
dx)
321 s(
'domains',
'dy',self.
dy)
322 s(
'domains',
'parent_id',0)
323 s(
'domains',
'parent_grid_ratio',1)
324 s(
'domains',
'parent_time_step_ratio',1)
325 s(
'domains',
'i_parent_start',0)
326 s(
'domains',
'j_parent_start',0)
327 assert(self.
dy is not None)
329 """!Called by WRFSimulation to initialize this domain as a nest
331 Do not call this function directly. It is called by the
332 WRFSimulation to initialize the domain as a nest
333 @param parent the parent WRFDomain
334 @param grid_id the integer grid_id
335 @param start the domain start time
336 @param end the domain end time"""
337 WRFDomainBase.init_as_nest(self,parent,grid_id,start,end)
338 if not is_at_timestep(parent._start,start,parent._dt):
340 'Start time %s for domain %d is not at parent %d timestep.'
341 %(parent._start,grid_id,parent.grid_id))
353 s(
'domains',
'parent_id',p(
'domains',
'grid_id'))
354 s(
'domains',
'parent_time_step_ratio',3)
355 s(
'domains',
'parent_grid_ratio',3)
358 s(
'domains',
'dx',p(
'domains',
'dx')/3)
359 s(
'domains',
'dy',p(
'domains',
'dy')/3)
360 s(
'domains',
'e_vert',p(
'domains',
'e_vert'))
361 start=str(t(
'start',
'auto')).lower()
363 s(
'domains',
'i_parent_start',int(t(
'istart')))
364 s(
'domains',
'j_parent_start',int(t(
'jstart')))
365 elif start==
'centered':
366 s(
'domains',
'i_parent_start',
'**CENTERED**')
367 s(
'domains',
'j_parent_start',
'**CENTERED**')
369 s(
'domains',
'i_parent_start',
'**AUTO**')
370 s(
'domains',
'j_parent_start',
'**AUTO**')
373 '%s: Invalid value for start. It must be "fixed" "centered" or "auto",'
374 ' but you gave %s'%(self.
name,repr(start)),self.
name)
375 assert(self.
dy is not None)
377 """!Creates the WRF namelist contents and returns it as a string."""
378 return self.nl.make_namelist()
380 """!Returns True if the domain will output to the specified
383 Checks the internal data structures maintained by add_output
384 to see if output was requested for the specified stream.
385 @param stream the stream to check
386 @return True if the domain will output to the specified
387 stream, and False if it won't (as far as we know)."""
390 """!Returns the range of times that has output for the given stream.
392 @return a tuple containing the first output time, last
393 output time and output interval for this domain and the
395 @param stream the stream for whom output is requested"""
398 'Stream %s is disabled for domain %s'%(stream,repr(self)))
400 if 'start' in self.
_output[stream]
and \
401 self.
_output[stream][
'start']
is not None:
402 start=to_datetime_rel(self.
_output[stream][
'start'],start)
404 if 'end' in self.
_output[stream]
and \
405 self.
_output[stream][
'end']
is not None:
406 end=to_datetime_rel(self.
_output[stream][
'end'],start)
407 interval=to_timedelta(self.
_output[stream][
'step'])
408 return (start,end,interval)
410 """!Returns the hifreq filename for this domain."""
411 return parse_wrf_outname(
'hifreq_d<domain>.htcf',self.
get_grid_id(),
414 """Returns the track patcf file for this domain. """
415 return parse_wrf_outname(
'track_d<domain>.patcf',self.
get_grid_id(),
417 def _get_output_time(self,when):
418 """!Internal function that determines the time output would
419 actually be generated
421 This is an internal implementation function. You should not
422 call it directly. It returns the nearest datetime.datetime to
423 the specified time that lies on a model timestep, without
424 going over. Uses hwrf.numerics.nearest_datetime()
425 @param when the desired time
426 @returns a datetime.datetime for the actual time that will appear"""
427 return nearest_datetime(self.
_start,when,self.
_dt)
428 def _get_output(self,stream,outname,when,actual_time=None,logger=None):
429 """!Internal function that generates WRFOutput objects
431 This is an internal implementation function. You should not
432 call it directly. It returns a WRFOutput object for the
433 specified output time (when) and stream. The outname is the
434 WRF output filename syntax, with <domain> and <date> in it.
435 If actual_time is specified, it is used as the output time,
436 otherwise, "when" is passed into self._get_output_time to get
437 the actual time WRF will output it.
438 @param stream the desired stream
439 @param outname the output filename format
440 @param when the desired output time
441 @param actual_time the actual time from _get_output_time. If
442 missing or None, then _get_output_time will be called.
443 @param logger if specified, the logging.Logger to use for log
445 if actual_time
is None:
450 path=parse_wrf_outname(outname,self.
get_grid_id(),actual_time,
452 assert(actual_time
is not None)
454 validtime=actual_time)
456 """!Iterate over all output files for a specified time.
458 Iterates over all output files as WRFOutput objects. If a
459 time is specified, then only outputs for that time are
461 @param time the time of interest, or None (the default)"""
469 """!Iterates over all outputs for a specified stream
471 Iterates over all output files for the specified stream, as
473 @param stream the string name of the output stream"""
475 epsilon=to_timedelta(
'0+1/500')
479 outname=self.
_output[stream][
'outname']
480 while when<end+epsilon:
482 if prevwhen
is None or prevwhen!=actual_time:
483 obj=self.
_get_output(stream,outname,when,actual_time)
489 'Zero output interval %s: somehow %s+%s=%s'%\
490 (repr(interval),repr(when),repr(interval),repr(when)))
492 """!Get output for a specified time and stream
494 Returns a WRFOutput object for the output file for the
495 specified stream and time, or None if no such file exists.
496 Will return the first output time not before the given time.
497 @param stream the desired stream
498 @param time the desired time
499 @param logger if specified, a logging.Logger to log to"""
501 time=to_datetime_rel(time,self.
_start)
502 outname=self.
_output[stream][
'outname']
503 near=nearest_datetime(start,time,interval)
510 result=self.
_get_output(stream,outname,near,logger=logger)
515 """!Forget that output was requested for a given stream
517 Removes the specified stream from the internal data
518 structures. Its output will revert to the WRF default, and
519 will be unavailable via this WRFDomain.
520 @param stream the string name of the stream of disinterest"""
523 """!Disable output for a specified stream, if the stream was
526 If output is enabled for the specified stream, moves the
527 output start time to after the end of the simulation. That
528 way any WRF code relying on the output frequency will still
529 work, but no output will be generated. Will not work for
530 restart stream since that is not controlled on a per-domain
531 basis. Note that code that queries the output times will
532 break if this is called.
533 @param stream the string name of the stream of disinterest"""
534 if not self.
_output[stream]:
return
538 if stream==
'restart' and not self.
is_moad():
540 self.
_output[stream][
'start']=forever
541 self.
_output[stream][
'end']=forever+1
542 self.
_output[stream][
'step']=forever
543 if stream==
'inputout':
544 s(
'time_control',
'%s_begin_m'%(stream,),forever)
545 s(
'time_control',
'%s_end_m'%(stream,),forever+1)
547 s(
'time_control',
'%s_begin'%(stream,),forever)
548 s(
'time_control',
'%s_end'%(stream,),forever+1)
549 d(
'time_control',
'%s_begin_s'%(stream,))
550 d(
'time_control',
'%s_end_s'%(stream,))
552 def add_output(self,stream,start=None,end=None,step=None,outname=None,
553 frames_per_outfile=
None,io_form=
None,simstart=
None):
554 """!Adds output to the specified stream. Other arguments are
557 @param stream the stream: "history" or "auxhistN" for an integer N>0
558 @param start output start time (anything accepted by to_datetime)
559 Default: simulation start time.
560 @param end output end time (anything accepted by to_datetime.
561 Default: simulation end time.
562 @param step output interval, sent into to_out_interval().
563 Default: trait stream+"_interval" or 6hrs
564 @param outname output name or array of output names (one per
565 domain). Can only specify for all domains, not for only
566 one. Default: leave unspecified, and let WRF use its
568 @param frames_per_outfile how many output times per output file
569 @param io_form WRF IO form. Simply calls self.set_io_form(stream,io_form)
570 @param simstart the simulation start time which must be provided fi start or end times are given"""
572 iof=self.nl.trait_get(
'io_form',
'missing')
577 assert(isinstance(io_form,int))
583 (dstart,dend,fstep)=(
None,
None,
None)
584 if ( start
is not None or end
is not None )
and simstart
is None:
585 raise TypeError(
'WRFDomain.add_output: simstart must be provided '
586 'if start or end times are given')
587 if start
is not None:
588 start=to_datetime_rel(start,simstart)
589 dstart=start-simstart
590 (smin,ssec,srest) = minutes_seconds_rest(dstart)
593 'Output start time must be an integer multiple of a '
594 'second after simulation start time.')
596 startrel=self.
_start if (start
is None)
else start
597 dend=to_datetime_rel(end,simstart)
599 (emin,esec,erest) = minutes_seconds_rest(fend)
602 'Output end time must be an integer multiple of a second '
603 'after simulation start time.')
605 if step
is not None: fstep=to_fraction(step)
606 if fstep
is None: fstep=to_fraction(3600*6)
607 (minutes,seconds,rest)=minutes_seconds_rest(fstep)
610 'Output frequency must be an integer multiple of a second.')
612 frames_per=
'frames_per_outfile'
613 if stream!=
'history':
614 frames_per=
'frames_per_%s'%(stream,)
618 if stream==
'inputout':
619 s(
'time_control',
'%s_interval_m'%(stream,),minutes)
621 s(
'time_control',
'%s_interval'%(stream,),minutes)
623 s(
'time_control',
'%s_interval_s'%(stream,),seconds)
624 if stream==
'restart' and not self.
is_moad():
626 elif start
is not None:
627 if stream==
'inputout':
628 s(
'time_control',
'%s_begin_m'%(stream,),smin)
630 s(
'time_control',
'%s_begin'%(stream,),smin)
632 s(
'time_control',
'%s_begin_s'%(stream,),ssec)
633 if end
is not None and stream!=
'restart':
634 if stream==
'inputout':
635 s(
'time_control',
'%s_end_m'%(stream,),emin)
637 s(
'time_control',
'%s_end'%(stream,),emin)
639 s(
'time_control',
'%s_end_s'%(stream,),esec)
641 if stream!=
'inputout' and stream!=
'restart':
642 if frames_per_outfile
is not None:
643 s(
'time_control',frames_per,int(frames_per_outfile))
645 s(
'time_control',frames_per,1)
648 self.
_output[stream]={
'start':dstart,
'end':dend,
649 'step':fstep,
'outname':outname}
650 self.nl.nl_set_if_unset(
'time_control',
'nocolons',
True)
652 """!Return the output interval for the stream
654 Returns the output interval for the specified stream, or
655 None if the stream is disabled.
656 @param stream the stream of interest"""
658 return self.
_output[stream][
'step']
664 """!generate and manipulate wrf namelists, predict output filenames
666 The WRFSimulation class is at the core of the HWRF scripting
667 system. It stores information about every aspect of the WRF
668 namelist, and can manipulate it in complex ways. It automatically
669 generates I/O information, and can predict output and input
670 filenames no matter what crazy timesteps and start/end times you
671 select. There are a number of safeguards that will raise
672 exceptions in Python if you try to set up a simulation that is not
675 """!Makes a deep copy of this object
677 Returns a deep copy of this object, providing new data
678 structures so modifying the copy will not modify the original.
679 The underlying WRFDomain objects and their data structures are
687 def __init__(self,conf,section,moad,simstart,simend,timestep=None,dup=None):
688 """!Creates a new WRFSimulation object:
690 Creates a new WRFSimulation object.
691 @param conf the HWRFConfig to provide configuration information
692 @param section the section to use in that config object
693 @param moad the Mother of All Domains, as a WRFDomain
694 @param simstart,simend - simulation start and end times
695 @param timestep the simulation timestep
696 @param dup do not use. This is used by the self.copy() do do a deep
697 copy of a WRFDomains."""
700 WRFDomains.__init__(self,
None,
None,
None,
None,
None,
None,dup=dup)
703 for domain
in self:
pass
706 WRFDomains.__init__(self,conf,section,moad,simstart,simend,timestep)
714 siu=self.nl.nl_set_if_unset
716 th=self.nl.trait_have
720 'time_control',
'fdda',
'domains',
'physics',
'dynamics',
721 'bdy_control',
'namelist_quilt',
'logging')
723 dt=to_fraction(t(
'dt'))
724 (i,n,d)=split_fraction(dt)
725 s(
'domains',
'time_step',i)
726 s(
'domains',
'time_step_fract_num',n)
727 s(
'domains',
'time_step_fract_den',d)
729 s(
'time_control',
'interval_seconds',t(
'bdystep'))
730 s(
'domains',
'ptsgm',float(t(
'ptsgm')))
731 s(
'domains',
'p_top_requested',float(t(
'ptop')))
732 s(
'domains',
'use_prep_hybrid',bool(t(
'prep_hybrid')))
733 s(
'domains',
'num_metgrid_soil_levels',int(t(
'metgrid_soil_levels',4)))
734 s(
'domains',
'num_metgrid_levels',int(t(
'metgrid_levels',4)))
736 siu(
'namelist_quilt',
'nio_tasks_per_group',[0])
737 siu(
'namelist_quilt',
'nio_groups',1)
738 for stream
in [
'input',
'boundary',
'auxinput1',
'auxhist1',
'auxhist2',
739 'auxhist3',
'auxhist4',
'auxhist5',
'history',
'auxhist6',
742 if not sh(
'time_control',n):
744 s(
'time_control',n,t(n))
746 s(
'time_control',n,self.
io_form)
747 siu(
'time_control',
'auxinput1_inname',
"met_nmm.d<domain>.<date>")
751 if self.nl.nl_have_sect(
'dm_task_split'):
752 siu(
'dm_task_split',
'comm_start',[-1])
753 siu(
'dm_task_split',
'nest_pes_x',[-1])
754 siu(
'dm_task_split',
'nest_pes_y',[-1])
755 if sh(
'domains',
'nproc_x')
and sh(
'domains',
'nproc_y'):
756 nd(
'domains',
'nproc_x')
757 nd(
'domains',
'nproc_y')
759 siu(
'domains',
'nproc_x',-1)
760 siu(
'domains',
'nproc_y',-1)
763 nio_tpg=ng(
'namelist_quilt',
'nio_tasks_per_group')
764 nio_g=ng(
'namelist_quilt',
'nio_groups')
767 if isinstance(nio_tpg,list):
769 total_nio_tpg+=int(num)
772 if isinstance(nio_tpg,basestring):
773 nio_tpg_str=nio_tpg.strip().strip(
',').strip()
774 if ',' in nio_tpg_str:
775 nio_tpg_split=nio_tpg_str.split(
',')
777 nio_tpg_split=nio_tpg_str.split()
778 for num
in nio_tpg_split:
779 total_nio_tpg+=int(num)
781 nio=total_nio_tpg * nio_g
782 siu(
'namelist_quilt',
'poll_servers',nio > 0)
785 s(
'domains',
'numtiles',1)
786 s(
'domains',
'tile_sz_x',0)
787 s(
'domains',
'tile_sz_y',0)
789 """!Sets nproc_x and nproc_y in the namelist
791 Sets the WRF namelist values of nproc_x and nproc_y, which
792 configure task geometry. Default values are -1, which tells
793 WRF to automatically decide the task geometry.
794 @param nproc_x,nproc_y the new values, which default to -1"""
798 s(
'domains',
'nproc_x',nproc_x)
799 s(
'domains',
'nproc_y',nproc_y)
802 """Adds the WRF hifreq_d<domain>.htcf product to the
803 specified domains of nestlevel in this simulation."""
807 if domain.nestlevel == nestlevel:
811 comm_start_d01=-1, nest_pes_x_d01=-1, nest_pes_y_d01=-1):
812 """Sets the WRF namelist values of comm_start, nest_pes_x and
813 nest_pes_y, which configures task geometry. Default
814 values are -1, which tells WRF to automatically decide the
817 The nest_pes_x or nest_pes_y MUST BE either a comma
818 seperated string, list of ints, or a single int.
825 if comm_start_d01==-1
and nest_pes_x_d01==-1
and nest_pes_y_d01==-1:
826 if self.nl.nl_have_sect(
'dm_task_split'):
827 self.nl.nl_del_sect(
'dm_task_split')
835 if isinstance(comm_start,basestring):
836 if len(comm_start.strip().split(
',')) > 1:
837 comm_start_ints=[int(s)
for s
in comm_start.strip().split(
',')]
838 elif len(comm_start.strip().split()) > 1:
839 comm_start_ints=[int(s)
for s
in comm_start.strip().split()]
841 comm_start_ints=[int(comm_start.strip())]
843 comm_start_ints=int(comm_start)
845 if isinstance(nest_pes_x,basestring):
846 if len(nest_pes_x.strip().split(
',')) > 1:
847 nest_pes_x_ints=[int(s)
for s
in nest_pes_x.strip().split(
',')]
848 elif len(nest_pes_x.strip().split()) > 1:
849 nest_pes_x_ints=[int(s)
for s
in nest_pes_x.strip().split()]
851 nest_pes_x_ints=[int(nest_pes_x.strip())]
853 nest_pes_x_ints=int(nest_pes_x)
855 if isinstance(nest_pes_y,basestring):
856 if len(nest_pes_y.strip().split(
',')) > 1:
857 nest_pes_y_ints=[int(s)
for s
in nest_pes_y.strip().split(
',')]
858 elif len(nest_pes_y.strip().split()) > 1:
859 nest_pes_y_ints=[int(s)
for s
in nest_pes_y.strip().split()]
861 nest_pes_y_ints=[int(nest_pes_y.strip())]
863 nest_pes_y_ints=int(nest_pes_y)
865 self.nl.nl_set(
'dm_task_split',
'comm_start',comm_start_ints)
866 self.nl.nl_set(
'dm_task_split',
'nest_pes_x',nest_pes_x_ints)
867 self.nl.nl_set(
'dm_task_split',
'nest_pes_y',nest_pes_y_ints)
872 """!Does this stream have any outputs?
874 Determines if the specified stream has output.
875 @returns True if the stream if add_output() has been called
876 for this stream, for any domain, and False otherwise.
877 @param stream the string name of the stream (lower-case)."""
879 if domain.has_output(stream):
883 """!Sets the I/O server configuration in WRF.
885 Sets the WRF I/O server configuration in the &namelist_quilt
888 @param tasks_per_group the nio_tasks_per_group setting, which
889 specifies the number of I/O server tasks in each I/O server
891 @param groups the nio_groups setting, an integer which
892 specifies the number of I/O server groups.
893 @param poll_servers the poll_servers setting, a logical that
894 specifies whether I/O server polling should be enabled."""
897 if isinstance(tasks_per_group,basestring):
898 tasks_per_group_str=tasks_per_group.strip().strip(
',').strip()
899 if ',' in tasks_per_group_str:
900 tasks_per_group_split=tasks_per_group_str.split(
',')
902 tasks_per_group_split=tasks_per_group_str.split()
903 if len(tasks_per_group_split) > 1:
904 nio_tpg_ints=[int(s)
for s
in tasks_per_group_split]
906 nio_tpg_ints=[int(tasks_per_group_split)]
908 nio_tpg_ints=int(tasks_per_group)
911 poll_servers=bool(poll_servers)
913 s(
'namelist_quilt',
'nio_tasks_per_group',nio_tpg_ints)
914 s(
'namelist_quilt',
'nio_groups',groups)
915 s(
'namelist_quilt',
'poll_servers',poll_servers)
919 """!The number of I/O server tasks per group"""
920 iopg=self.nl.nl_get(
'namelist_quilt',
'nio_tasks_per_group',
'1')
924 """!The number of I/O server groups"""
925 ngroups=self.nl.nl_get(
'namelist_quilt',
'nio_groups',
'0')
929 """!Sets the boundary input interval (interval_seconds)
931 Sets the interval at which this WRF simulation expects
932 boundary conditions. Accepts anything that can be passed to
934 @param step boundary input interval. Can be anything accepted
937 step=to_timedelta(step)
938 step=to_fraction(step)
939 step=int(float(round(step)))
940 self.nl.trait_set(
'bdystep',step)
941 self.nl.nl_set(
'time_control',
'interval_seconds',step)
943 """!Returns the boundary input interval (interval_seconds)
945 Computes the interval at which this WRF simulation expects
946 boundary conditions as a datetime.timedelta. This is done
947 using the "bdystep" trait.
948 @return the boundary input interval (interval_seconds) as a
949 datetime.timedelta"""
950 return to_timedelta(self.nl.trait_get(
'bdystep'))
952 """!Returns the epsilon for boundary time equality comparison
954 Returns the largest difference between two times such that
955 they are considered identical. This is used in the context of
956 WRF boundary input times. This is equal to bdystep()/10
957 @return a fractions.Fraction with the suggested epsilon for
958 equality comparisons of boundary output time."""
959 return to_fraction(self.nl.trait_get(
'bdystep'))/10
961 """!Iterates over boundary times
963 Iterates over times at which this WRF simulation expects
964 boundary conditions. Yields datetime objects for each
968 end=self.
simend() + to_timedelta(to_fraction(dt)/10)
973 """!Returns the number of OpenMP tiles per MPI patch
975 Gets the number of WRF tiles in each WRF patch, returning 1 if
976 tiling is not in use."""
982 """!Sets the OpenMP tiling information.
984 Sets the number of WRF OpenMP tiles in each WRF MPI patch to x
985 by y. Don't use this: OpenMP is not supported by WRF-NMM"""
987 s(
'domains',
'numtiles',int(x)*int(y))
988 s(
'domains',
'tile_sz_x',int(x))
989 s(
'domains',
'tile_sz_y',int(y))
991 """!Generates a Conf2Namelist for this simulation
993 Generates a Conf2Namelist object for the namelist that
994 should be input to wrf.exe
995 @param section_sorter the section_sorter argument to hwrf.namelist.Conf2Namelist.__init__
996 @param var_sorters the var_sorters argument to hwrf.namelist.Conf2Namelist.__init__
997 @return an hwrf.namelist.Conf2Namelist object that can generate namelists for this simulation"""
999 domain_nl_list=[d.nl
for d
in self]
1000 domain_nl=domain_nl_list[0].join(domain_nl_list[1:])
1001 return domain_nl.copy(other=nl).remove_traits().set_sorters(
1002 _wrf_namelist_order,_wrf_nl_var_order)
1003 def _analysis_setup(self,io_form=None):
1004 """!Internal function for configuring wrfanl file generation
1006 Sets several namelist settings related to reading and writing
1007 wrfanl files. This does not enable wrfanl reading or writing
1008 though - that is done by analysis_out() and analysis_in().
1009 @param io_form the restart file io_form """
1012 io_form=self.nl.trait_get(
1013 'io_form_restart',self.nl.trait_get(
'io_form',
1015 self.nl.nl_set(
'time_control',
'io_form_restart',io_form)
1016 self.nl.nl_set(
'time_control',
'override_restart_timers',
True)
1017 self.nl.nl_set(
'time_control',
'restart',
False)
1018 self.nl.nl_set_if_unset(
'time_control',
'restart_interval',36000)
1019 self.nl.nl_set(
'time_control',
'reset_simulation_start',
False)
1021 """!Requests that this WRF simulation write analysis files.
1023 Sets up the namelist settings for writing analysis files
1024 @param io_form the io_form for restart (wrfanl) files
1028 domain.nl.nl_set(
'time_control',
'analysis',
False)
1032 """!Requests that this WRF simulation read an analysis file.
1034 Sets up the namelist settings for reading analysis files
1035 @param io_form the io_form for restart (wrfanl) files
1042 domain.nl.nl_set(
'time_control',
'analysis',val)
1046 """!Sets the WRF wrfanl output file pattern for all domains.
1048 Sets the output file pattern for the wrfanl file. It sets
1049 this for ALL domains.
1050 @param pattern the pattern for all wrfout files. Make sure
1051 you include at least one <domain> in the pattern
1052 @bug this function ignores the pattern argument. It always
1053 sets the pattern to "wrfanl_d<domain>_<date>" """
1055 domain.nl.nl_set(
'time_control',
'anl_outname',
1056 'wrfanl_d<domain>_<date>')
1058 """!Returns the wrfanl name for the specified domain
1060 Produces an analysis filename for the specified domain. NOTE:
1061 this function assumes all domains have the same wrfanl
1063 @param domain the wrf domain of interest (integer grid_id,
1064 string name or a WRFDomain object)
1065 @return the filename as a string"""
1066 domain=self.
get(domain)
1067 domid=self.
get(domain).get_grid_id()
1068 pattern=domain.nl.nl_get(
'time_control',
'anl_outname',
1069 'wrfanl_d<domain>_<date>')
1070 return parse_wrf_outname(pattern,domid,self.
simstart(),
1073 """!Requests reading of a restart file
1075 Raises NotImplementedError(). This would request that this
1076 WRF simulation read a restart file. This is not implemented
1077 since the restart capability was broken as of the writing of
1079 raise NotImplementedError(
1080 'Restart capability is presently broken in HWRF.')
1083 """!Sets the io_form for all active streams.
1085 Changes the io_form for all streams to the specified io_form
1086 @param io_form the io_form as an integer"""
1087 io_form=int(io_form)
1089 for var,value
in self.nl.nl_each(
'time_control'):
1090 if var.find(
'io_form')>=0:
1093 self.nl.nl_set(
'time_control',var,io_form)
1095 """!Sets the io_form for the given stream
1097 Changes the io_form for the specified stream
1098 @param stream the string name of the stream, lower-case
1099 @param io_form the io_form to use. If unspecified or None,
1100 then self.io_form_for(stream) is called"""
1101 io_form_stream=
'io_form_%s'%(stream,)
1103 ts=self.nl.trait_set
1105 if io_form
is not None:
1106 s(
'time_control',io_form_stream,int(io_form))
1107 ts(io_form_stream,int(io_form))
1109 s(
'time_control',io_form_stream,self.
io_form_for(stream))
1112 """!sets the simulation start and tend times, and timestep
1114 Sets the simulation start and end times, and timestep. The
1115 start may be anything accepted by to_datetime. The end is
1116 passed through to_datetime_rel, relative to start. The
1117 timestep must be accepted by to_fraction.
1118 @param start,end simulation start and end times
1119 @param timestep the outermost domain timestep"""
1121 if end
is None: end=self.
_simend
1122 if timestep
is None: timestep=self.
_timestep
1123 start=to_datetime(start)
1124 end=to_datetime_rel(end,start)
1125 timestep=to_fraction(timestep)
1127 domain.set_timing(start,end,timestep/domain.moad_ratio())
1132 """!Sets the num_metgrid_levels and num_metgrid_soil_levels
1134 Overrides the num_metgrid_levels in &domains to equal the
1135 value in the specified metgrid file. Does this by analyzing
1136 the output of metgrid.
1137 @param exepath path to the hwrf_metgrid_levels program
1138 @param metgrid_out_file path to the metgrid out file to read
1139 @param logger optional logging.Logger for logging"""
1141 strmet=str(metgrid_out_file)
1142 nummet=runstr(batchexe(strexe)[strmet],logger=logger)
1143 numsm=runstr(batchexe(strexe)[strmet,
'num_sm_levels'],logger=logger)
1144 numst=runstr(batchexe(strexe)[strmet,
'num_st_levels'],logger=logger)
1148 numsoil=min(numsm,numst)
1149 if logger
is not None:
1150 logger.info(
'Have %d levels, %d soil levels (m=%d t=%d).'
1151 %(nummet,numsoil,numsm,numst))
1152 self.nl.nl_set(
'domains',
'num_metgrid_levels',nummet)
1153 self.nl.nl_set(
'domains',
'num_metgrid_soil_levels',numsoil)
1155 """!Suns swcorner_dynamic to set domain start locations
1157 Runs the swcorner_dynamic program to fill in this
1158 WRFSimulation's domain start locations. Returns the resulting
1159 namelist as a multi-line string.
1161 @param exepath full path to the hwrf_swcorner_dynamic
1162 @param storminfo an hwrf.storminfo.StormInfo object for the
1164 @param domlat,domlon the outermost domain center lat & lon,
1165 which is also the projection center
1166 @param logger optional logger.Logger object for logging"""
1170 junkwrf.fill_auto_starts(7)
1171 junknml=junkwrf.wrf_namelist().make_namelist()
1172 with open(
'fort.12',
'wt')
as f:
1175 with open(
'domain.center',
'wt')
as f:
1176 f.write(
'%f\n%f\n'%(float(domlat),float(domlon)))
1178 with open(
'storm.center',
'wt')
as f:
1179 f.write(
'%f\n%f\n'%(storminfo.lat,storminfo.lon))
1182 checkrun(bigexe(strexe) << str(storminfo.hwrfbasin2),logger=logger)
1183 if not isnonempty(
'set_nest'):
1184 raise SetNestFailed(
'%s could not find the nest south-west '
1185 'corner point.'%(strexe,))
1187 (istart, jstart) = (-99,-99)
1188 with open(
'set_nest',
'rt')
as f:
1190 line=line.upper().rstrip()
1191 m=re.search(
'([IJ])START=([0-9.+-]+)',line)
1194 if ij==
'I': istart=int(val)
1195 if ij==
'J': jstart=int(val)
1196 elif line
and logger:
1197 logger.warning(
'%s: ignoring unrecognized line %s'
1198 %(strexe,line.rstrip()))
1199 if not (istart>5
and jstart>5):
1201 '%s: could not find the south-west corner point '
1202 '(istart=%d jstart=%d)'%(strexe,istart,jstart))
1205 except Exception
as e:
1207 logger.warning(
'%s unexpected exception: %s'
1208 %(strexe,str(e)),exc_info=
True)
1214 """Runs the swcorner_dynamic program to fill in this
1215 WRFSimulation's domain start locations. Returns the resulting
1216 namelist as a multi-line string.
1219 exepath = full path to the hwrf_swcorner_dynamic
1221 all_storminfo = a list of hwrf.storminfo.StormInfo objects
1222 for all the real storms in the multistorm run.
1225 domlat, domlon = the outermost domain center lat & lon,
1226 which is also the projection center
1228 logger = optional: a logger.Logger object for logging"""
1232 junkwrf.fill_auto_starts(7)
1233 junknml=junkwrf.wrf_namelist().make_namelist()
1234 with open(
'fort.12',
'wt')
as f:
1240 with open(
'domain.center',
'wt')
as f:
1241 f.write(
'%f\n%f\n'%(float(domlat),float(domlon)))
1246 for index, storminfo
in enumerate(all_storminfo):
1247 with open(
'storm.center',
'wt')
as f:
1248 f.write(
'%f\n%f\n'%(storminfo.lat,storminfo.lon))
1251 checkrun(bigexe(strexe) << str(storminfo.hwrfbasin2),logger=logger)
1256 if not isnonempty(
'set_nest'):
1257 raise SetNestFailed(
'%s could not find the nest south-west '
1258 'corner point.'%(strexe,))
1260 (istart, jstart) = (-99,-99)
1261 with open(
'set_nest',
'rt')
as f:
1263 line=line.upper().rstrip()
1264 m=re.search(
'([IJ])START=([0-9.+-]+)',line)
1269 istarts.append(istart)
1272 jstarts.append(jstart)
1273 elif line
and logger:
1274 logger.warning(
'%s: ignoring unrecognized line %s'
1275 %(strexe,line.rstrip()))
1276 if not (istart>5
and jstart>5):
1278 '%s: could not find the south-west corner point '
1279 '(istart=%d jstart=%d)'%(strexe,istart,jstart))
1280 except Exception
as e:
1282 logger.warning(
'%s unexpected exception: %s'
1283 %(strexe,str(e)),exc_info=
True)
1288 except Exception
as e:
1290 logger.warning(
'%s unexpected exception: %s'
1291 %(strexe,str(e)),exc_info=
True)
1297 """!monitors a running wrf simulation
1299 This class represents a WRF simulation that is running in an
1300 external workflow. It reads the WRF configuration to internally
1301 generate namelist information, as if it was going to run the WRF
1302 itself. It then monitors the running or completed WRF simulation
1303 for simulation output, making it available as Product objects.
1304 All WRF outputs are available as UpstreamProduct objects.
1306 The WRFSimulation object is available as the public "wrf" member
1307 variable and is initialized by the ExternalWRFTask constructor
1308 using arguments similar to the WRFSimulation constructor. The
1309 simulation start, end and timestep, if unspecified, are taken from
1310 the specified conf section's variables by the same name."""
1311 def __init__(self,dstore,conf,section,wrf,relocate=False,**kwargs):
1312 """!ExternalWRFTask constructor
1314 Creates an ExternalWRFTask, as a wrapper around a
1315 WRFSimulation. The conf, section, moad, simstart, simend and
1316 timestep are passed on to the WRFSimulation. If simstart,
1317 simend, or timestep are None or missing, then they are taken
1318 from the configuration section for this task."""
1321 if 'skip_parent' not in kwargs
or not kwargs[
'skip_parent']:
1322 HWRFTask.__init__(self,dstore,conf,section,**kwargs)
1324 if 'outdir' not in self:
1325 if 'outdir' not in kwargs:
1326 self[
'outdir']=os.path.join(self.
getdir(
'WORKhwrf'),
1329 self[
'outdir']=str(kwargs[
'outdir'])
1330 with self.dstore.transaction()
as t:
1331 for p
in self.
products(relocate=relocate):
pass
1341 """Allows subclasses to change self.location in the
1342 constructor before product generation."""
1344 """!returns the WRFSimulation object that describes the simulation
1346 Returns the underlying WRFSimulation object that describes the
1347 simulation that is being run."""
1350 """!marks products as not having been delivered
1352 Marks all products as not having been delivered. Does not
1357 """!clears cached Product objects
1359 Clears the cache of WRFOutput -> Product mappings, used to
1360 speed up as_product. Calling this will ensure that any later
1361 calls to as_product will generate new Product objects."""
1364 """!Returns the product cached for the specified wrfout or None if not found.
1366 @param wrfout the hwrf.wrfbase.WRFOutput"""
1367 if self.__prodcache.has_key(wrfout):
1370 def _set_cache(self,wrfout,uf):
1371 """!Sets the cached produtil.datastore.UpstreamFile for the given wrfout
1372 @param wrfout the hwrf.wrfbase.WRFOutput for which uf is the cached product
1373 @param uf the product to return from _get_cache() and as_product()
1378 """!Converts a WRFOutput to a Product.
1380 Returns a Product for a WRFOutput. The Product is cached in
1381 self.__prodcache and as_product() will return that cached
1382 value if one is available. Otherwise, a new one is created.
1383 Call clear_cached_products() to clear the cache."""
1384 if self.__prodcache.has_key(wrfout):
1388 outdir=self[
'outdir']
1389 assert(outdir
is not None)
1390 loc=os.path.join(outdir,os.path.basename(wrfout.path()))
1391 with self.dstore.transaction()
as t:
1393 prodname=rel,location=loc)
1394 stream=wrfout.stream()
1395 minsize_def=self.
confint(
'minsize',0)
1396 minsize=self.
confint(
'minsize_'+stream,minsize_def)
1397 minage_def=self.
confint(
'minage',20)
1398 minage=self.
confint(
'minage_'+stream,minage_def)
1401 uf[
'minsize']=minsize
1403 if relocate: uf.location=loc
1406 def products(self,domains=None,stream=None,time=None,relocate=False):
1407 """!Iterate over products
1409 Iterates over all Products subject to the given constraints,
1410 or all Products if no constraints are given:
1412 @param domains only these WRFDomains
1413 @param stream only these streams (strings)
1414 @param time only these times. The earliest output time that
1415 is not before the target time is yielded
1416 @param relocate passed to self.as_product. Forces an update
1417 of the product location """
1419 domlist=[d
for d
in self.
__wrf]
1420 elif isinstance(domains,WRFDomainBase)
or isinstance(domains,int) \
1421 or isinstance(domains,basestring):
1422 domlist=[self.__wrf.get(domain)]
1424 domlist=[self.__wrf.get(d)
for d
in domains]
1425 for domain
in domlist:
1427 for out
in domain.get_all_outputs(time):
1430 for out
in domain.get_outputs(stream):
1433 yield self.
as_product(domain.get_output(stream,time),
1436 """!Update file availability information
1438 Calls produtil.datastore.UpstreamFile.check() to update the
1439 availability information on all products() that match the
1442 @param product only this product is checked
1443 @param stream only these streams (strings)
1444 @param time only these times. The earliest output time that
1445 is not before the target time is yielded"""
1446 if product
is not None:
1449 for prod
in self.
products(stream,time):
1452 """!Is the WRF running, completed or failed?
1454 Scans the rsl.out.0000 file to automatically determine the
1455 state of the WRF simulation. Looks for "SUCCESS COMPLETE" and
1456 "FATAL CALLED" to detect successful completion, or calling of
1457 wrf_error_fatal. Sets self.state to
1458 produtil.datastore.COMPLETED, produtil.datastore.FAILED,
1459 produtil.datastore.RUNNING or produtil.datastore.UNSTARTED
1460 based on the contents of rsl.out.0000"""
1462 logger.info(
'Check on status of WRF...')
1463 rsl0=os.path.join(self.
location,
'rsl.out.0000')
1465 logger.info(
'No RSL file here: '+repr(rsl0))
1466 self.
state=UNSTARTED
1468 with open(rsl0,
'rt')
as f:
1470 f.seek(-10000,os.SEEK_END)
1471 except EnvironmentError
as e:
1473 'Cannot seek -10000 bytes. Will read whole file.')
1477 if re.search(
'SUCCESS COMPLETE',line):
1478 logger.info(
'WRF is complete: %s'%(line.rstrip(),))
1479 self.
state=COMPLETED
1481 elif re.search(
'FATAL CALLED',line):
1482 logger.info(
'WRF failed: %s'%(line.rstrip(),))
1485 except EnvironmentError
as e:
1486 logger.warning(
'Unexpected error checking WRF: %s'%(str(e),),
1488 self.
state=UNSTARTED
Raised when failing to set the parent start location via the set_nest (set_ij_start) program...
This module provides a set of utility functions to do filesystem operations.
def get_moad(self)
returns the MOAD as a WRFDomain.
def get_output
Get output for a specified time and stream.
io_form
the default io_form if none is specified
Generates a Fortran namelist entirely from config files.
def set_timing
sets the simulation start and tend times, and timestep
def swcorner_dynamic_multistorm
def getdt(self)
Returns the timestep for this domain.
def wrf(self)
returns the WRFSimulation object that describes the simulation
def get_output_range(self, stream)
Returns the range of times that has output for the given stream.
def set_metgrid_levels_from
Sets the num_metgrid_levels and num_metgrid_soil_levels.
taskname
Read-only property: the name of this task.
def nx(self)
The number of grid cells the X direction.
The base class of tasks run by the HWRF system.
def moad_ratio(self)
Returns the nesting ratio between this domain and the MOAD.
def update_state(self)
Is the WRF running, completed or failed?
def analysis_in
Requests that this WRF simulation read an analysis file.
dstore
Read-only property, an alias for getdatastore(), the Datastore in which this Datum resides...
nl
The hwrf.namelist.Conf2Namelist for this domain.
nocolons
True if colons should be omitted from filenames.
def nio_tasks_per_group(self)
The number of I/O server tasks per group.
def nio_groups(self)
The number of I/O server groups.
def init_as_moad(self, simstart, simend, simdt, eta_levels)
Called by WRFSimulation to initialize this as the outermost domain.
def clear_cached_products(self)
clears cached Product objects
name
The name of this domain.
def has_output(self, stream)
Returns True if the domain will output to the specified stream.
def set_io_servers
Sets the I/O server configuration in WRF.
def _get_output_time(self, when)
Internal function that determines the time output would actually be generated.
def _analysis_setup
Internal function for configuring wrfanl file generation.
def bdyepsilon(self)
Returns the epsilon for boundary time equality comparison.
def set_timing(self, start, end, timestep)
Sets start and end times and timestep.
def change_location(self)
low-level wrf implementation, underlying hwrf.wrf
def unrun(self)
marks products as not having been delivered
_tiling
Unused: stores OpenMP tiling information.
def __init__
Creates a new WRFSimulation object:
def default_wrf_outname(stream)
default wrf output filename patterns
def is_moad(self)
Is this the outermost domain?
def __repr__(self)
A string description of this domain.
def copy(self)
Makes a deep copy of this object.
Base class of tasks run by HWRF.
A shell-like syntax for running serial, MPI and OpenMP programs.
def getdir
Alias for hwrf.config.HWRFConfig.get() for the "dir" section.
def set_nprocs
Sets nproc_x and nproc_y in the namelist.
def simstart(self)
Returns the simulation start time as a datetime.datetime.
def isnonempty(filename)
Returns True if the filename refers to an existent file that is non-empty, and False otherwise...
Stores products and tasks in an sqlite3 database file.
location
Read-write property, an alias for getlocation() and setlocation().
def set_bdystep(self, step)
Sets the boundary input interval (interval_seconds)
def get_all_outputs
Iterate over all output files for a specified time.
Time manipulation and other numerical routines.
Raised when attempting to obtain information about when a WRF stream outputs, if the stream is disabl...
def no_output(self, stream)
Forget that output was requested for a given stream.
def add_output
Adds output to the specified stream.
def fill_auto_starts_multistorm
def confint
Alias for self.conf.getint for section self.section.
def add_hifreq(self, nestlevel)
def make_namelist(self)
Creates the WRF namelist contents and returns it as a string.
This module provides two different ways to generate Fortran namelist files from HWRFConfig sections: ...
def set_active_io_form_to(self, io_form)
Sets the io_form for all active streams.
def hifreq_file(self)
Returns the hifreq filename for this domain.
def as_product
Converts a WRFOutput to a Product.
def interval_for(self, stream)
Return the output interval for the stream.
Raised when a time was requested with higher precision than available.
def _get_output
Internal function that generates WRFOutput objects.
def log
Obtain a logging domain.
monitors a running wrf simulation
A class that provides information about WRF output and input files.
_io_form
the default io_form
abstract base class of WRFSimulation
def analysis_out
Requests that this WRF simulation write analysis files.
Base class of WRF-related errors.
Sorts a pre-determined list of objects, placing unknown items at a specified location.
Superclass of exceptions relating to groups of one or more distinct times and relationships between t...
def _get_cache(self, wrfout)
Returns the product cached for the specified wrfout or None if not found.
dy
the resolution in the rotated latitude direction
def init_as_nest(self, parent, grid_id, start, end)
Called by WRFSimulation to initialize this domain as a nest.
def __init__
WRFDomain constructor.
def simend(self)
Returns the simulation end time as a datetime.datetime.
def fill_auto_starts
sets i_parent_start and j_parent_start if needed
Raised when a timespan's beginning is not at a timestep.
def set_tiling(self, x, y)
Sets the OpenMP tiling information.
__wrf
the underlying WRFSimulation object
def get_nocolons(self)
Force a recheck of whether colons be omitted from filenames.
def _validate_timespan(self, start, end, timestep)
checks if a timespan is valid
def restart_in(self, restartsource)
Requests reading of a restart file.
def wrf_namelist
Generates a Conf2Namelist for this simulation.
Exceptions raised by the hwrf package.
def num_tiles(self)
Returns the number of OpenMP tiles per MPI patch.
generate and manipulate wrf namelists, predict output filenames
parent
The parent WRFDomain.
def get(self, what)
return the specified domain
def nz(self)
The number of grid cells the Z direction.
def has_output(self, stream)
Does this stream have any outputs?
def swcorner_dynamic
Suns swcorner_dynamic to set domain start locations.
def products
Iterate over products.
def bdystep(self)
Returns the boundary input interval (interval_seconds)
def analysis_name(self, domain)
Returns the wrfanl name for the specified domain.
def wrf_check
Update file availability information.
def hide_output(self, stream)
Disable output for a specified stream, if the stream was requested before.
nestlevel
The WRF domain nesting level.
def get_anl_time(self)
returns the analysis time
def trackpatcf_file(self)
def copy(self)
Returns a deep copy of this object.
def get_outputs(self, stream)
Iterates over all outputs for a specified stream.
dx
the resolution in the rotated longitude direction
def io_form_for(self, stream)
Returns the io_form for the specified stream.
def init_domain(self, grid_id)
Internal helper function that initializes variables common to all domains.
def __init__(self, dstore, conf, section, wrf, relocate=False, kwargs)
ExternalWRFTask constructor.
def ny(self)
The number of grid cells the Y direction.
Raised when the hwrf.wrf.WRFDomain start type is unrecognized.
def bdytimes(self)
Iterates over boundary times.
__prodcache
a mapping from WRFOutput to WRFProduct, used only as a cache
def set_wrfanl_outname(self, pattern)
Sets the WRF wrfanl output file pattern for all domains.
A domain in a WRF simulation.
def set_io_form
Sets the io_form for the given stream.
Represents a Product created by an external workflow.
def get_grid_id(self)
Returns the WRF grid id.