LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Public Member Functions | Static Public Attributes | List of all members
lsst.pipe.tasks.ingestCalibs.CalibsRegisterTask Class Reference
Inheritance diagram for lsst.pipe.tasks.ingestCalibs.CalibsRegisterTask:
lsst.pipe.tasks.ingest.RegisterTask

Public Member Functions

def openRegistry (self, directory, create=False, dryrun=False, name="calibRegistry.sqlite3")
 
def createTable (self, conn, forceCreateTables=False)
 
def addRow (self, conn, info, *args, **kwargs)
 
def updateValidityRanges (self, conn, validity, tables=None)
 
def fixSubsetValidity (self, conn, table, detectorData, validity)
 
def createTable (self, conn, table=None, forceCreateTables=False)
 
def check (self, conn, info, table=None)
 
def addRow (self, conn, info, dryrun=False, create=False, table=None)
 

Static Public Attributes

 ConfigClass = CalibsRegisterConfig
 
string placeHolder = '?'
 
dictionary typemap = {'text': str, 'int': int, 'double': float}
 

Detailed Description

Task that will generate the calibration registry for the Mapper

Definition at line 102 of file ingestCalibs.py.

Member Function Documentation

◆ addRow() [1/2]

def lsst.pipe.tasks.ingestCalibs.CalibsRegisterTask.addRow (   self,
  conn,
  info,
args,
**  kwargs 
)
Add a row to the file table

Definition at line 115 of file ingestCalibs.py.

115  def addRow(self, conn, info, *args, **kwargs):
116  """Add a row to the file table"""
117  info[self.config.validStart] = None
118  info[self.config.validEnd] = None
119  RegisterTask.addRow(self, conn, info, *args, **kwargs)
120 

◆ addRow() [2/2]

def lsst.pipe.tasks.ingest.RegisterTask.addRow (   self,
  conn,
  info,
  dryrun = False,
  create = False,
  table = None 
)
inherited
Add a row to the file table (typically 'raw').

@param conn    Database connection
@param info    File properties to add to database
@param table   Name of table in database

Definition at line 359 of file ingest.py.

359  def addRow(self, conn, info, dryrun=False, create=False, table=None):
360  """Add a row to the file table (typically 'raw').
361 
362  @param conn Database connection
363  @param info File properties to add to database
364  @param table Name of table in database
365  """
366  with conn:
367  if table is None:
368  table = self.config.table
369  ignoreClause = ""
370  if self.config.ignore:
371  ignoreClause = " OR IGNORE"
372  sql = "INSERT%s INTO %s (%s) VALUES (" % (ignoreClause, table, ",".join(self.config.columns))
373  sql += ",".join([self.placeHolder] * len(self.config.columns)) + ")"
374  values = [self.typemap[tt](info[col]) for col, tt in self.config.columns.items()]
375 
376  if dryrun:
377  print("Would execute: '%s' with %s" % (sql, ",".join([str(value) for value in values])))
378  else:
379  conn.cursor().execute(sql, values)
380 
381  sql = "INSERT OR IGNORE INTO %s_visit VALUES (" % table
382  sql += ",".join([self.placeHolder] * len(self.config.visit)) + ")"
383  values = [self.typemap[self.config.columns[col]](info[col]) for col in self.config.visit]
384 
385  if dryrun:
386  print("Would execute: '%s' with %s" % (sql, ",".join([str(value) for value in values])))
387  else:
388  conn.cursor().execute(sql, values)
389 
390 

◆ check()

def lsst.pipe.tasks.ingest.RegisterTask.check (   self,
  conn,
  info,
  table = None 
)
inherited
Check for the presence of a row already

Not sure this is required, given the 'ignore' configuration option.

Definition at line 340 of file ingest.py.

340  def check(self, conn, info, table=None):
341  """Check for the presence of a row already
342 
343  Not sure this is required, given the 'ignore' configuration option.
344  """
345  if table is None:
346  table = self.config.table
347  if self.config.ignore or len(self.config.unique) == 0:
348  return False # Our entry could already be there, but we don't care
349  cursor = conn.cursor()
350  sql = "SELECT COUNT(*) FROM %s WHERE " % table
351  sql += " AND ".join(["%s = %s" % (col, self.placeHolder) for col in self.config.unique])
352  values = [self.typemap[self.config.columns[col]](info[col]) for col in self.config.unique]
353 
354  cursor.execute(sql, values)
355  if cursor.fetchone()[0] > 0:
356  return True
357  return False
358 

◆ createTable() [1/2]

def lsst.pipe.tasks.ingestCalibs.CalibsRegisterTask.createTable (   self,
  conn,
  forceCreateTables = False 
)
Create the registry tables

