Ejemplo n.º 1
0
    def get(self, obj_id):
        phase_fold_data = self.get_query_argument("phaseFoldData", False)

        if Obj.get_if_accessible_by(obj_id, self.current_user) is None:
            raise AccessError(
                f"Insufficient permissions for User {self.current_user.id} to read Obj {obj_id}"
            )
        photometry = Photometry.query_records_accessible_by(
            self.current_user).filter(Photometry.obj_id == obj_id)
        format = self.get_query_argument('format', 'mag')
        outsys = self.get_query_argument('magsys', 'ab')

        self.verify_and_commit()
        data = [serialize(phot, outsys, format) for phot in photometry]

        if phase_fold_data:
            period, modified = None, arrow.Arrow(1, 1, 1)
            annotations = (Annotation.query_records_accessible_by(
                self.current_user).filter(Annotation.obj_id == obj_id).all())
            period_str_options = ['period', 'Period', 'PERIOD']
            for an in annotations:
                if not isinstance(an.data, dict):
                    continue
                for period_str in period_str_options:
                    if period_str in an.data and arrow.get(
                            an.modified) > modified:
                        period = an.data[period_str]
                        modified = arrow.get(an.modified)
            if period is None:
                self.error(f'No period for object {obj_id}')
            for ii in range(len(data)):
                data[ii]['phase'] = np.mod(data[ii]['mjd'], period) / period

        return self.success(data=data)
Ejemplo n.º 2
0
    def parse_id_list(self, id_list, model_class):
        """
        Return a list of integer IDs from the comma separated
        string of IDs given by the query argument, and the
        model/table to be queried.

        Parameters
        ----------
        id_list: string
            Comma separated list of integer values.
        model_class: class
            A skyportal data model class, e.g., Group, Instrument.
        """

        if id_list is None:
            return  # silently pass through any None values

        try:
            accessible_rows = model_class.get_records_accessible_by(
                self.current_user)
            validated_ids = []
            for id in id_list.split(','):
                id = int(id)
                if id not in [row.id for row in accessible_rows]:
                    raise AccessError(
                        f'Invalid {model_class.__name__} IDs field ("{id_list}"); '
                        f'Not all {model_class.__name__} IDs are valid/accessible'
                    )
                validated_ids.append(id)
        except ValueError:
            raise ValueError(
                f'Invalid {model_class.__name__} IDs field ("{id_list}"); '
                f'Could not parse all elements to integers')

        return validated_ids
Ejemplo n.º 3
0
def get_source_if_owned_by(obj_id, user_or_token, options=[]):
    if Source.query.filter(Source.obj_id == obj_id).first() is None:
        return None
    user_group_ids = [g.id for g in user_or_token.groups]
    s = (Source.query.filter(Source.obj_id == obj_id).filter(
        Source.group_id.in_(user_group_ids)).options(options).first())
    if s is None:
        raise AccessError("Insufficient permissions.")
    return s.obj
Ejemplo n.º 4
0
    async def post(self):
        data = self.get_json()
        featureset_name = data.get('featuresetName', '')
        dataset_id = int(data['datasetID'])
        features_to_use = [
            feature for (feature, selected) in data.items()
            if feature in dask_feature_graph and selected
        ]
        if not features_to_use:
            return self.error("At least one feature must be selected.")

        custom_feats_code = data['customFeatsCode'].strip()
        custom_script_path = None

        dataset = Dataset.query.filter(Dataset.id == dataset_id).one()
        if not dataset.is_owned_by(self.current_user):
            raise AccessError('No such data set')

        fset_path = pjoin(self.cfg['paths:features_folder'],
                          '{}_featureset.npz'.format(uuid.uuid4()))

        fset = Featureset(name=featureset_name,
                          file_uri=fset_path,
                          project=dataset.project,
                          features_list=features_to_use,
                          custom_features_script=None)
        DBSession().add(fset)

        client = await self._get_client()

        all_time_series = client.map(time_series.load,
                                     [f.uri for f in dataset.files])
        all_labels = client.map(lambda ts: ts.label, all_time_series)
        all_features = client.map(featurize.featurize_single_ts,
                                  all_time_series,
                                  features_to_use=features_to_use,
                                  custom_script_path=custom_script_path,
                                  raise_exceptions=False)
        computed_fset = client.submit(featurize.assemble_featureset,
                                      all_features, all_time_series)
        imputed_fset = client.submit(featurize.impute_featureset,
                                     computed_fset,
                                     inplace=False)
        future = client.submit(featurize.save_featureset,
                               imputed_fset,
                               fset_path,
                               labels=all_labels)
        fset.task_id = future.key
        DBSession().commit()

        loop = tornado.ioloop.IOLoop.current()
        loop.spawn_callback(self._await_featurization, future, fset)

        self.success(fset, 'cesium/FETCH_FEATURESETS')
Ejemplo n.º 5
0
def get_candidate_if_owned_by(obj_id, user_or_token, options=[]):
    if Candidate.query.filter(Candidate.obj_id == obj_id).first() is None:
        return None
    user_group_ids = [g.id for g in user_or_token.groups]
    c = (Candidate.query.filter(Candidate.obj_id == obj_id).filter(
        Candidate.filter_id.in_(
            DBSession.query(Filter.id).filter(
                Filter.group_id.in_(user_group_ids)))).options(
                    options).first())
    if c is None:
        raise AccessError("Insufficient permissions.")
    return c.obj
Ejemplo n.º 6
0
def get_obj_if_owned_by(obj_id, user_or_token, options=[]):
    try:
        obj = Source.get_obj_if_owned_by(obj_id, user_or_token, options)
    except AccessError:  # They may still be able to view the associated Candidate
        obj = Candidate.get_obj_if_owned_by(obj_id, user_or_token, options)
        if obj is None:
            # If user can't view associated Source, and there's no Candidate they can
            # view, raise AccessError
            raise
    if obj is None:  # There is no associated Source/Cand, so check based on photometry
        if Obj.get_photometry_owned_by_user(obj_id, user_or_token):
            return Obj.query.options(options).get(obj_id)
        raise AccessError("Insufficient permissions.")
    # If we get here, the user has access to either the associated Source or Candidate
    return obj
Ejemplo n.º 7
0
def add_linked_thumbnails_and_push_ws_msg(obj_id, user_id):
    with Session() as session:
        try:
            user = session.query(User).get(user_id)
            if Obj.get_if_accessible_by(obj_id, user) is None:
                raise AccessError(
                    f"Insufficient permissions for User {user_id} to read Obj {obj_id}"
                )
            obj = session.query(Obj).get(obj_id)
            obj.add_linked_thumbnails(session=session)
            flow = Flow()
            flow.push(
                '*', "skyportal/REFRESH_SOURCE", payload={"obj_key": obj.internal_key}
            )
            flow.push(
                '*', "skyportal/REFRESH_CANDIDATE", payload={"id": obj.internal_key}
            )
        except Exception as e:
            log(f"Unable to add linked thumbnails to {obj_id}: {e}")
            session.rollback()