class Base(IDMixin, TimestampMixin):
    """
    Defines base SQlAlchemy model class
    :param visible: Flags visibility of data from the dataservice
    """
    visible = db.Column(db.Boolean(),
                        nullable=False,
                        server_default='true',
                        doc='Flags visibility of data from the dataservice')
Example #2
0
class TaskGenomicFile(db.Model, Base):
    """
    Represents association table between task table and
    genomic_file table. Contains all task, genomic_file combiniations.

    :param kf_id: Unique id given by the Kid's First DCC
    :param created_at: Time of object creation
    :param modified_at: Last time of object modification
    :param is_input: Denotes whether the genomic file was an input to the
        executed task. True = Input, False = Output
    """

    __tablename__ = 'task_genomic_file'
    __prefix__ = 'TG'
    __table_args__ = (db.UniqueConstraint('genomic_file_id', 'task_id',
                                          'is_input'), )
    genomic_file_id = db.Column(KfId(),
                                db.ForeignKey('genomic_file.kf_id'),
                                nullable=False)

    task_id = db.Column(KfId(), db.ForeignKey('task.kf_id'), nullable=False)
    is_input = db.Column(db.Boolean(), nullable=False, default=True)
Example #3
0
class Participant(db.Model, Base):
    """
    Participant entity.
    :param kf_id: Unique id given by the Kid's First DCC
    :param external_id: Name given to participant by contributor
    :param family_id: Id for the participants grouped by family
    :param is_proband: Denotes whether participant is proband of study
    :param race: Race of participant
    :param ethnicity: Ethnicity of participant
    :param gender: Self reported gender of participant
    :param affected_status: Denotes whether participant is affected
    :param diagnosis_category: High level diagnosis categorization
    :param created_at: Time of object creation
    :param modified_at: Last time of object modification
    """
    __tablename__ = 'participant'
    __prefix__ = 'PT'

    external_id = db.Column(db.Text(), doc='ID used by external study')
    family_id = db.Column(KfId(),
                          db.ForeignKey('family.kf_id'),
                          nullable=True,
                          doc='Id for the participants grouped by family')
    is_proband = db.Column(
        db.Boolean(), doc='Denotes whether participant is proband of study')
    race = db.Column(db.Text(), doc='The race of the participant')
    ethnicity = db.Column(db.Text(), doc='The ethnicity of the participant')
    gender = db.Column(db.Text(), doc='The gender of the participant')
    affected_status = db.Column(db.Boolean(),
                                doc='Denotes whether participant is affected')
    diagnosis_category = db.Column(db.Text(),
                                   doc='High level diagnosis categorization')
    species = db.Column(db.Text(),
                        default='H**o sapiens',
                        doc='The species of the research particpant')
    diagnoses = db.relationship(Diagnosis,
                                cascade='all, delete-orphan',
                                backref=db.backref('participant', lazy=True))
    biospecimens = db.relationship(Biospecimen,
                                   backref='participant',
                                   cascade='all, delete-orphan')
    outcomes = db.relationship(Outcome,
                               cascade='all, delete-orphan',
                               backref=db.backref('participant', lazy=True))
    phenotypes = db.relationship(Phenotype,
                                 cascade='all, delete-orphan',
                                 backref=db.backref('participant', lazy=True))

    study_id = db.Column(KfId(), db.ForeignKey('study.kf_id'), nullable=False)

    alias_group_id = db.Column(KfId(), db.ForeignKey('alias_group.kf_id'))

    def add_alias(self, pt):
        """
        A convenience method to make participant 'pt'
        an alias of participant 'self'.
        There are 4 cases to consider:
        1) Participant pt and self have not been assigned an alias
        group. Create a new alias group and add both particpants to it.
        2) Participant pt does not have an alias group, but participant self
        does. Add pt to self's alias group.
        3) Participant self does not have an alias group but particpant pt
        does. Add self to pt's alias group
        4) Both participants already have an alias group. Find which particpant
        has the smaller alias group and merge all particpants in the
        smaller group into the larger group
        ** NOTE ** A particpant's aliases can also be created manually by
        direct manipulation of the particpants in an AliasGroup or
        the particpant's alias_group_id. However, then it is completely up to
        the user to ensure all aliases are in the right group and there aren't
        redundant groups that exist.
        """
        # Neither particpant has an alias group yet
        if (not pt.alias_group) and (not self.alias_group):
            g = AliasGroup()
            g.participants.extend([self, pt])

        # Self belongs to alias group, pt does not
        elif (not pt.alias_group) and (self.alias_group):
            self.alias_group.particpants.append(pt)

        # pt belongs to an alias group, self does not
        elif pt.alias_group and (not self.alias_group):
            pt.alias_group.particpants.append(self)

        # Both particpants belong to two different alias groups
        elif pt.alias_group and self.alias_group:
            # Find smaller alias group first
            c1 = (Participant.query.filter_by(
                alias_group_id=self.alias_group_id).count())
            c2 = (Participant.query.filter_by(
                alias_group_id=pt.alias_group_id).count())

            smaller_alias_group = self.alias_group
            larger_alias_group = pt.alias_group
            if c2 <= c1:
                larger_alias_group = self.alias_group
                smaller_alias_group = pt.alias_group

            # Merge smaller alias group with larger alias group
            # aka, change all participants' alias_group_id in the smaller group
            # to be the alias_group_id of the larger group
            for p in (db.session.query(Participant).filter(
                    Participant.alias_group_id == smaller_alias_group.kf_id)):
                p.alias_group = larger_alias_group

            # Delete old alias group
            db.session.delete(smaller_alias_group)

    @property
    def aliases(self):
        """
        Retrieve aliases of participant
        Return all participants with same alias group id
        """
        if self.alias_group:
            return [
                pt for pt in Participant.query.filter(
                    and_(Participant.alias_group_id == self.alias_group_id),
                    Participant.kf_id != self.kf_id)
            ]
        else:
            return []

    def __repr__(self):
        return '<Participant {}>'.format(self.kf_id)