Definition at line 110 of file ingestCalibs.py.

110  def createTable(self, conn, forceCreateTables=False):
111  """Create the registry tables"""
112  for table in self.config.tables:
113  RegisterTask.createTable(self, conn, table=table, forceCreateTables=forceCreateTables)
114 

◆ createTable() [2/2]

def lsst.pipe.tasks.ingest.RegisterTask.createTable (   self,
  conn,
  table = None,
  forceCreateTables = False 
)
inherited
Create the registry tables

One table (typically 'raw') contains information on all files, and the
other (typically 'raw_visit') contains information on all visits.

@param conn    Database connection
@param table   Name of table to create in database

Definition at line 302 of file ingest.py.

302  def createTable(self, conn, table=None, forceCreateTables=False):
303  """Create the registry tables
304 
305  One table (typically 'raw') contains information on all files, and the
306  other (typically 'raw_visit') contains information on all visits.
307 
308  @param conn Database connection
309  @param table Name of table to create in database
310  """
311  cursor = conn.cursor()
312  if table is None:
313  table = self.config.table
314  cmd = "SELECT name FROM sqlite_master WHERE type='table' AND name='%s'" % table
315  cursor.execute(cmd)
316  if cursor.fetchone() and not forceCreateTables: # Assume if we get an answer the table exists
317  self.log.info('Table "%s" exists. Skipping creation', table)
318  return
319  else:
320  cmd = "drop table if exists %s" % table
321  cursor.execute(cmd)
322  cmd = "drop table if exists %s_visit" % table
323  cursor.execute(cmd)
324 
325  cmd = "create table %s (id integer primary key autoincrement, " % table
326  cmd += ",".join([("%s %s" % (col, colType)) for col, colType in self.config.columns.items()])
327  if len(self.config.unique) > 0:
328  cmd += ", unique(" + ",".join(self.config.unique) + ")"
329  cmd += ")"
330  cursor.execute(cmd)
331 
332  cmd = "create table %s_visit (" % table
333  cmd += ",".join([("%s %s" % (col, self.config.columns[col])) for col in self.config.visit])
334  cmd += ", unique(" + ",".join(set(self.config.visit).intersection(set(self.config.unique))) + ")"
335  cmd += ")"
336  cursor.execute(cmd)
337 
338  conn.commit()
339 
daf::base::PropertySet * set
Definition: fits.cc:912

◆ fixSubsetValidity()

def lsst.pipe.tasks.ingestCalibs.CalibsRegisterTask.fixSubsetValidity (   self,
  conn,
  table,
  detectorData,
  validity 
)
Update the validity ranges among selected rows in the registry.

For defects and qe_curve, the products are valid from their start date until
they are superseded by subsequent defect data.
For other calibration products, the validity ranges are checked and
if there are overlaps, a midpoint is used to fix the overlaps,
so that the calibration data with whose date is nearest the date
of the observation is used.

DM generated calibrations contain a CALIB_ID header
keyword. These calibrations likely require the
incrementValidEnd configuration option set to True.  Other
calibrations generate the calibDate via the DATE-OBS header
keyword, and likely require incrementValidEnd=False.

@param conn: Database connection
@param table: Name of table to be selected
@param detectorData: Values identifying a detector (from columns in self.config.detector)
@param validity: Validity range (days)

Definition at line 139 of file ingestCalibs.py.

