1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

# http://pyrocko.org - GPLv3 

# 

# The Pyrocko Developers, 21st Century 

# ---|P------/S----------~Lg---------- 

 

from __future__ import absolute_import, print_function 

 

import argparse 

import logging 

 

from pyrocko import util 

from pyrocko.squirrel import error 

 

 

logger = logging.getLogger('psq.tool.common') 

 

 

class PyrockoHelpFormatter(argparse.RawDescriptionHelpFormatter): 

def __init__(self, *args, **kwargs): 

kwargs['width'] = 79 

argparse.RawDescriptionHelpFormatter.__init__(self, *args, **kwargs) 

 

 

class PyrockoArgumentParser(argparse.ArgumentParser): 

 

def __init__(self, *args, **kwargs): 

 

kwargs['formatter_class'] = PyrockoHelpFormatter 

 

argparse.ArgumentParser.__init__(self, *args, **kwargs) 

 

if hasattr(self, '_action_groups'): 

for group in self._action_groups: 

if group.title == 'positional arguments': 

group.title = 'Positional arguments' 

 

elif group.title == 'optional arguments': 

group.title = 'Optional arguments' 

 

 

def csvtype(choices): 

def splitarg(arg): 

values = arg.split(',') 

for value in values: 

if value not in choices: 

raise argparse.ArgumentTypeError( 

'Invalid choice: {!r} (choose from {})' 

.format(value, ', '.join(map(repr, choices)))) 

return values 

return splitarg 

 

 

def add_parser(subparsers, *args, **kwargs): 

kwargs['add_help'] = False 

p = subparsers.add_parser(*args, **kwargs) 

p.add_argument( 

'--help', '-h', 

action='help', 

help='Show this help message and exit.') 

return p 

 

 

def add_selection_arguments(p): 

from pyrocko import squirrel as sq 

 

p.add_argument( 

'paths', 

nargs='*', 

help='Files and directories with waveforms, metadata and events.') 

 

p.add_argument( 

'--optimistic', '-o', 

action='store_false', 

dest='check', 

default=True, 

help='Disable checking file modification times.') 

 

p.add_argument( 

'--format', '-f', 

dest='format', 

metavar='FORMAT', 

default='detect', 

choices=sq.supported_formats(), 

help='Assume input files are of given FORMAT. Choices: %(choices)s. ' 

'Default: %(default)s.') 

 

p.add_argument( 

'--kind', '-k', 

type=csvtype(sq.supported_content_kinds()), 

dest='kinds', 

help='Restrict meta-data scanning to given content kinds. ' 

'KINDS is a comma-separated list of content kinds, choices: %s. ' 

'By default, all content kinds are indexed.' 

% ', '.join(sq.supported_content_kinds())) 

 

p.add_argument( 

'--persistent', '-p', 

dest='persistent', 

metavar='NAME', 

help='Create/use persistent selection with given NAME. Persistent ' 

'selections can be used to speed up startup of Squirrel-based ' 

'applications.') 

 

p.add_argument( 

'--update', '-u', 

dest='update', 

action='store_true', 

default=False, 

help='Allow adding paths and datasets to existing persistent ' 

'selection.') 

 

p.add_argument( 

'--dataset', '-d', 

dest='datasets', 

default=[], 

action='append', 

metavar='FILE', 

help='Add directories/files/sources from dataset description file. ' 

'This option can be repeated to add multiple datasets.') 

 

 

def squirrel_from_selection_arguments(args): 

from pyrocko.squirrel import base, dataset 

 

datasets = [ 

dataset.read_dataset(dataset_path) for dataset_path in args.datasets] 

 

persistents = [ds.persistent for ds in datasets] 

if args.persistent: 

persistent = args.persistent 

elif persistents: 

persistent = persistents[0] 

if not all(p == persistents for p in persistents[1:]): 

raise error.SquirrelError( 

'Given datasets specify different `persistent` settings.') 

 

logger.info( 

'Persistent selection requested by dataset: %s' % persistent) 

 

squirrel = base.Squirrel(persistent=persistent) 

 

if persistent and not squirrel.is_new(): 

if not args.update: 

logger.info( 

'Using existing persistent selection: %s' % persistent) 

if args.paths or datasets: 

logger.info( 

'Avoiding dataset rescan. Use --update/-u to ' 

'rescan or add items to existing persistent selection.') 

 

return squirrel 

 

else: 

logger.info( 

'Updating existing persistent selection: %s' % persistent) 

 

kinds = args.kinds or None 

if args.paths: 

squirrel.add( 

args.paths, check=args.check, format=args.format, kinds=kinds) 

 

for ds in datasets: 

squirrel.add_dataset(ds, check=args.check) 

 

return squirrel 

 

 

def add_query_arguments(p): 

p.add_argument( 

'--codes', 

dest='codes', 

metavar='CODES', 

help='Code pattern to query (STA, NET.STA, NET.STA.LOC, ' 

'NET.STA.LOC.CHA, NET.STA.LOC.CHA.EXTRA, ' 

'AGENCY.NET.STA.LOC.CHA.EXTRA).') 

 

p.add_argument( 

'--tmin', 

dest='tmin', 

metavar='TIME', 

help='Begin of time interval to query.') 

 

p.add_argument( 

'--tmax', 

dest='tmax', 

metavar='TIME', 

help='End of time interval to query.') 

 

p.add_argument( 

'--time', 

dest='time', 

metavar='TIME', 

help='Time instant to query.') 

 

 

def squirrel_query_from_arguments(args): 

d = {} 

if (args.tmin and args.time) or (args.tmax and args.time): 

raise error.SquirrelError( 

'Options --tmin/--tmax and --time are mutually exclusive.') 

 

if args.kinds: 

d['kind'] = args.kinds 

if args.tmin: 

d['tmin'] = util.str_to_time(args.tmin) 

if args.tmax: 

d['tmax'] = util.str_to_time(args.tmax) 

if args.time: 

d['tmin'] = d['tmax'] = util.str_to_time(args.time) 

if args.codes: 

d['codes'] = tuple(args.codes.split('.')) 

 

return d