def fieldQuery(cadence=None, priority=None, ra_range=None, limit=100): """query targetdb for fields matching parameters """ dbCad = targetdb.Cadence if cadence is not None: matchingCad = dbCad.select().where(dbCad.label.contains(cadence)) else: matchingCad = dbCad.select() Field = targetdb.Field dbVersion = targetdb.Version.get(plan=rs_version) Design = targetdb.Design d2s = opsdb.DesignToStatus doneStatus = opsdb.CompletionStatus.get(label="done").pk doneField = Field.alias() obsDB = targetdb.Observatory() obs = obsDB.get(label=observatory) doneCount = Design.select(fn.COUNT(Design.design_id).alias("count"))\ .join(d2s, JOIN.LEFT_OUTER, on=(Design.design_id == d2s.design_id))\ .switch(Design)\ .join(doneField, JOIN.LEFT_OUTER, on=(Design.field_pk == doneField.pk))\ .where(d2s.completion_status_pk == doneStatus, doneField.pk == Field.pk)\ .alias("doneCount") fields = Field.select(Field, doneCount)\ .where(Field.cadence << matchingCad, Field.version == dbVersion, Field.observatory == obs)\ .limit(limit) if priority is not None: fp = opsdb.FieldPriority f2p = opsdb.FieldToPriority priority = fp.get(label=priority) fields = fields.join(f2p, on=(f2p.field_pk == Field.pk))\ .join(fp, on=(fp.pk == f2p.field_priority_pk))\ .where(fp.pk == priority.pk) if ra_range: assert len(ra_range) == 2, "must specify only begin and end of RA range" # print("RA RAGE", ra_range) if ra_range[0] > ra_range[1]: # implied between ra_range[1] and 360, or between 0 and ra_range[0] fields = fields.where((Field.racen > ra_range[0]) | (Field.racen < ra_range[1])).order_by(Field.racen) else: fields = fields.where((Field.racen > ra_range[0]) & (Field.racen < ra_range[1])).order_by(Field.racen) # print(fields.sql()) # select returns query object, we want a list return [f for f in fields]
def hist(self): # """The observation history of the field. Unlike Fields.observations, # this property will be used on sky. # Attributes: # ---------- # _hist : dict of lists # A dictionary with field_id keys containing lists of obs mjds for # each field. # """ if self._hist is None: self._hist = {f: list() for f in self.field_id} if self._database: versionDB = targetdb.Version() ver = versionDB.get(plan=self.plan) obsDB = targetdb.Observatory() obs = obsDB.get(label=self.observatory.upper()) Field = targetdb.Field Design = targetdb.Design Status = opsdb.CompletionStatus d2s = opsdb.DesignToStatus done = Status.get(label="done") dbfields = Field.select(d2s.mjd, Field.field_id)\ .join(Design)\ .join(d2s, on=(Design.pk == d2s.design_pk))\ .where((Field.version == ver) & (Field.observatory == obs), (d2s.status == done)).dicts() for d in dbfields: self._hist[d["field_id"]].append(d["mjd"]) for i in range(len(self.field_id)): self.checkCompletion(i) return self._hist
file_save = replace_path + plan + '_field_replacement_log.fits' files = [] for fid in fieldids: files += [file for file in glob.glob(replace_path + '{plan}_{fid}*.fits'.format( plan=plan, fid=fid))] for f in files: if 'validation' in f: files.remove(f) files_valid = [] for f in files: files_valid.append(f[:-5] + '_validation.fits') # get observatory insts obsDB = targetdb.Observatory() obs_inst = {} obs_inst['APO'] = obsDB.get(label='APO') obs_inst['LCO'] = obsDB.get(label='LCO') # get the instrument pks instr_pks = {} instr_pks['BOSS'] = targetdb.Instrument.get(label='BOSS').pk instr_pks['APOGEE'] = targetdb.Instrument.get(label='APOGEE').pk # create dict of fiber pks fiber_pks = {} fiber_pks['APO'] = {} fiber_pks['LCO'] = {} # get APO holes holes = (targetdb.Hole.select()
def fromdb(self, version=None): """Load this Fields object with fields from the targetdb Parameters: ---------- version : string db version to grab, if Fields.plan is not set. If passed Fields.plan will be reset to version """ if (self._database is False): print("No database available.") return () if version is None: version = self.plan else: self.plan = version assert version is not None, "must specify version!" fields_model = [('field_id', np.int32), ('racen', np.float64), ('deccen', np.float64), ('nfilled', np.int32), ('flag', np.int32), ('slots_exposures', np.int32, (24, 2)), ('cadence', np.dtype('a20'))] versionDB = targetdb.Version() ver = versionDB.get(plan=version) obsDB = targetdb.Observatory() obs = obsDB.get(label=self.observatory.upper()) Field = targetdb.Field dbfields = Field.select().where(Field.version == ver, Field.observatory == obs) fieldid = list() racen = list() deccen = list() slots_exposures = list() cadence = list() flags = list() for field in dbfields: fieldid.append(field.field_id) racen.append(field.racen) deccen.append(field.deccen) slots_exposures.append(field.slots_exposures) cadence.append(field.cadence.label) if len(field.priority) > 0: if field.priority[0].label == "top": flags.append(1) elif field.priority[0].label == "disabled": flags.append(-1) else: flags.append(0) fields = np.zeros(len(dbfields), dtype=fields_model) fields["field_id"] = fieldid fields["racen"] = racen fields["deccen"] = deccen fields["flag"] = flags fields["slots_exposures"] = slots_exposures fields["cadence"] = cadence self.fromarray(fields_array=fields) self.cadencelist.fromdb()
def designQuery(field_id=None, ra_range=None, dbStatus=None, carton=None, limit=100, pa_range=None, instrument="BOSS", orderby=None, design_ids=[]): compStatus = opsdb.CompletionStatus d2s = opsdb.DesignToStatus dbDesign = targetdb.Design dbField = targetdb.Field Assign = targetdb.Assignment Inst = targetdb.Instrument obsDB = targetdb.Observatory() obs = obsDB.get(label=observatory) qInst = Inst.get(label=instrument) designs = dbDesign.select(compStatus.label, dbDesign.design_id, dbField.field_id, dbField.racen, dbField.deccen, dbField.position_angle, fn.COUNT(Assign.pk))\ .join(d2s, on=(d2s.design_id == dbDesign.design_id))\ .join(compStatus, on=(d2s.completion_status_pk == compStatus.pk))\ .switch(dbDesign)\ .join(dbField, on=(dbField.pk == dbDesign.field_pk))\ .switch(dbDesign)\ .join(Assign, on=(dbDesign.design_id == Assign.design_id))\ .where(dbField.observatory == obs, Assign.instrument_pk == qInst.pk)\ .limit(limit) designs = designs.group_by(compStatus.label, dbDesign.design_id, dbField.field_id, dbField.racen, dbField.deccen, dbField.position_angle) if field_id is not None: designs = designs.where(dbField.field_id == field_id) if dbStatus is not None: designs = designs.where(compStatus.label == dbStatus) if carton is not None: C2T = targetdb.CartonToTarget Carton = targetdb.Carton matchingCartons = Carton.select().where(Carton.carton.contains(carton)) designs = designs.join(C2T, on=(Assign.carton_to_target_pk == C2T.pk))\ .where(C2T.carton << matchingCartons) if ra_range and field_id is None: assert len(ra_range) == 2, "must specify only begin and end of RA range" if ra_range[0] > ra_range[1]: # implied between ra_range[1] and 360, or between 0 and ra_range[0] designs = designs.where((dbField.racen > ra_range[0]) | (dbField.racen < ra_range[1])) else: designs = designs.where((dbField.racen > ra_range[0]) & (dbField.racen < ra_range[1])) if pa_range and field_id is None: assert len(pa_range) == 2, "must specify only begin and end of position angle range" designs = designs.where((dbField.position_angle >= pa_range[0]) & (dbField.position_angle <= pa_range[1])) if orderby is not None: translate = {"designID": dbDesign.design_id, "fieldID": dbField.field_id, "RA": dbField.racen, "PA": dbField.position_angle} designs = designs.order_by(translate[orderby]) if len(design_ids) > 0: designs = designs.where(dbDesign.design_id << design_ids) resTuples = designs.tuples() designIDS = [r[1] for r in resTuples] if instrument == "BOSS": qInst = Inst.get(label="APOGEE") else: qInst = Inst.get(label="BOSS") ocounts = dbDesign.select(fn.COUNT(Assign.pk), dbDesign.design_id)\ .join(Assign, on=(dbDesign.design_id == Assign.design_id))\ .group_by(dbDesign.design_id)\ .where(Assign.instrument_pk == qInst.pk, dbDesign.design_id << designIDS) dCounts = {c[1]: c[0] for c in ocounts.tuples()} res = [{"label": d[0], "design_id": d[1], "field_id": d[2], "racen": d[3], "deccen": d[4], "position_angle": d[5], "assigned": d[6], "oassigned": dCounts.get(d[1], 0)} for d in resTuples] return res
def make_design_assignments_targetdb(plan, fieldid, exposure, field_exposure, desmode_label, design_ids, robotID, holeID, obsWavelength, carton, observatory, targetdb_ver=None, instr_pks=None, cart_pks=None, fiber_pks=None, idtype='carton_to_target', return_design_id=False): """ Add assignments for a design to targetdb. Parameters ---------- plan: str or targetdb.Version instance Either robostratgegy plan as a str or a targetdb.Version.get instance for the plan that can be used to get the version pk fieldid: int or targetdb.Field instance The fieldid for the field (int) or a targetdb.Field instance for the field that can be used to get the field pk exposure: int The exposure of this set of designs. 0th indexed field_exposure: int The exposure of this set of designs as listed in the robostrategy design file. 0th indexed desmode_label: str DesignMode labe for the design. design_ids: np.array Array of catalogids or carton_to_target_pks for the design of length N robotID: np.array Array of the robotIDs (robotIDs in robostrategy) for the design of length N holeID: np.array Array of holeIDs for the design of length N carton: np.array Array of cartons for the design of length N obsWavelength: np.array Array of obsWavelength for the design (choice of 'BOSS' or 'APOGEE') for the design of legnth N targetdb_ver: dict Optional dictonary of pks for the targetdb version of each carton used in this design. Dict is indexed by carton names. Only needed if idtype='catalogID'. instr_pks: dict Optional dictonary with the isntrument pks from targetdb. Dict is indexed by instrument names. cart_pks: dict or array Optional dictonary with the possible carton pks for the design. If dict, then indexed by carton name. Optionally can be array of carton pks same length as design entries. Only needed if idtype='catalogID'. fiber_pks: dict Optional dictonary with the holeID pks. Dict is indexed by holeID. idtype: str Defines the id type used in defining the design_ids. Must be 'catalogID' or 'carton_to_target'. return_design_id: boolean Optionally return the design_id for the new entry in the database. """ # make sure idtype is catalogID or carton_to_target if idtype != 'catalogID' and idtype != 'carton_to_target': raise MugatuError( message='idtype must be catalogID or carton_to_target') # get the version pk based on the plan if isinstance(plan, str): versionDB = targetdb.Version() verpk = versionDB.get(plan=plan).pk else: verpk = plan.pk # get the observatory pk if isinstance(observatory, str): obsDB = targetdb.Observatory() obspk = obsDB.get(label=observatory.upper()).pk else: obspk = observatory.pk # get the instrument pks if instr_pks is None: instr_pks = {} instr_pks['BOSS'] = targetdb.Instrument.get(label='BOSS').pk instr_pks['APOGEE'] = targetdb.Instrument.get(label='APOGEE').pk # grab all carton pks here if cart_pks is None and idtype == 'catalogID': cart_pks = {} for cart in np.unique(carton): # skip calibration from now if cart != 'CALIBRATION': cart_pks[cart] = (targetdb.Carton.select( targetdb.Carton.pk).where((targetdb.Carton.carton == cart) & (targetdb.Carton.version_pk == targetdb_ver[cart]))[0].pk) # get the fieldpk if isinstance(fieldid, int): field = ( targetdb.Field.select().where((targetdb.Field.field_id == fieldid) & (targetdb.Field.version == verpk))) fieldpk = field[0].pk else: fieldpk = fieldid[0].pk assign_hash = assignment_hash(design_ids[robotID != -1], holeID[robotID != -1]) designDB = targetdb.Design.create(design_mode=desmode_label, mugatu_version=mugatu_version, run_on=datetime.datetime.now(), assignment_hash=assign_hash) # save row designDB.save() # add the designToField entry make_designToField(designDB.design_id, fieldid, exposure, field_exposure) # add the assignments for the design to the assignment database rows = [] for j in range(len(robotID)): row_dict = {} # right now calibrations are fake, so need to skip if robotID[j] != -1: # get the pk for the positioner_info # (where I assume the ID is just the # row # in the fits file) if fiber_pks is None: this_pos_DB = (targetdb.Hole.get( (targetdb.Hole.holeid == holeID[j]) & (targetdb.Hole.observatory == obspk)).pk) else: this_pos_DB = fiber_pks[holeID[j]] # get the instrument for fiber inst_assign = obsWavelength[j] # add db row info to dic row_dict['design'] = designDB.design_id row_dict['instrument'] = instr_pks[inst_assign] row_dict['hole'] = this_pos_DB if idtype == 'catalogID': if isinstance(cart_pks, dict): cart_pk = cart_pks[carton[j]] else: cart_pk = cart_pks[j] row_dict['carton_to_target'] = (targetdb.CartonToTarget.select( targetdb.CartonToTarget.pk).join( targetdb.Target, on=(targetdb.CartonToTarget.target_pk == targetdb.Target.pk) ).where((targetdb.Target.catalogid == design_ids[j]) & ( targetdb.CartonToTarget.carton_pk == cart_pk))[0].pk) if idtype == 'carton_to_target': row_dict['carton_to_target'] = design_ids[j] rows.append(row_dict) # write all exposures for field to targetdb targetdb.Assignment.insert_many(rows).execute() # return design_id if requested if return_design_id: return designDB.design_id
def make_design_field_targetdb(cadence, fieldid, plan, racen, deccen, position_angle, observatory, slots_exposures, replacement_field=False): """ Create a new field in targetdb. Will return warning if the field already exists in targetdb Parameters ---------- cadence: str or targetdb.Cadence instance Either label of the cadence for the field (str) or a targetdb.Cadence.get instance for the label that can be used to get the cadence pk fieldid: int The fieldid for the field plan: str or targetdb.Version instance Either robostratgegy plan as a str or a targetdb.Version.get instance for the plan that can be used to get the version pk racen: float Right Ascension center of the field (degrees) deccen: float Declination center of the field (degrees) position_angle: float Position angle of the field, East of North (degrees) observatory: str or targetdb.Observatory instance Either label of the observatory for the field (str; either 'apo' or 'lco') or a targetdb.Observatory.get instance for the observatory label that can be used to get the observatory pk replacement_field: boolean If the field is a replacement field. If True then will ignore check for if field exists. """ # get the field cadence pk if isinstance(cadence, str): cadenceDB = targetdb.Cadence() dbCadence = cadenceDB.get(label=cadence).pk else: dbCadence = cadence.pk # get the observatory pk if isinstance(observatory, str): obsDB = targetdb.Observatory() obspk = obsDB.get(label=observatory.upper()).pk else: obspk = observatory.pk # get the version pk based on the plan if isinstance(plan, str): versionDB = targetdb.Version() verpk = versionDB.get(plan=plan).pk else: verpk = plan.pk if replacement_field: fieldDB = targetdb.Field.create(field_id=fieldid, racen=racen, deccen=deccen, position_angle=position_angle, slots_exposures=slots_exposures, cadence=dbCadence, observatory=obspk, version=verpk) # save row in database fieldDB.save() else: # check if field exists field_test = (targetdb.Field.select().where( (targetdb.Field.field_id == fieldid) & (targetdb.Field.version == verpk) & (targetdb.Field.cadence == dbCadence))) # creates new field in database if it doesnt exist if field_test.exists(): flag = 'Field already exists in targetdb' warnings.warn(flag, MugatuWarning) else: fieldDB = targetdb.Field.create(field_id=fieldid, racen=racen, deccen=deccen, position_angle=position_angle, slots_exposures=slots_exposures, cadence=dbCadence, observatory=obspk, version=verpk) # save row in database fieldDB.save()