139  def fixSubsetValidity(self, conn, table, detectorData, validity):
140  """Update the validity ranges among selected rows in the registry.
141 
142  For defects and qe_curve, the products are valid from their start date until
143  they are superseded by subsequent defect data.
144  For other calibration products, the validity ranges are checked and
145  if there are overlaps, a midpoint is used to fix the overlaps,
146  so that the calibration data with whose date is nearest the date
147  of the observation is used.
148 
149  DM generated calibrations contain a CALIB_ID header
150  keyword. These calibrations likely require the
151  incrementValidEnd configuration option set to True. Other
152  calibrations generate the calibDate via the DATE-OBS header
153  keyword, and likely require incrementValidEnd=False.
154 
155  @param conn: Database connection
156  @param table: Name of table to be selected
157  @param detectorData: Values identifying a detector (from columns in self.config.detector)
158  @param validity: Validity range (days)
159  """
160  columns = ", ".join([self.config.calibDate, self.config.validStart, self.config.validEnd])
161  sql = "SELECT id, %s FROM %s" % (columns, table)
162  sql += " WHERE " + " AND ".join(col + "=?" for col in self.config.detector)
163  sql += " ORDER BY " + self.config.calibDate
164  cursor = conn.cursor()
165  cursor.execute(sql, detectorData)
166  rows = cursor.fetchall()
167 
168  try:
169  valids = collections.OrderedDict([(_convertToDate(row[self.config.calibDate]), [None, None]) for
170  row in rows])
171  except Exception:
172  det = " ".join("%s=%s" % (k, v) for k, v in zip(self.config.detector, detectorData))
173  self.log.warning("Skipped setting the validity overlaps for %s %s: missing calibration dates",
174  table, det)
175  return
176  dates = list(valids.keys())
177  if table in self.config.validityUntilSuperseded:
178  # A calib is valid until it is superseded
179  for thisDate, nextDate in zip(dates[:-1], dates[1:]):
180  valids[thisDate][0] = thisDate
181  valids[thisDate][1] = nextDate
182  valids[dates[-1]][0] = dates[-1]
183  valids[dates[-1]][1] = _convertToDate("2037-12-31") # End of UNIX time
184  else:
185  # A calib is valid within the validity range (in days) specified.
186  for dd in dates:
187  valids[dd] = [dd - datetime.timedelta(validity), dd + datetime.timedelta(validity)]
188  # Fix the dates so that they do not overlap, which can cause the butler to find a
189  # non-unique calib.
190  midpoints = [t1 + (t2 - t1)//2 for t1, t2 in zip(dates[:-1], dates[1:])]
191  for i, (date, midpoint) in enumerate(zip(dates[:-1], midpoints)):
192  if valids[date][1] > midpoint:
193  nextDate = dates[i + 1]
194  valids[nextDate][0] = midpoint + datetime.timedelta(1)
195  if self.config.incrementValidEnd:
196  valids[date][1] = midpoint + datetime.timedelta(1)
197  else:
198  valids[date][1] = midpoint
199  del midpoints
200  del dates
201  # Update the validity data in the registry
202  for row in rows:
203  calibDate = _convertToDate(row[self.config.calibDate])
204  validStart = valids[calibDate][0].isoformat()
205  validEnd = valids[calibDate][1].isoformat()
206  sql = "UPDATE %s" % table
207  sql += " SET %s=?, %s=?" % (self.config.validStart, self.config.validEnd)
208  sql += " WHERE id=?"
209  conn.execute(sql, (validStart, validEnd, row["id"]))
210 
211 
daf::base::PropertyList * list
Definition: fits.cc:913

◆ openRegistry()

def lsst.pipe.tasks.ingestCalibs.CalibsRegisterTask.openRegistry (   self,
  directory,
  create = False,
  dryrun = False,
  name = "calibRegistry.sqlite3" 
)
Open the registry and return the connection handle

Reimplemented from lsst.pipe.tasks.ingest.RegisterTask.

Definition at line 106 of file ingestCalibs.py.

106  def openRegistry(self, directory, create=False, dryrun=False, name="calibRegistry.sqlite3"):
107  """Open the registry and return the connection handle"""
108  return RegisterTask.openRegistry(self, directory, create, dryrun, name)
109 

◆ updateValidityRanges()

def lsst.pipe.tasks.ingestCalibs.CalibsRegisterTask.updateValidityRanges (   self,
  conn,
  validity,
  tables = None 
)
Loop over all tables, filters, and ccdnums,
and update the validity ranges in the registry.

@param conn: Database connection
@param validity: Validity range (days)

Definition at line 121 of file ingestCalibs.py.

121  def updateValidityRanges(self, conn, validity, tables=None):
122  """Loop over all tables, filters, and ccdnums,
123  and update the validity ranges in the registry.
124 
125  @param conn: Database connection
126  @param validity: Validity range (days)
127  """
128  conn.row_factory = sqlite3.Row
129  cursor = conn.cursor()
130  if tables is None:
131  tables = self.config.tables
132  for table in tables:
133  sql = "SELECT DISTINCT %s FROM %s" % (", ".join(self.config.detector), table)
134  cursor.execute(sql)
135  rows = cursor.fetchall()
136  for row in rows:
137  self.fixSubsetValidity(conn, table, row, validity)
138 

Member Data Documentation

◆ ConfigClass

lsst.pipe.tasks.ingestCalibs.CalibsRegisterTask.ConfigClass = CalibsRegisterConfig
static

Definition at line 104 of file ingestCalibs.py.

◆ placeHolder

string lsst.pipe.tasks.ingest.RegisterTask.placeHolder = '?'
staticinherited

Definition at line 283 of file ingest.py.

◆ typemap

dictionary lsst.pipe.tasks.ingest.RegisterTask.typemap = {'text': str, 'int': int, 'double': float}
staticinherited

Definition at line 284 of file ingest.py.


The documentation for this class was generated from the following file: