Coverage for python/lsst/source/injection/bin/make_injection_pipeline.py: 19%

37 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-10 05:24 -0700

1# This file is part of source_injection. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <https://www.gnu.org/licenses/>. 

21 

22from __future__ import annotations 

23 

24import logging 

25import os 

26import time 

27from argparse import SUPPRESS, ArgumentParser 

28 

29from ..utils.make_injection_pipeline import make_injection_pipeline 

30from .source_injection_help_formatter import SourceInjectionHelpFormatter 

31 

32 

33def build_argparser(): 

34 """Build an argument parser for this script.""" 

35 parser = ArgumentParser( 

36 description="""Make an expanded source injection pipeline. 

37 

38This script takes a reference pipeline definition file in YAML format and 

39prefixes all post-injection dataset type names with the injected prefix. If an 

40optional injection pipeline definition YAML file is also provided, the 

41injection task will be merged into the pipeline. Unless explicitly excluded, 

42all subsets from the reference pipeline containing the task which generates 

43the injection dataset type will also be updated to include the injection task. 

44A series of new injection subsets will also be constructed. These new subsets 

45are copies of existent subsets, but with tasks not directly impacted by source 

46injection removed. Injected subsets will be the original existent subset name 

47with the 'injected_' prefix prepended. 

48""", 

49 formatter_class=SourceInjectionHelpFormatter, 

50 epilog="More information is available at https://pipelines.lsst.io.", 

51 add_help=False, 

52 argument_default=SUPPRESS, 

53 ) 

54 parser.add_argument( 

55 "-t", 

56 "--dataset-type-name", 

57 type=str, 

58 help="Name of the datset type being injected into.", 

59 required=True, 

60 metavar="TEXT", 

61 ) 

62 parser.add_argument( 

63 "-r", 

64 "--reference-pipeline", 

65 type=str, 

66 help="Location of a reference pipeline definition YAML file.", 

67 required=True, 

68 metavar="FILE", 

69 ) 

70 parser.add_argument( 

71 "-i", 

72 "--injection-pipeline", 

73 type=str, 

74 help="Location of an injection pipeline definition YAML file stub. If " 

75 "this is not explicitly provided, an attempt to infer the injection " 

76 "pipeline stub will be made using the injected dataset type name.", 

77 metavar="FILE", 

78 ) 

79 parser.add_argument( 

80 "-e", 

81 "--exclude-subsets", 

82 help="Do not update pipeline subsets to include the injection task.", 

83 action="store_true", 

84 ) 

85 parser.add_argument( 

86 "-x", 

87 "--excluded-tasks", 

88 type=str, 

89 help="Comma-separated set of task labels to exclude from the pipeline.", 

90 metavar="task", 

91 default="jointcal,gbdesAstrometricFit,fgcmBuildFromIsolatedStars,fgcmFitCycle,fgcmOutputProducts", 

92 ) 

93 parser.add_argument( 

94 "-f", 

95 "--filename", 

96 help="Path to save a modified pipeline definition YAML file.", 

97 metavar="FILE", 

98 ) 

99 parser.add_argument( 

100 "--overwrite", 

101 help="Overwrite the output saved pipeline definition file if it already exists.", 

102 action="store_true", 

103 ) 

104 parser.add_argument( 

105 "--prefix", 

106 type=str, 

107 help="Prefix to prepend to each affected post-injection dataset type name.", 

108 default="injected_", 

109 ) 

110 parser.add_argument( 

111 "--instrument", 

112 type=str, 

113 help="Add instrument overrides. Must be a fully qualified class name.", 

114 metavar="instrument", 

115 ) 

116 parser.add_argument( 

117 "-c", 

118 "--config", 

119 type=str, 

120 help="Config override for a task, in the format 'label:key=value'.", 

121 action="append", 

122 ) 

123 parser.add_argument( 

124 "-h", 

125 "--help", 

126 action="help", 

127 help="Show this help message and exit.", 

128 ) 

129 return parser 

130 

131 

132def main(): 

133 """Use this as the main entry point when calling from the command line.""" 

134 # Set up logging. 

135 tz = time.strftime("%z") 

136 logging.basicConfig( 

137 format="%(levelname)s %(asctime)s.%(msecs)03d" + tz + " - %(message)s", 

138 datefmt="%Y-%m-%dT%H:%M:%S", 

139 ) 

140 logger = logging.getLogger(__name__) 

141 logger.setLevel(logging.DEBUG) 

142 

143 args = build_argparser().parse_args() 

144 if hasattr(args, "filename"): 

145 if os.path.exists(args.filename): 

146 if not hasattr(args, "overwrite"): 

147 raise RuntimeError(f"File {args.filename} already exists; use --overwrite to write anyway.") 

148 else: 

149 logger.warning("File %s already exists; overwriting.", args.filename) 

150 pipeline = make_injection_pipeline( 

151 **{k: v for k, v in vars(args).items() if k not in ["filename", "overwrite"]} 

152 ) 

153 pipeline.write_to_uri(args.filename) 

154 logger.info( 

155 "Modified pipeline definition YAML file saved at %s.", 

156 os.path.realpath(args.filename), 

157 ) 

158 else: 

159 pipeline = make_injection_pipeline( 

160 **{k: v for k, v in vars(args).items() if k not in ["filename", "overwrite"]} 

161 ) 

162 print("\n", pipeline, sep="")