class SequencingExperiment(db.Model, Base):
    """
    SequencingExperiment entity.
    :param kf_id: Unique id given by the Kid's First DCC
    :param external_id: Name given to sequencing experiment by contributor
    :param experiment_date : Date of the sequencing experiment conducted
    :param experiment_strategy: Text term that represents the library strategy
    :param library_name: Text term that represents the name of the library
    :param library_strand: Text term that represents the library stranded-ness
    :param is_paired_end: Boolean term specifies whether reads have paired end
    :param platform: Name of the platform used to obtain data
    :param instrument_model: Text term that represents the model of instrument
    :param max_insert_size: Maximum size of the fragmented DNA
    :param mean_insert_size: Mean size of the fragmented DNA
    :param mean_depth: (Coverage)Describes the amount of sequence data that
           is available per position in the sequenced genome territory
    :param total_reads: Total reads of the sequencing experiment
    :param mean_read_length: Mean lenth of the reads
    """
    __tablename__ = 'sequencing_experiment'
    __prefix__ = 'SE'

    external_id = db.Column(db.Text(), nullable=False,
                            doc='Name given to sequencing experiment by'
                            ' contributor')
    experiment_date = db.Column(db.DateTime(),
                                doc='Date of the sequencing experiment'
                                ' conducted')
    experiment_strategy = db.Column(db.Text(), nullable=False,
                                    doc='Text term that represents the'
                                    ' Library strategy')
    library_name = db.Column(db.Text(),
                             doc='Text term that represents the name of the'
                             ' library')
    library_strand = db.Column(db.Text(),
                               doc='Text term that represents the'
                               ' library stranded-ness')
    is_paired_end = db.Column(db.Boolean(), nullable=False,
                              doc='Boolean term specifies whether reads have'
                              ' paired end')
    platform = db.Column(db.Text(), nullable=False,
                         doc='Name of the platform used to obtain data')
    instrument_model = db.Column(db.Text(),
                                 doc='Text term that represents the model of'
                                 ' instrument')
    max_insert_size = db.Column(db.Integer(),
                                doc='Maximum size of the fragmented DNA')
    mean_insert_size = db.Column(db.Float(),
                                 doc='Mean size of the fragmented DNA')
    mean_depth = db.Column(db.Float(),
                           doc='Mean depth or coverage describes the amount of'
                           ' sequence data that is available per position in'
                           ' the sequenced genome territory')
    total_reads = db.Column(db.Integer(),
                            doc='Total reads of the sequencing experiment')
    mean_read_length = db.Column(db.Float(),
                                 doc='Mean lenth of the reads')
    genomic_files = db.relationship(GenomicFile,
                                    backref=db.backref(
                                        'sequencing_experiment',
                                        lazy=True))
    sequencing_center_id = db.Column(KfId(),
                                     db.ForeignKey('sequencing_center.kf_id'),
                                     nullable=False,
                                     doc='The kf_id of the sequencing center')