Ejemplo n.º 1
0
class GeneticSpecimen(models.Model, IndexableMixin):
    """
    Class to describe a biosample used for genomics testing or analysis.
    """
    id = models.CharField(primary_key=True,
                          max_length=200,
                          help_text=rec_help(d.GENETIC_SPECIMEN, "id"))
    specimen_type = JSONField(validators=[ontology_validator],
                              help_text=rec_help(d.GENETIC_SPECIMEN,
                                                 "specimen_type"))
    collection_body = JSONField(blank=True,
                                null=True,
                                validators=[ontology_validator],
                                help_text=rec_help(d.GENETIC_SPECIMEN,
                                                   "collection_body"))
    laterality = JSONField(blank=True,
                           null=True,
                           validators=[ontology_validator],
                           help_text=rec_help(d.GENETIC_SPECIMEN,
                                              "laterality"))
    extra_properties = JSONField(blank=True,
                                 null=True,
                                 help_text=rec_help(d.GENETIC_SPECIMEN,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['id']

    def __str__(self):
        return str(self.id)
Ejemplo n.º 2
0
class Variant(models.Model):
    """
    Class to describe Individual variants or diagnosed causative variants

    FHIR: Observation ?
    Draft extension for Variant is in development
    """

    ALLELE = (
        ('hgvsAllele', 'hgvsAllele'),
        ('vcfAllele', 'vcfAllele'),
        ('spdiAllele', 'spdiAllele'),
        ('iscnAllele', 'iscnAllele'),
    )
    allele_type = models.CharField(max_length=200, choices=ALLELE, help_text="One of four allele types.")
    allele = JSONField(validators=[JsonSchemaValidator(schema=ALLELE_SCHEMA)],
                       help_text=rec_help(d.VARIANT, "allele"))
    zygosity = JSONField(blank=True, null=True, validators=[ontology_validator],
                         help_text=rec_help(d.VARIANT, "zygosity"))
    extra_properties = JSONField(blank=True, null=True, help_text=rec_help(d.VARIANT, "extra_properties"))
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.id)
Ejemplo n.º 3
0
class Disease(models.Model, IndexableMixin):
    """
    Class to represent a diagnosis and inference or hypothesis about the cause
    underlying the observed phenotypic abnormalities

    FHIR: Condition
    """

    term = JSONField(validators=[ontology_validator], help_text=rec_help(d.DISEASE, "term"))
    # "ageOfOnset": {
    # "age": "P38Y7M"
    # }
    # OR
    # "ageOfOnset": {
    # "id": "HP:0003581",
    # "label": "Adult onset"
    # }
    onset = JSONField(blank=True, null=True, validators=[JsonSchemaValidator(schema=PHENOPACKET_DISEASE_ONSET_SCHEMA)],
                      help_text=rec_help(d.DISEASE, "onset"))
    disease_stage = JSONField(blank=True, null=True, validators=[ontology_list_validator],
                              help_text=rec_help(d.DISEASE, "disease_stage"))
    tnm_finding = JSONField(blank=True, null=True, validators=[ontology_list_validator],
                            help_text=rec_help(d.DISEASE, "tnm_finding"))
    extra_properties = JSONField(blank=True, null=True, help_text=rec_help(d.DISEASE, "extra_properties"))
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.id)
Ejemplo n.º 4
0
class LabsVital(models.Model, IndexableMixin):
    """
    Class  to record tests performed on patient.
    """
    # TODO Should this class be a part of Patients app? patient related metadata
    id = models.CharField(primary_key=True,
                          max_length=200,
                          help_text=rec_help(d.LABS_VITAL, "id"))
    individual = models.ForeignKey(Individual,
                                   on_delete=models.CASCADE,
                                   help_text=rec_help(d.LABS_VITAL,
                                                      "individual"))
    # TODO Change CodeableConcept to Ontology class
    tumor_marker_code = JSONField(validators=[ontology_validator],
                                  help_text=rec_help(d.LABS_VITAL,
                                                     "tumor_marker_code"))
    tumor_marker_data_value = JSONField(
        blank=True,
        null=True,
        validators=[tumor_marker_data_value_validator],
        help_text=rec_help(d.LABS_VITAL, "tumor_marker_data_value"))
    extra_properties = JSONField(blank=True,
                                 null=True,
                                 help_text=rec_help(d.LABS_VITAL,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['id']

    def __str__(self):
        return str(self.id)
Ejemplo n.º 5
0
class ExperimentResult(models.Model, IndexableMixin):
    """ Class to represent information about analysis of sequencing data in a file format. """
    # TODO identifier assigned by lab (?)
    identifier = CharField(max_length=200, blank=True, null=True,
                           help_text=rec_help(d.EXPERIMENT_RESULT, "identifier"))
    description = CharField(max_length=500, blank=True, null=True,
                            help_text=rec_help(d.EXPERIMENT_RESULT, "description"))
    filename = CharField(max_length=500, blank=True, null=True,
                         help_text=rec_help(d.EXPERIMENT_RESULT, "filename"))
    genome_assembly_id = CharField(max_length=50, blank=True, null=True,
                                   help_text=rec_help(d.EXPERIMENT_RESULT, "genome_assembly_id"))
    file_format = CharField(max_length=50, blank=True, null=True,
                            help_text=rec_help(d.EXPERIMENT_RESULT, "file_format"))
    data_output_type = CharField(max_length=200, blank=True, null=True,
                                 help_text=rec_help(d.EXPERIMENT_RESULT, "data_output_type"))
    usage = CharField(max_length=200, blank=True, null=True,
                      help_text=rec_help(d.EXPERIMENT_RESULT, "usage"))
    creation_date = CharField(max_length=500, blank=True, null=True,
                              help_text=rec_help(d.EXPERIMENT_RESULT, "creation_date"))
    created_by = CharField(max_length=200, blank=True, null=True,
                           help_text=rec_help(d.EXPERIMENT_RESULT, "created_by"))
    extra_properties = JSONField(blank=True, default=dict, validators=[key_value_validator],
                                 help_text=rec_help(d.EXPERIMENT_RESULT, "extra_properties"))
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.identifier)
Ejemplo n.º 6
0
class Instrument(models.Model, IndexableMixin):
    """ Class to represent information about instrument used to perform a sequencing experiment. """

    # TODO identifier assigned by lab (?)
    identifier = CharField(max_length=200,
                           blank=True,
                           null=True,
                           help_text=rec_help(d.EXPERIMENT_RESULT,
                                              "identifier"))
    platform = CharField(max_length=200,
                         blank=True,
                         null=True,
                         help_text=rec_help(d.INSTRUMENT, "platform"))
    description = CharField(max_length=500,
                            blank=True,
                            null=True,
                            help_text=rec_help(d.INSTRUMENT, "description"))
    model = CharField(max_length=500,
                      blank=True,
                      null=True,
                      help_text=rec_help(d.INSTRUMENT, "model"))
    extra_properties = JSONField(blank=True,
                                 default=dict,
                                 validators=[key_value_validator],
                                 help_text=rec_help(d.INSTRUMENT,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.id)
Ejemplo n.º 7
0
class CancerCondition(models.Model, IndexableMixin):
    """
    Class to record the history of primary or secondary cancer conditions.
    """
    CANCER_CONDITION_TYPE = (('primary', 'primary'), ('secondary',
                                                      'secondary'))
    id = models.CharField(primary_key=True,
                          max_length=200,
                          help_text=rec_help(d.CANCER_CONDITION, "id"))
    condition_type = models.CharField(choices=CANCER_CONDITION_TYPE,
                                      max_length=200,
                                      help_text=rec_help(
                                          d.CANCER_CONDITION,
                                          "condition_type"))
    body_site = JSONField(null=True,
                          validators=[ontology_list_validator],
                          help_text=rec_help(d.CANCER_CONDITION, 'body_site'))
    laterality = JSONField(blank=True,
                           null=True,
                           validators=[ontology_validator],
                           help_text=rec_help(d.CANCER_CONDITION,
                                              "laterality"))
    clinical_status = JSONField(blank=True,
                                null=True,
                                validators=[ontology_validator],
                                help_text=rec_help(d.CANCER_CONDITION,
                                                   "clinical_status"))
    code = JSONField(validators=[ontology_validator],
                     help_text=rec_help(d.CANCER_CONDITION, "code"))
    date_of_diagnosis = models.DateTimeField(blank=True,
                                             null=True,
                                             help_text=rec_help(
                                                 d.CANCER_CONDITION,
                                                 "date_of_diagnosis"))
    histology_morphology_behavior = JSONField(
        blank=True,
        null=True,
        validators=[ontology_validator],
        help_text=rec_help(d.CANCER_CONDITION,
                           "histology_morphology_behavior"))
    verification_status = JSONField(blank=True,
                                    null=True,
                                    validators=[ontology_validator],
                                    help_text=rec_help(d.CANCER_CONDITION,
                                                       "verification_status"))
    extra_properties = JSONField(blank=True,
                                 null=True,
                                 help_text=rec_help(d.CANCER_CONDITION,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['id']

    def __str__(self):
        return str(self.id)
Ejemplo n.º 8
0
class Phenopacket(models.Model, IndexableMixin):
    """
    Class to aggregate Individual's experiments data

    FHIR: Composition
    """

    id = models.CharField(primary_key=True, max_length=200, help_text=rec_help(d.PHENOPACKET, "id"))
    # if Individual instance is deleted Phenopacket instance is deleted too
    # CHECK !!! Force as required?
    subject = models.ForeignKey(
        Individual, on_delete=models.CASCADE, related_name="phenopackets",
        help_text=rec_help(d.PHENOPACKET, "subject"))
    # PhenotypicFeatures are present in Biosample, so can be accessed via Biosample instance
    # phenotypic_features = models.ManyToManyField(PhenotypicFeature, blank=True,
    #   help_text='Phenotypic features observed in the proband.')
    biosamples = models.ManyToManyField(Biosample, blank=True, help_text=rec_help(d.PHENOPACKET, "biosamples"))
    genes = models.ManyToManyField(Gene, blank=True, help_text=rec_help(d.PHENOPACKET, "genes"))
    variants = models.ManyToManyField(Variant, blank=True, help_text=rec_help(d.PHENOPACKET, "variants"))
    diseases = models.ManyToManyField(Disease, blank=True, help_text=rec_help(d.PHENOPACKET, "diseases"))
    hts_files = models.ManyToManyField(HtsFile, blank=True, help_text=rec_help(d.PHENOPACKET, "hts_files"))
    # TODO OneToOneField
    meta_data = models.ForeignKey(MetaData, on_delete=models.CASCADE, help_text=rec_help(d.PHENOPACKET, "meta_data"))
    table = models.ForeignKey("chord.Table", on_delete=models.CASCADE, blank=True, null=True)  # TODO: Help text
    extra_properties = JSONField(blank=True, null=True, help_text=rec_help(d.PHENOPACKET, "extra_properties"))
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.id)
Ejemplo n.º 9
0
class MCodePacket(models.Model, IndexableMixin):
    """
    Class to aggregate Individual's cancer related metadata
    """

    id = models.CharField(primary_key=True,
                          max_length=200,
                          help_text=rec_help(d.MCODEPACKET, "id"))
    subject = models.ForeignKey(Individual,
                                on_delete=models.CASCADE,
                                help_text=rec_help(d.MCODEPACKET, "subject"))
    genomics_report = models.ForeignKey(GenomicsReport,
                                        blank=True,
                                        null=True,
                                        on_delete=models.SET_NULL,
                                        help_text=rec_help(
                                            d.MCODEPACKET, "genomics_report"))
    cancer_condition = models.ManyToManyField(CancerCondition,
                                              blank=True,
                                              help_text=rec_help(
                                                  d.MCODEPACKET,
                                                  "cancer_condition"))
    cancer_related_procedures = models.ManyToManyField(
        CancerRelatedProcedure,
        blank=True,
        help_text=rec_help(d.MCODEPACKET, "cancer_related_procedures"))
    medication_statement = models.ManyToManyField(MedicationStatement,
                                                  blank=True,
                                                  help_text=rec_help(
                                                      d.MCODEPACKET,
                                                      "medication_statement"))
    date_of_death = models.CharField(max_length=200,
                                     blank=True,
                                     help_text=rec_help(
                                         d.MCODEPACKET, "date_of_death"))
    cancer_disease_status = JSONField(blank=True,
                                      null=True,
                                      validators=[ontology_validator],
                                      help_text=rec_help(
                                          d.MCODEPACKET,
                                          "cancer_disease_status"))
    # link to dataset via the table
    table = models.ForeignKey("chord.Table",
                              on_delete=models.CASCADE,
                              blank=True,
                              null=True)  # TODO: Help text
    extra_properties = JSONField(blank=True,
                                 null=True,
                                 help_text=rec_help(d.MCODEPACKET,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['id']

    def __str__(self):
        return str(self.id)
Ejemplo n.º 10
0
class PhenotypicFeature(models.Model, IndexableMixin):
    """
    Class to describe a phenotype of an Individual

    FHIR: Condition or Observation
    """

    description = models.CharField(max_length=200, blank=True, help_text=rec_help(d.PHENOTYPIC_FEATURE, "description"))
    pftype = JSONField(verbose_name='type', validators=[ontology_validator],
                       help_text=rec_help(d.PHENOTYPIC_FEATURE, "type"))
    negated = models.BooleanField(default=False, help_text=rec_help(d.PHENOTYPIC_FEATURE, "negated"))
    severity = JSONField(blank=True, null=True, validators=[ontology_validator],
                         help_text=rec_help(d.PHENOTYPIC_FEATURE, "severity"))
    modifier = JSONField(blank=True, null=True, validators=[ontology_list_validator],
                         help_text=rec_help(d.PHENOTYPIC_FEATURE, "modifier"))
    onset = JSONField(blank=True, null=True, validators=[ontology_validator],
                      help_text=rec_help(d.PHENOTYPIC_FEATURE, "onset"))
    # evidence can stay here because evidence is given for an observation of PF
    # JSON schema to check evidence_code is present
    # FHIR: Condition.evidence
    evidence = JSONField(blank=True, null=True, validators=[JsonSchemaValidator(schema=PHENOPACKET_EVIDENCE_SCHEMA)],
                         help_text=rec_help(d.PHENOTYPIC_FEATURE, "evidence"))
    biosample = models.ForeignKey(
        "Biosample", on_delete=models.SET_NULL, blank=True, null=True, related_name='phenotypic_features')
    phenopacket = models.ForeignKey(
        "Phenopacket", on_delete=models.SET_NULL, blank=True, null=True, related_name='phenotypic_features')
    extra_properties = JSONField(blank=True, null=True, help_text=rec_help(d.PHENOTYPIC_FEATURE, "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.id)
Ejemplo n.º 11
0
class CancerRelatedProcedure(models.Model, IndexableMixin):
    """
    Class to represent radiological treatment or surgical action addressing a cancer condition.
    """

    PROCEDURE_TYPES = (('radiation', 'radiation'), ('surgical', 'surgical'))
    id = models.CharField(primary_key=True,
                          max_length=200,
                          help_text=rec_help(d.CANCER_RELATED_PROCEDURE, "id"))
    procedure_type = models.CharField(choices=PROCEDURE_TYPES,
                                      max_length=200,
                                      help_text=rec_help(
                                          d.CANCER_RELATED_PROCEDURE,
                                          "procedure_type"))
    code = JSONField(validators=[ontology_validator],
                     help_text=rec_help(d.CANCER_RELATED_PROCEDURE, "code"))
    body_site = JSONField(null=True,
                          validators=[ontology_list_validator],
                          help_text=rec_help(d.CANCER_RELATED_PROCEDURE,
                                             'body_site'))
    laterality = JSONField(blank=True,
                           null=True,
                           validators=[ontology_validator],
                           help_text=rec_help(d.CANCER_RELATED_PROCEDURE,
                                              "laterality"))
    treatment_intent = JSONField(blank=True,
                                 null=True,
                                 validators=[ontology_validator],
                                 help_text=rec_help(d.CANCER_RELATED_PROCEDURE,
                                                    "treatment_intent"))
    # Only for Surgical Procedure
    # TODO CHANGE to ontology list validator
    reason_code = JSONField(blank=True,
                            null=True,
                            validators=[ontology_validator],
                            help_text=rec_help(d.CANCER_RELATED_PROCEDURE,
                                               "reason_code"))
    reason_reference = models.ManyToManyField(CancerCondition,
                                              blank=True,
                                              help_text=rec_help(
                                                  d.CANCER_RELATED_PROCEDURE,
                                                  "reason_reference"))
    extra_properties = JSONField(blank=True,
                                 null=True,
                                 help_text=rec_help(d.CANCER_RELATED_PROCEDURE,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['id']

    def __str__(self):
        return str(self.id)
Ejemplo n.º 12
0
class Procedure(models.Model):
    """
    Class to represent a clinical procedure performed on an individual
    (subject) in order to extract a biosample

    FHIR: Procedure
    """

    code = JSONField(help_text=rec_help(d.PROCEDURE, "code"))
    body_site = JSONField(blank=True, null=True, help_text=rec_help(d.PROCEDURE, "body_site"))
    extra_properties = JSONField(blank=True, null=True, help_text=rec_help(d.PROCEDURE, "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.id)
Ejemplo n.º 13
0
class MetaData(models.Model):
    """
    Class to store structured definitions of the resources
    and ontologies used within the phenopacket

    FHIR: Metadata
    """

    created = models.DateTimeField(default=timezone.now, help_text=rec_help(d.META_DATA, "created"))
    created_by = models.CharField(max_length=200, help_text=rec_help(d.META_DATA, "created_by"))
    submitted_by = models.CharField(max_length=200, blank=True, help_text=rec_help(d.META_DATA, "submitted_by"))
    resources = models.ManyToManyField(Resource, help_text=rec_help(d.META_DATA, "resources"))
    updates = ArrayField(
        JSONField(null=True, blank=True), blank=True, null=True,
        help_text=rec_help(d.META_DATA, "updates"))
    phenopacket_schema_version = models.CharField(max_length=200, blank=True,
        help_text='Schema version of the current phenopacket.')
    external_references = ArrayField(
        JSONField(null=True, blank=True), blank=True, null=True,
        help_text=rec_help(d.META_DATA, "external_references"))
    extra_properties = JSONField(
        blank=True, null=True, help_text=rec_help(d.META_DATA, "extra_properties"))
    updated = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.id)
Ejemplo n.º 14
0
class MetaData(models.Model):
    """
    Class to store structured definitions of the resources
    and ontologies used within the phenopacket

    FHIR: Metadata
    """

    created = models.DateTimeField(default=timezone.now, help_text=rec_help(d.META_DATA, "created"))
    created_by = models.CharField(max_length=200, help_text=rec_help(d.META_DATA, "created_by"))
    submitted_by = models.CharField(max_length=200, blank=True, help_text=rec_help(d.META_DATA, "submitted_by"))
    resources = models.ManyToManyField(Resource, help_text=rec_help(d.META_DATA, "resources"))
    updates = JSONField(blank=True, null=True, validators=[JsonSchemaValidator(
                        schema=schema_list(PHENOPACKET_UPDATE_SCHEMA), formats=['date-time'])],
                        help_text=rec_help(d.META_DATA, "updates"))
    phenopacket_schema_version = models.CharField(max_length=200, blank=True,
                                                  help_text='Schema version of the current phenopacket.')
    external_references = JSONField(blank=True, null=True, validators=[JsonSchemaValidator(
                                    schema=schema_list(PHENOPACKET_EXTERNAL_REFERENCE_SCHEMA))],
                                    help_text=rec_help(d.META_DATA, "external_references"))
    extra_properties = JSONField(blank=True, null=True, help_text=rec_help(d.META_DATA, "extra_properties"))
    updated = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.id)
Ejemplo n.º 15
0
class GenomicRegionStudied(models.Model, IndexableMixin):
    """
    Class to describe the area of the genome region referenced in testing for variants.
    """
    id = models.CharField(primary_key=True,
                          max_length=200,
                          help_text=rec_help(d.GENOMIC_REGION_STUDIED, "id"))
    # TODO schema Range list
    dna_ranges_examined = JSONField(blank=True,
                                    null=True,
                                    validators=[ontology_list_validator],
                                    help_text=rec_help(
                                        d.GENOMIC_REGION_STUDIED,
                                        "dna_ranges_examined"))
    dna_region_description = ArrayField(models.CharField(
        max_length=100,
        help_text=rec_help(d.GENOMIC_REGION_STUDIED,
                           'dna_region_description')),
                                        blank=True,
                                        default=list)
    gene_mutation = JSONField(blank=True,
                              null=True,
                              validators=[ontology_list_validator],
                              help_text=rec_help(d.GENOMIC_REGION_STUDIED,
                                                 "gene_mutation"))
    # TODO check: thisis not a Reference in mcode data dictionary why not?
    gene_studied = JSONField(blank=True,
                             null=True,
                             validators=[ontology_list_validator],
                             help_text=rec_help(d.GENOMIC_REGION_STUDIED,
                                                "gene_studied"))
    genomic_reference_sequence_id = JSONField(
        blank=True,
        null=True,
        help_text=rec_help(d.GENOMIC_REGION_STUDIED,
                           "genomic_reference_sequence_id"))
    genomic_region_coordinate_system = JSONField(
        blank=True,
        null=True,
        validators=[ontology_validator],
        help_text=rec_help(d.GENOMIC_REGION_STUDIED,
                           "genomic_region_coordinate_system"))
    extra_properties = JSONField(blank=True,
                                 null=True,
                                 help_text=rec_help(d.GENOMIC_REGION_STUDIED,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['id']

    def __str__(self):
        return str(self.id)
Ejemplo n.º 16
0
class Gene(models.Model):
    """
    Class to represent an identifier for a gene

    FHIR: ?
    Draft extension for Gene is in development
    where Gene defined via class CodeableConcept
    """

    # Gene id is unique
    id = models.CharField(primary_key=True, max_length=200, help_text=rec_help(d.GENE, "id"))
    # CURIE style? Yes!
    alternate_ids = ArrayField(models.CharField(max_length=200, blank=True), blank=True, default=list,
                               help_text=rec_help(d.GENE, "alternate_ids"))
    symbol = models.CharField(max_length=200, help_text=rec_help(d.GENE, "symbol"))
    extra_properties = JSONField(blank=True, null=True, help_text=rec_help(d.GENE, "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.id)
Ejemplo n.º 17
0
class HtsFile(models.Model, IndexableMixin):
    """
    Class to link HTC files with data

    FHIR: DocumentReference
    """

    HTS_FORMAT = (
        ('UNKNOWN', 'UNKNOWN'),
        ('SAM', 'SAM'),
        ('BAM', 'BAM'),
        ('CRAM', 'CRAM'),
        ('VCF', 'VCF'),
        ('BCF', 'BCF'),
        ('GVCF', 'GVCF'),
    )
    uri = models.URLField(primary_key=True, max_length=200, help_text=rec_help(d.HTS_FILE, "uri"))
    description = models.CharField(max_length=200, blank=True, help_text=rec_help(d.HTS_FILE, "description"))
    hts_format = models.CharField(max_length=200, choices=HTS_FORMAT, help_text=rec_help(d.HTS_FILE, "hts_format"))
    genome_assembly = models.CharField(max_length=200, help_text=rec_help(d.HTS_FILE, "genome_assembly"))
    # e.g.
    # "individualToSampleIdentifiers": {
    #   "patient23456": "NA12345"
    # TODO how to perform this validation, ensure the patient id is the correct one?
    individual_to_sample_identifiers = JSONField(
        blank=True, null=True, help_text=rec_help(d.HTS_FILE, "individual_to_sample_identifiers"))
    extra_properties = JSONField(blank=True, null=True, help_text=rec_help(d.HTS_FILE, "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.uri)
Ejemplo n.º 18
0
class Resource(models.Model):
    """
    Class to represent a description of an external resource
    used for referencing an object

    FHIR: CodeSystem
    """
    class Meta:
        unique_together = (("namespace_prefix", "version"), )

    # resource_id e.g. "id": "uniprot:2019_07"
    id = models.CharField(primary_key=True,
                          max_length=200,
                          help_text=rec_help(d.RESOURCE, "id"))
    name = models.CharField(max_length=200,
                            help_text=rec_help(d.RESOURCE, "name"))
    namespace_prefix = models.CharField(max_length=200,
                                        help_text=rec_help(
                                            d.RESOURCE, "namespace_prefix"))
    url = models.URLField(max_length=200,
                          help_text=rec_help(d.RESOURCE, "url"))
    version = models.CharField(max_length=200,
                               help_text=rec_help(d.RESOURCE, "version"))
    iri_prefix = models.URLField(max_length=200,
                                 help_text=rec_help(d.RESOURCE, "iri_prefix"))
    extra_properties = JSONField(blank=True,
                                 null=True,
                                 help_text=rec_help(d.RESOURCE,
                                                    "extra_properties"))

    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    def clean(self):
        # For phenopackets compliance, we need to have a string identifier. Django does not allow compound keys, we
        # ideally want to identify resources by the pair (namespace_prefix, version). In this case, we hack this by
        # enforcing that id == (namespace_prefix, version). In the case of an unspecified version, enforce
        # id == namespace_prefix.
        if (self.version and self.id != f"{self.namespace_prefix}:{self.version}") or \
                (not self.version and self.id != self.namespace_prefix):
            raise ValidationError({
                "id": [
                    ValidationError(
                        "Resource ID must match the format 'namespace_prefix:version'"
                    )
                ],
            })

    def save(self, *args, **kwargs):
        self.clean()
        return super().save(*args, **kwargs)

    def __str__(self):
        return str(self.id)
Ejemplo n.º 19
0
class GenomicsReport(models.Model, IndexableMixin):
    """
    Genetic Analysis Summary.
    """

    id = models.CharField(primary_key=True,
                          max_length=200,
                          help_text=rec_help(d.GENOMICS_REPORT, "id"))
    code = JSONField(validators=[ontology_validator],
                     help_text=rec_help(d.GENOMICS_REPORT, "code"))
    performing_organization_name = models.CharField(
        max_length=200,
        blank=True,
        help_text=rec_help(d.GENOMICS_REPORT, "performing_organization_name"))
    issued = models.DateTimeField(default=timezone.now,
                                  help_text=rec_help(d.GENOMICS_REPORT,
                                                     "issued"))
    genetic_specimen = models.ManyToManyField(GeneticSpecimen,
                                              blank=True,
                                              help_text=rec_help(
                                                  d.GENOMICS_REPORT,
                                                  "genetic_specimen"))
    genetic_variant = models.ForeignKey(CancerGeneticVariant,
                                        blank=True,
                                        null=True,
                                        on_delete=models.SET_NULL,
                                        help_text=rec_help(
                                            d.GENOMICS_REPORT,
                                            "genetic_variant"))
    genomic_region_studied = models.ForeignKey(GenomicRegionStudied,
                                               blank=True,
                                               null=True,
                                               on_delete=models.SET_NULL,
                                               help_text=rec_help(
                                                   d.GENOMICS_REPORT,
                                                   "genomic_region_studied"))
    extra_properties = JSONField(blank=True,
                                 null=True,
                                 help_text=rec_help(d.GENOMICS_REPORT,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['id']

    def __str__(self):
        return str(self.id)
Ejemplo n.º 20
0
class TNMStaging(models.Model, IndexableMixin):
    """
    Class to describe the spread of cancer in a patient’s body.
    """

    TNM_TYPES = (('clinical', 'clinical'), ('pathologic', 'pathologic'))
    id = models.CharField(primary_key=True,
                          max_length=200,
                          help_text=rec_help(d.TNM_STAGING, "id"))
    tnm_type = models.CharField(choices=TNM_TYPES,
                                max_length=200,
                                help_text=rec_help(d.TNM_STAGING, "tnm_type"))
    stage_group = JSONField(validators=[complex_ontology_validator],
                            help_text=rec_help(d.TNM_STAGING, "stage_group"))
    primary_tumor_category = JSONField(validators=[complex_ontology_validator],
                                       help_text=rec_help(
                                           d.TNM_STAGING,
                                           "primary_tumor_category"))
    regional_nodes_category = JSONField(
        validators=[complex_ontology_validator],
        help_text=rec_help(d.TNM_STAGING, "regional_nodes_category"))
    distant_metastases_category = JSONField(
        validators=[complex_ontology_validator],
        help_text=rec_help(d.TNM_STAGING, "distant_metastases_category"))
    # TODO check if one cancer condition has many TNM Staging
    cancer_condition = models.ForeignKey(CancerCondition,
                                         on_delete=models.CASCADE,
                                         help_text=rec_help(
                                             d.TNM_STAGING,
                                             "cancer_condition"))
    extra_properties = JSONField(blank=True,
                                 null=True,
                                 help_text=rec_help(d.TNM_STAGING,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['id']

    def __str__(self):
        return str(self.id)
Ejemplo n.º 21
0
class MedicationStatement(models.Model, IndexableMixin):
    """
    Class to record the use of a medication.
    """

    id = models.CharField(primary_key=True,
                          max_length=200,
                          help_text=rec_help(d.MEDICATION_STATEMENT, "id"))
    # list http://hl7.org/fhir/us/core/STU3.1/ValueSet-us-core-medication-codes.html
    medication_code = JSONField(validators=[ontology_validator],
                                help_text=rec_help(d.MEDICATION_STATEMENT,
                                                   "medication_code"))
    termination_reason = JSONField(null=True,
                                   validators=[ontology_list_validator],
                                   help_text=rec_help(d.MEDICATION_STATEMENT,
                                                      'termination_reason'))
    treatment_intent = JSONField(blank=True,
                                 null=True,
                                 validators=[ontology_validator],
                                 help_text=rec_help(d.MEDICATION_STATEMENT,
                                                    "treatment_intent"))
    start_date = models.DateTimeField(blank=True,
                                      null=True,
                                      help_text=rec_help(
                                          d.MEDICATION_STATEMENT,
                                          "start_date"))
    end_date = models.DateTimeField(blank=True,
                                    null=True,
                                    help_text=rec_help(d.MEDICATION_STATEMENT,
                                                       "end_date"))
    extra_properties = JSONField(blank=True,
                                 null=True,
                                 help_text=rec_help(d.MEDICATION_STATEMENT,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['id']

    def __str__(self):
        return str(self.id)
Ejemplo n.º 22
0
class Resource(models.Model):
    """
    Class to represent a description of an external resource
    used for referencing an object

    FHIR: CodeSystem
    """

    # resource_id e.g. "id": "uniprot"
    id = models.CharField(primary_key=True, max_length=200, help_text=rec_help(d.RESOURCE, "id"))
    name = models.CharField(max_length=200, help_text=rec_help(d.RESOURCE, "name"))
    namespace_prefix = models.CharField(max_length=200, help_text=rec_help(d.RESOURCE, "namespace_prefix"))
    url = models.URLField(max_length=200, help_text=rec_help(d.RESOURCE, "url"))
    version = models.CharField(max_length=200, help_text=rec_help(d.RESOURCE, "version"))
    iri_prefix = models.URLField(max_length=200, help_text=rec_help(d.RESOURCE, "iri_prefix"))
    extra_properties = JSONField(blank=True, null=True, help_text=rec_help(d.RESOURCE, "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.id)
Ejemplo n.º 23
0
class Experiment(models.Model, IndexableMixin):
    """ Class to store Experiment information """

    LIBRARY_STRATEGY = (
        ('DNase-Hypersensitivity', 'DNase-Hypersensitivity'),
        ('ATAC-seq', 'ATAC-seq'),
        ('NOME-Seq', 'NOME-Seq'),
        ('Bisulfite-Seq', 'Bisulfite-Seq'),
        ('MeDIP-Seq', 'MeDIP-Seq'),
        ('MRE-Seq', 'MRE-Seq'),
        ('ChIP-Seq', 'ChIP-Seq'),
        ('RNA-Seq', 'RNA-Seq'),
        ('miRNA-Seq', 'miRNA-Seq'),
        ('WGS', 'WGS'),
    )

    MOLECULE = (
        ('total RNA', 'total RNA'),
        ('polyA RNA', 'polyA RNA'),
        ('cytoplasmic RNA', 'cytoplasmic RNA'),
        ('nuclear RNA', 'nuclear RNA'),
        ('small RNA', 'small RNA'),
        ('genomic DNA', 'genomic DNA'),
        ('protein', 'protein'),
        ('other', 'other'),
    )

    id = CharField(primary_key=True,
                   max_length=200,
                   help_text=rec_help(d.EXPERIMENT, 'id'))

    reference_registry_id = CharField(max_length=30,
                                      blank=True,
                                      null=True,
                                      help_text=rec_help(
                                          d.EXPERIMENT,
                                          'reference_registry_id'))
    qc_flags = ArrayField(CharField(max_length=100,
                                    help_text=rec_help(d.EXPERIMENT,
                                                       'qc_flags')),
                          blank=True,
                          default=list)
    experiment_type = CharField(max_length=30,
                                help_text=rec_help(d.EXPERIMENT,
                                                   'experiment_type'))
    experiment_ontology = JSONField(blank=True,
                                    default=list,
                                    validators=[ontology_list_validator],
                                    help_text=rec_help(d.EXPERIMENT,
                                                       'experiment_ontology'))
    molecule_ontology = JSONField(blank=True,
                                  default=list,
                                  validators=[ontology_list_validator],
                                  help_text=rec_help(d.EXPERIMENT,
                                                     'molecule_ontology'))
    molecule = CharField(choices=MOLECULE,
                         max_length=20,
                         blank=True,
                         null=True,
                         help_text=rec_help(d.EXPERIMENT, 'molecule'))
    library_strategy = CharField(choices=LIBRARY_STRATEGY,
                                 max_length=25,
                                 help_text=rec_help(d.EXPERIMENT,
                                                    'library_strategy'))

    other_fields = JSONField(blank=True,
                             default=dict,
                             validators=[key_value_validator],
                             help_text=rec_help(d.EXPERIMENT, 'other_fields'))

    biosample = models.ForeignKey(Biosample,
                                  on_delete=models.CASCADE,
                                  help_text=rec_help(d.EXPERIMENT,
                                                     'biosample'))
    table = models.ForeignKey("chord.Table",
                              on_delete=models.CASCADE,
                              blank=True,
                              null=True)  # TODO: Help text

    def __str__(self):
        return str(self.id)
Ejemplo n.º 24
0
class Experiment(models.Model, IndexableMixin):
    """ Class to store Experiment information """

    id = CharField(primary_key=True,
                   max_length=200,
                   help_text=rec_help(d.EXPERIMENT, "id"))
    # STUDY TYPE
    # ["Whole Genome Sequencing","Metagenomics","Transcriptome Analysis","Resequencing","Epigenetics",
    # "Synthetic Genomics","Forensic or Paleo-genomics","Gene Regulation Study","Cancer Genomics",
    # "Population Genomics","RNASeq","Pooled Clone Sequencing","Transcriptome Sequencing","Other"]
    study_type = CharField(max_length=200,
                           blank=True,
                           null=True,
                           help_text=rec_help(d.EXPERIMENT, "study_type"))
    # TYPE
    experiment_type = CharField(max_length=200,
                                help_text=rec_help(d.EXPERIMENT,
                                                   "experiment_type"))
    experiment_ontology = JSONField(blank=True,
                                    default=list,
                                    validators=[ontology_list_validator],
                                    help_text=rec_help(d.EXPERIMENT,
                                                       "experiment_ontology"))
    # MOLECULE
    molecule = CharField(max_length=200,
                         blank=True,
                         null=True,
                         help_text=rec_help(d.EXPERIMENT, "molecule"))
    molecule_ontology = JSONField(blank=True,
                                  default=list,
                                  validators=[ontology_list_validator],
                                  help_text=rec_help(d.EXPERIMENT,
                                                     "molecule_ontology"))
    # LIBRARY
    library_strategy = CharField(max_length=200,
                                 blank=True,
                                 null=True,
                                 help_text=rec_help(d.EXPERIMENT,
                                                    "library_strategy"))
    library_source = CharField(max_length=200,
                               blank=True,
                               null=True,
                               help_text=rec_help(d.EXPERIMENT,
                                                  "library_source"))
    library_selection = CharField(max_length=200,
                                  blank=True,
                                  null=True,
                                  help_text=rec_help(d.EXPERIMENT,
                                                     "library_selection"))
    library_layout = CharField(max_length=200,
                               blank=True,
                               null=True,
                               help_text=rec_help(d.EXPERIMENT,
                                                  "library_layout"))
    extraction_protocol = CharField(max_length=200,
                                    blank=True,
                                    null=True,
                                    help_text=rec_help(d.EXPERIMENT,
                                                       "extraction_protocol"))
    reference_registry_id = CharField(max_length=200,
                                      blank=True,
                                      null=True,
                                      help_text=rec_help(
                                          d.EXPERIMENT,
                                          "reference_registry_id"))
    qc_flags = ArrayField(CharField(max_length=200,
                                    help_text=rec_help(d.EXPERIMENT,
                                                       "qc_flags")),
                          blank=True,
                          default=list)
    # SAMPLE
    biosample = models.ForeignKey(Biosample,
                                  on_delete=models.CASCADE,
                                  help_text=rec_help(d.EXPERIMENT,
                                                     "biosample"))
    table = models.ForeignKey("chord.Table",
                              on_delete=models.CASCADE,
                              blank=True,
                              null=True)  # TODO: Help text
    # EXPERIMENT RESULT
    experiment_results = models.ManyToManyField("ExperimentResult",
                                                blank=True,
                                                help_text=rec_help(
                                                    d.EXPERIMENT,
                                                    "experiment_results"))
    # INTSRUMENT
    instrument = models.ForeignKey("Instrument",
                                   blank=True,
                                   null=True,
                                   on_delete=models.CASCADE,
                                   help_text=rec_help(d.EXPERIMENT,
                                                      "instrument"))
    # EXTRA
    extra_properties = JSONField(blank=True,
                                 default=dict,
                                 validators=[key_value_validator],
                                 help_text=rec_help(d.EXPERIMENT,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.id)
Ejemplo n.º 25
0
class ExperimentResult(models.Model, IndexableMixin):
    """ Class to represent information about analysis of sequencing data in a file format. """

    FILE_FORMAT = (
        ("SAM", "SAM"),
        ("BAM", "BAM"),
        ("CRAM", "CRAM"),
        ("BAI", "BAI"),
        ("CRAI", "CRAI"),
        ("VCF", "VCF"),
        ("BCF", "BCF"),
        ("GVCF", "GVCF"),
        ("BigWig", "BigWig"),
        ("BigBed", "BigBed"),
        ("FASTA", "FASTA"),
        ("FASTQ", "FASTQ"),
        ("TAB", "TAB"),
        ("SRA", "SRA"),
        ("SRF", "SRF"),
        ("SFF", "SFF"),
        ("GFF", "GFF"),
        ("TABIX", "TABIX"),
        ("UNKNOWN", "UNKNOWN"),
        ("OTHER", "OTHER"),
    )
    # TODO or Processed/Sequenced vs. Raw/Derived
    DATA_OUTPUT_TYPE = (
        ("Raw data", "Raw data"),
        ("Derived data", "Derived data"),
    )
    # Data usage
    # USAGE = (
    #     ("Visualize", "Visualize"),
    #     ("Download", "Download"),
    # )

    # TODO identifier assigned by lab (?)
    identifier = CharField(max_length=200,
                           blank=True,
                           null=True,
                           help_text=rec_help(d.EXPERIMENT_RESULT,
                                              "identifier"))
    description = CharField(max_length=500,
                            blank=True,
                            null=True,
                            help_text=rec_help(d.EXPERIMENT_RESULT,
                                               "description"))
    filename = CharField(max_length=500,
                         blank=True,
                         null=True,
                         help_text=rec_help(d.EXPERIMENT_RESULT, "filename"))
    file_format = CharField(max_length=50,
                            choices=FILE_FORMAT,
                            blank=True,
                            null=True,
                            help_text=rec_help(d.EXPERIMENT_RESULT,
                                               "file_format"))
    data_output_type = CharField(max_length=50,
                                 choices=DATA_OUTPUT_TYPE,
                                 blank=True,
                                 null=True,
                                 help_text=rec_help(d.EXPERIMENT_RESULT,
                                                    "data_output_type"))
    usage = CharField(max_length=200,
                      blank=True,
                      null=True,
                      help_text=rec_help(d.EXPERIMENT_RESULT, "usage"))
    creation_date = CharField(max_length=500,
                              blank=True,
                              null=True,
                              help_text=rec_help(d.EXPERIMENT_RESULT,
                                                 "creation_date"))
    created_by = CharField(max_length=200,
                           blank=True,
                           null=True,
                           help_text=rec_help(d.EXPERIMENT_RESULT,
                                              "created_by"))
    extra_properties = JSONField(blank=True,
                                 default=dict,
                                 validators=[key_value_validator],
                                 help_text=rec_help(d.EXPERIMENT_RESULT,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.identifier)
Ejemplo n.º 26
0
class Biosample(models.Model, IndexableMixin):
    """
    Class to describe a unit of biological material

    FHIR: Specimen
    """

    id = models.CharField(primary_key=True, max_length=200, help_text=rec_help(d.BIOSAMPLE, "id"))
    # if Individual instance is deleted Biosample instance is deleted too
    individual = models.ForeignKey(
        Individual, on_delete=models.CASCADE, blank=True, null=True, related_name="biosamples",
        help_text=rec_help(d.BIOSAMPLE, "individual_id"))
    description = models.CharField(max_length=200, blank=True, help_text=rec_help(d.BIOSAMPLE, "description"))
    sampled_tissue = JSONField(validators=[ontology_validator], help_text=rec_help(d.BIOSAMPLE, "sampled_tissue"))
    # phenotypic_features = models.ManyToManyField(PhenotypicFeature, blank=True,
    #   help_text='List of phenotypic abnormalities of the sample.')
    taxonomy = JSONField(blank=True, null=True, validators=[ontology_validator],
                         help_text=rec_help(d.BIOSAMPLE, "taxonomy"))
    # An ISO8601 string represent age
    individual_age_at_collection = JSONField(blank=True, null=True, validators=[age_or_age_range_validator],
                                             help_text=rec_help("individual_age_at_collection"))
    histological_diagnosis = JSONField(
        blank=True, null=True, validators=[ontology_validator],
        help_text=rec_help(d.BIOSAMPLE, "histological_diagnosis"))
    # TODO: Lists?
    tumor_progression = JSONField(blank=True, null=True, validators=[ontology_validator],
                                  help_text=rec_help(d.BIOSAMPLE, "tumor_progression"))
    tumor_grade = JSONField(blank=True, null=True, validators=[ontology_validator],
                            help_text=rec_help(d.BIOSAMPLE, "tumor_grade"))
    diagnostic_markers = JSONField(blank=True, null=True, validators=[ontology_list_validator],
                                   help_text=rec_help(d.BIOSAMPLE, "diagnostic_markers"))
    # CHECK! if Procedure instance is deleted Biosample instance is deleted too
    procedure = models.ForeignKey(Procedure, on_delete=models.CASCADE, help_text=rec_help(d.BIOSAMPLE, "procedure"))
    hts_files = models.ManyToManyField(
        HtsFile, blank=True, related_name='biosample_hts_files', help_text=rec_help(d.BIOSAMPLE, "hts_files"))
    variants = models.ManyToManyField(Variant, blank=True, help_text=rec_help(d.BIOSAMPLE, "variants"))
    is_control_sample = models.BooleanField(default=False, help_text=rec_help(d.BIOSAMPLE, "is_control_sample"))
    extra_properties = JSONField(blank=True, null=True, help_text=rec_help(d.BIOSAMPLE, "extra_properties"))
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.id)

    @property
    def get_sample_tissue_data(self):
        return {'reference': {
            'reference': self.sampled_tissue.get('id'),
            'display': self.sampled_tissue.get('label')
            }
        }
Ejemplo n.º 27
0
class CancerGeneticVariant(models.Model, IndexableMixin):
    """
    Class to record an alteration in DNA.
    """
    id = models.CharField(primary_key=True,
                          max_length=200,
                          help_text=rec_help(d.CANCER_GENETIC_VARIANT, "id"))
    data_value = JSONField(blank=True,
                           null=True,
                           validators=[ontology_validator],
                           help_text=rec_help(d.CANCER_GENETIC_VARIANT,
                                              "data_value"))
    method = JSONField(blank=True,
                       null=True,
                       validators=[ontology_validator],
                       help_text=rec_help(d.CANCER_GENETIC_VARIANT, "method"))
    amino_acid_change = JSONField(blank=True,
                                  null=True,
                                  validators=[ontology_validator],
                                  help_text=rec_help(d.CANCER_GENETIC_VARIANT,
                                                     "amino_acid_change"))
    amino_acid_change_type = JSONField(blank=True,
                                       null=True,
                                       validators=[ontology_validator],
                                       help_text=rec_help(
                                           d.CANCER_GENETIC_VARIANT,
                                           "amino_acid_change_type"))
    cytogenetic_location = JSONField(blank=True,
                                     null=True,
                                     help_text=rec_help(
                                         d.CANCER_GENETIC_VARIANT,
                                         "cytogenetic_location"))
    cytogenetic_nomenclature = JSONField(blank=True,
                                         null=True,
                                         validators=[ontology_validator],
                                         help_text=rec_help(
                                             d.CANCER_GENETIC_VARIANT,
                                             "cytogenetic_nomenclature"))
    gene_studied = models.ManyToManyField(Gene,
                                          blank=True,
                                          help_text=rec_help(
                                              d.CANCER_GENETIC_VARIANT,
                                              "gene_studied"))
    genomic_dna_change = JSONField(blank=True,
                                   null=True,
                                   validators=[ontology_validator],
                                   help_text=rec_help(d.CANCER_GENETIC_VARIANT,
                                                      "genomic_dna_change"))
    genomic_source_class = JSONField(blank=True,
                                     null=True,
                                     validators=[ontology_validator],
                                     help_text=rec_help(
                                         d.CANCER_GENETIC_VARIANT,
                                         "genomic_source_class"))
    variation_code = JSONField(blank=True,
                               null=True,
                               validators=[ontology_list_validator],
                               help_text=rec_help(d.CANCER_GENETIC_VARIANT,
                                                  "variation_code"))
    extra_properties = JSONField(blank=True,
                                 null=True,
                                 help_text=rec_help(d.CANCER_GENETIC_VARIANT,
                                                    "extra_properties"))
    created = models.DateTimeField(auto_now=True)
    updated = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['id']

    def __str__(self):
        return str(self.id)