Browse Source

add possibilty to tag rundirs with user-defined labels (grond tag)

priors
Sebastian Heimann 2 years ago
committed by miili
parent
commit
aa8276a2c5
8 changed files with 149 additions and 3 deletions
  1. +2
    -0
      CHANGELOG.md
  2. +66
    -0
      src/apps/grond.py
  3. +16
    -1
      src/environment.py
  4. +2
    -1
      src/report/app/css/local.css
  5. +1
    -0
      src/report/app/js/app.js
  6. +4
    -0
      src/report/app/templates/report_list_modal.tmpl.html
  7. +4
    -1
      src/report/base.py
  8. +54
    -0
      src/run_info.py

+ 2
- 0
CHANGELOG.md View File

@ -15,3 +15,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Plot descriptions improved
- Grond plot now has a `--show` option to display MPL plots interactively.
- Grond reports can now be viewed in IE.
- User can now add self-defined labels to a run dir (`grond tag`). The labels
are shown in the report list.

+ 66
- 0
src/apps/grond.py View File

@ -34,6 +34,7 @@ subcommand_descriptions = {
'plot': 'plot optimisation result',
'movie': 'visualize optimiser evolution',
'export': 'export results',
'tag': 'add user-defined label to run directories',
'report': 'create result report',
'diff': 'compare two configs or other normalized Grond YAML files',
'qc-polarization': 'check sensor orientations with polarization analysis',
@ -62,6 +63,10 @@ subcommand_usages = {
'plot config ( <rundir> | <configfile> <eventname> ) [options]'),
'movie': 'movie <rundir> <xpar> <ypar> <filetemplate> [options]',
'export': 'export (best|mean|ensemble|stats) <rundirs> ... [options]',
'tag': (
'tag add <tag> <rundir>',
'tag remove <tag> <rundir>',
'tag list <rundir>'),
'report': (
'report <rundir> ... [options]',
'report <configfile> <eventnames> ...'),
@ -100,6 +105,7 @@ Subcommands:
plot %(plot)s
movie %(movie)s
export %(export)s
tag %(tag)s
report %(report)s
diff %(diff)s
qc-polarization %(qc_polarization)s
@ -861,6 +867,66 @@ def command_export(args):
die(str(e))
def command_tag(args):
def setup(parser):
parser.add_option(
'-d', '--dir-names',
dest='show_dirnames',
action='store_true',
help='show directory names instead of run names')
parser, options, args = cl_parse('tag', args, setup)
if len(args) < 2:
help_and_die(parser, 'two or more arguments required')
action = args.pop(0)
if action not in ('add', 'remove', 'list'):
help_and_die(parser, 'invalid action: %s' % action)
if action in ('add', 'remove'):
if len(args) < 2:
help_and_die(parser, 'three or more arguments required')
tag = args.pop(0)
rundirs = args
if action == 'list':
rundirs = args
from grond.environment import Environment
errors = False
for rundir in rundirs:
try:
env = Environment([rundir])
if options.show_dirnames:
name = rundir
else:
name = env.get_problem().name
info = env.get_run_info()
if action == 'add':
info.add_tag(tag)
env.set_run_info(info)
elif action == 'remove':
info.remove_tag(tag)
env.set_run_info(info)
elif action == 'list':
print('%-60s : %s' % (
name,
', '.join(info.tags)))
except grond.GrondError as e:
errors = True
logger.error(e)
if errors:
die('errors occurred, see log messages above.')
def command_report(args):
import matplotlib


+ 16
- 1
src/environment.py View File

@ -2,7 +2,7 @@ import time
import os.path as op
from grond.config import read_config
from grond import meta
from grond import meta, run_info
from grond.problems.base import load_optimiser_info, load_problem_info, \
ModelHistory
@ -172,6 +172,21 @@ class Environment(object):
return self._rundir_path
def get_run_info_path(self):
return op.join(self.get_rundir_path(), 'run_info.yaml')
def get_run_info(self):
run_info_path = self.get_run_info_path()
if not op.exists(run_info_path):
info = run_info.RunInfo()
return info
else:
return run_info.read_info(run_info_path)
def set_run_info(self, info):
run_info_path = self.get_run_info_path()
run_info.write_info(info, run_info_path)
def get_optimiser(self):
if self._optimiser is None:
try:


+ 2
- 1
src/report/app/css/local.css View File

@ -309,7 +309,8 @@ div#browser-warning {
*/
.modal-lg {
max-width: 1100px;
/*max-width: 1100px;*/
max-width: 1400px;
}
.selected {


+ 1
- 0
src/report/app/js/app.js View File

@ -124,6 +124,7 @@ var yaml_type_map = [
['!grond.PNG', Dummy],
['!grond.PDF', Dummy],
['!grond.VersionInfo', Dummy],
['!grond.RunInfo', Dummy],
];
function make_constructor(type) {


+ 4
- 0
src/report/app/templates/report_list_modal.tmpl.html View File

@ -18,6 +18,7 @@
<th><a href ng-click="set_order('depth')">Depth [km]</a></th>
<th><a href ng-click="set_order('type')">Type</a></th>
<th><a href ng-click="set_order('run')">Run</a></th>
<th>Tags</th>
</tr>
</thead>
<tbody>
@ -40,6 +41,9 @@
<td>
{{ line.report_entry.problem_name }}
</td>
<td>
<span ng-repeat="tag in line.report_entry.run_info.tags">{{ tag }}</span>
</td>
</tr>
</tbody>
</table>


+ 4
- 1
src/report/base.py View File

@ -21,6 +21,7 @@ from grond.problems import ProblemInfoNotAvailable, ProblemDataNotAvailable
from grond.version import __version__
from grond import info
from grond.plot import PlotConfigCollection, get_all_plot_classes
from grond.run_info import RunInfo
guts_prefix = 'grond'
logger = logging.getLogger('grond.report')
@ -32,6 +33,7 @@ class ReportIndexEntry(Object):
event_reference = Event.T(optional=True)
event_best = Event.T(optional=True)
grond_version = String.T(optional=True)
run_info = RunInfo.T(optional=True)
class ReportConfig(HasPaths):
@ -184,7 +186,8 @@ def report(env, report_config=None, update_without_plotting=False):
rie = ReportIndexEntry(
path='.',
problem_name=problem.name,
grond_version=problem.grond_version)
grond_version=problem.grond_version,
run_info=env.get_run_info())
fn = op.join(report_path, 'event.solution.best.yaml')
if op.exists(fn):


+ 54
- 0
src/run_info.py View File

@ -0,0 +1,54 @@
import logging
from pyrocko import guts
from pyrocko.guts import List, Unicode, Object
from grond.version import __version__
from grond.meta import GrondError
guts_prefix = 'grond'
logger = logging.getLogger('grond.report')
class RunInfo(Object):
tags = List.T(
Unicode.T(),
help='list of user defined labels')
def add_tag(self, tag):
if tag not in self.tags:
self.tags.append(tag)
self.tags.sort()
else:
logger.warn('while adding tag: tag already set: %s' % tag)
def remove_tag(self, tag):
try:
self.tags.remove(tag)
except ValueError:
logger.warn('while removing tag: tag not set: %s' % tag)
def read_info(path):
try:
info = guts.load(filename=path)
except OSError:
raise GrondError(
'cannot read Grond run info file: %s' % path)
if not isinstance(info, RunInfo):
raise GrondError(
'invalid Grond run info in file "%s"' % path)
return info
def write_info(info, path):
try:
guts.dump(
info,
filename=path,
header='Grond run info file, version %s' % __version__)
except OSError:
raise GrondError(
'cannot write Grond run info file: %s' % path)

Loading…
Cancel
Save