예제 #1
0
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]
예제 #2
0
    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
예제 #3
0
    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()
예제 #4
0
    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()
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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()