1
2
3
4 """
5 Utility class to check that all multiframes in a survey are within a
6 product group and all used to make stacks (unless there is a limit on a
7 stack or different microstepping is used)
8
9
10 @author: N.J.G.. Cross
11 @org: WFAU, IfA, University of Edinburgh
12 """
13
14 from __future__ import division, print_function
15
16 from wsatools.CLI import CLI
17 from wsatools.DbConnect.CuSession import CuSession
18 from wsatools.Logger import Logger
19 import wsatools.Utilities as utils
20 import wsatools.DbConnect.CommonQueries as queries
21 from wsatools.SystemConstants import DepCodes
22
23
25 """ Makes sure all multiframes have been assigned
26 """
27
28
29 cuNum = 28
30
31
32
33 dateRange = CuSession.sysc.obsCal.dateRange()
34 maxProdID = None
35 minProdID = None
36 testProds = False
37 testGroups = False
38
39
61
62
63
83
84
85
87 """ Check actual products
88 """
89 productType = 'stack'
90
91
92
93 releaseNum = self.archive.query(
94 selectStr="max(releaseNum)",
95 fromStr="ProgrammeFrame",
96 whereStr="programmeID=%s" % self.programmeID, firstOnly=True)
97
98 frameSetSel = queries.getFrameSelection(productType, noDeeps=True)
99 multiframesSel1 = self.archive.query(
100 selectStr="m.multiframeID",
101 fromStr="Multiframe as m,ProgrammeFrame as p",
102 whereStr="p.programmeID=%s AND p.multiframeID=m.multiframeID AND "
103 "%s AND %s and productID>0 and releaseNum=%s"
104 % (self.programmeID, frameSetSel, DepCodes.selectNonDeprecated,
105 releaseNum))
106
107
108 frameSetSel = queries.getFrameSelection(productType, deepOnly=True)
109 multiframesSel1 += self.archive.query(
110 selectStr="v.multiframeID",
111 fromStr="Provenance as v,ProgrammeFrame as p,Multiframe as m",
112 whereStr="p.programmeID=%s AND p.multiframeID=m.multiframeID AND "
113 "%s AND %s and productID>0 and releaseNum=%s and "
114 "m.multiframeID=v.combiframeID"
115 % (self.programmeID, frameSetSel, DepCodes.selectNonDeprecated,
116 releaseNum))
117 frameTypeSel = queries.getFrameSelection(productType, noDeeps=True)
118 multiframesSel2 = set(self.archive.query(
119 selectStr="m.multiframeID",
120 fromStr="Multiframe as m, ProgrammeFrame as p",
121 whereStr="p.programmeID=%s AND m.multiframeID=p.multiframeID "
122 "AND deprecated in (0,%s) AND %s AND utDate BETWEEN '%s' AND '%s'"
123 % (self.programmeID, DepCodes.intermitDet, frameTypeSel,
124 self.dateRange[0], self.dateRange[1])))
125
126 self.testSelections(set(multiframesSel1), multiframesSel2,
127 productType, "Product production")
128
129
130
132 """ Check whether any overlapping fields.
133 """
134 overlappingFields = self.archive.query(
135 selectStr="s1.fieldID as field1,s2.fieldID as field2,"
136 "(60.*s1.stackRadius) as groupRadius1,(60*s2.stackRadius) as "
137 "groupRadius2,dbo.fGreatCircleDist(s1.ra,s1.dec,s2.ra,s2.dec) "
138 "as distanceMins",
139 fromStr="Required%s as s1,Required%s as s2" % (productType, productType),
140 whereStr="s1.programmeID=%s and s1.programmeID=s2.programmeID and "
141 "s1.fieldID!=s2.fieldID and dbo.fGreatCircleDist(s1.ra,s1.dec,"
142 "s2.ra,s2.dec)<60.*(s1.stackRadius+s2.stackRadius)"
143 % (self.programmeID))
144 if overlappingFields:
145 Logger.addMessage("The following fields are overlapping. "
146 "Problem with SetupProgramme")
147 for field1, field2, rad1, rad2, dist in overlappingFields:
148 Logger.addMessage("Field %s overlaps with field %s. "
149 "They should be separated by at least %s "
150 "arcmins, but are separated by %s arcmins."
151 % (field1, field2, rad1 + rad2, dist))
152
153
154
155 - def testSelections(self, multiframesSel1, multiframesSel2, productType, testType):
156 """
157 """
158 diff1 = multiframesSel1.difference(multiframesSel2)
159 diff2 = multiframesSel2.difference(multiframesSel1)
160 if len(diff1) > 0 or len(diff2) > 0:
161 Logger.addMessage("%s is not complete for %s %ss: " %
162 (testType.title(), self.programme.getAcronym().upper(),
163 productType))
164 if len(diff1) > 0:
165 Logger.addMessage("Following multiframes are in the %s "
166 "selection, but not in all science (stack) "
167 "frames in %s in the time range %s - %s and "
168 "with %s deprecations: %s" %
169 (testType, self.programme.getAcronym().upper(),
170 self.dateRange[0], self.dateRange[1],
171 DepCodes.selectNonDeprecated, diff1))
172 if len(diff2) > 0:
173 Logger.addMessage("Following multiframes are in the all "
174 "science (stack) frames in %s in the time "
175 "range %s - %s and with %s deprecations, but "
176 "not in the %s selection: %s" %
177 (self.programme.getAcronym().upper(),
178 self.dateRange[0], self.dateRange[1],
179 DepCodes.selectNonDeprecated, testType, diff2))
180 else:
181 Logger.addMessage("%s is complete for %s %ss: " %
182 (testType.title(), self.programme.getAcronym(),
183 productType))
184
185
186
187
188
189 if __name__ == "__main__":
190
191
192 CLI.progArgs += [
193 CLI.Argument("programmeID", "DXS"),
194 CLI.Argument("begin_date", "05A", isValOK=CLI.isDateOK),
195 CLI.Argument("end_date", "05A", isValOK=CLI.isDateOK)]
196
197 CLI.progOpts += [
198 CLI.Option('l', "products",
199 "comma separated list of highest layer of products e.g. mosaic "
200 "products if stacks and mosaics, tile products if stacks and tiles or "
201 "stacks if just stacks",
202 "LIST"),
203 CLI.Option('g', "testGroups",
204 "Test the grouping of products after ProgrammeSetup has been run"),
205 CLI.Option('n', "minProdID",
206 "start at this productID in highest layer of products",
207 "NUMBER", isValOK=lambda val: val.isdigit()),
208 CLI.Option('p', "testProducts",
209 "Test the contents of stacks after CU13 has been run"),
210 CLI.Option('v', "verbose",
211 "more verbose logging"),
212
213 CLI.Option('x', "maxProdID",
214 "finish at this productID in highest layer of products",
215 "NUMBER", isValOK=lambda val: val.isdigit())]
216
217 cli = CLI(ProgrammeCoverageChecker, "$Revision: 8995 $")
218 Logger.isVerbose = cli.getOpt("verbose")
219 Logger.addMessage(cli.getProgDetails())
220 cu = ProgrammeCoverageChecker(cli.getArg("programmeID"), cli=cli)
221 try:
222 cu.dateRange = cu.sysc.obsCal.dateRange(cli.getArg("begin_date"),
223 cli.getArg("end_date"))
224 except Exception as error:
225 eType = "Invalid Option"
226 Logger.addExceptionMessage(error, eType)
227 raise SystemExit(eType + ": see log " + cu._log.pathName)
228
229 cu.dirDate = \
230 utils.makeDateTime(cli.getOpt("dir_date")).date.replace('-', '')
231
232 if cli.getOpt("maxProdID"):
233 cu.maxProdID = int(cli.getOpt("maxProdID"))
234
235 if cli.getOpt("minProdID"):
236 cu.minProdID = int(cli.getOpt("minProdID"))
237
238
239 if cli.getOpt("testGroups"):
240 cu.testGroups = cli.getOpt("testGroups")
241 if cli.getOpt("testProducts"):
242 cu.testProds = cli.getOpt("testProducts")
243
244
245 cu.run()
246
247
248