# coding: utf-8

"""
    IGVF Project API

    No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)

    The version of the OpenAPI document: 73.0.0
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional
from typing_extensions import Annotated
from typing import Optional, Set
from typing_extensions import Self

class MeasurementSet(BaseModel):
    """
    Measurement set is a file set that hosts raw data files (e.g. FASTQs) resulting from sequencing of a library prepared from the nucleic acids of the sample that is the main target of the assay. For example sequencing of accessible regions in the genome, or sequencing of the transcriptome of the sample. The assay can either be bulk or single cell type. The sample specific raw sequencing results will be captured in the measurement sets. The files in the measurement sets are specific to the sample being investigated. See auxiliary sets for files that are not a direct result of sequencing the sample under investigation.
    """ # noqa: E501
    control_file_sets: Optional[List[StrictStr]] = Field(default=None, description="File sets that can serve as scientific controls for this file set.")
    release_timestamp: Optional[StrictStr] = Field(default=None, description="The date the object was released.")
    publications: Optional[List[StrictStr]] = Field(default=None, description="The publications associated with this object.")
    documents: Optional[List[StrictStr]] = Field(default=None, description="Documents that provide additional information (not data file).")
    lab: Optional[StrictStr] = Field(default=None, description="Lab associated with the submission.")
    award: Optional[StrictStr] = Field(default=None, description="Grant associated with the submission.")
    accession: Optional[StrictStr] = Field(default=None, description="A unique identifier to be used to reference the object prefixed with IGVF.")
    alternate_accessions: Optional[List[StrictStr]] = Field(default=None, description="Accessions previously assigned to objects that have been merged with this object.")
    collections: Optional[List[StrictStr]] = Field(default=None, description="Some samples are part of particular data collections.")
    status: Optional[StrictStr] = Field(default=None, description="The status of the metadata object.")
    revoke_detail: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="Explanation of why an object was transitioned to the revoked status.")
    schema_version: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="The version of the JSON schema that the server uses to validate the object.")
    uuid: Optional[StrictStr] = Field(default=None, description="The unique identifier associated with every object.")
    notes: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="DACC internal notes.")
    aliases: Optional[List[Annotated[str, Field(strict=True)]]] = Field(default=None, description="Lab specific identifiers to reference an object.")
    creation_timestamp: Optional[StrictStr] = Field(default=None, description="The date the object was created.")
    submitted_by: Optional[StrictStr] = Field(default=None, description="The user who submitted the object.")
    submitter_comment: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="Additional information specified by the submitter to be displayed as a comment on the portal.")
    description: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="A plain text description of the object.")
    dbxrefs: Optional[List[Annotated[str, Field(strict=True)]]] = Field(default=None, description="Identifiers from external resources that may have 1-to-1 or 1-to-many relationships with IGVF file sets.")
    control_type: Optional[StrictStr] = Field(default=None, description="The type of control this file set represents.")
    samples: Optional[List[StrictStr]] = Field(default=None, description="The sample(s) associated with this file set.")
    donors: Optional[List[StrictStr]] = Field(default=None, description="The donors of the samples associated with this measurement set.")
    file_set_type: Optional[StrictStr] = Field(default=None, description="The category that best describes this measurement set.")
    assay_term: Optional[StrictStr] = Field(default=None, description="The assay used to produce data in this measurement set.")
    protocols: Optional[List[Annotated[str, Field(strict=True)]]] = Field(default=None, description="Links to the protocol(s) for conducting the assay on Protocols.io.")
    preferred_assay_title: Optional[StrictStr] = Field(default=None, description="The custom lab preferred label for the experiment performed in this measurement set.")
    multiome_size: Optional[Annotated[int, Field(strict=True, ge=2)]] = Field(default=None, description="The number of datasets included in the multiome experiment this measurement set is a part of.")
    sequencing_library_types: Optional[List[StrictStr]] = Field(default=None, description="Description of the libraries sequenced in this measurement set.")
    strand_specificity: Optional[StrictStr] = Field(default=None, description="The strand-specificity of the sequencing results within Perturb-seq, scCRISPR screen, TAP-seq, and CERES-seq assays.")
    auxiliary_sets: Optional[List[StrictStr]] = Field(default=None, description="The auxiliary sets of files produced alongside raw data from this measurement set.")
    external_image_url: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="Links to the external site where images produced by this measurement are stored.")
    targeted_genes: Optional[List[StrictStr]] = Field(default=None, description="A list of genes targeted in this assay. For example, TF ChIP-seq attempts to identify binding sites of a protein encoded by a specific gene. In CRISPR FlowFISH, the modified samples are sorted based on expression of a specific gene. This property differs from small_scale_gene_list in Construct Library Set, which describes genes targeted by the content integrated in the constructs (such as guide RNAs.)")
    functional_assay_mechanisms: Optional[List[StrictStr]] = Field(default=None, description="The biological processes measured by this functional assay. For example, a VAMP-seq (MultiSTEP) assay measures the effects of variants on protein carboxylation and secretion processes.")
    onlist_method: Optional[StrictStr] = Field(default=None, description="The method by which the onlist files will be combined by the seqspec onlist tool to generate the final barcode inclusion list for the single cell uniform pipeline.")
    onlist_files: Optional[List[StrictStr]] = Field(default=None, description="The barcode region onlist files listed in associated seqspec yaml files.")
    id: Optional[StrictStr] = Field(default=None, alias="@id")
    type: Optional[List[StrictStr]] = Field(default=None, alias="@type")
    summary: Optional[StrictStr] = None
    files: Optional[List[StrictStr]] = Field(default=None, description="The files associated with this file set.")
    control_for: Optional[List[StrictStr]] = Field(default=None, description="The file sets for which this file set is a control.")
    submitted_files_timestamp: Optional[StrictStr] = Field(default=None, description="The timestamp the first file object in the file_set or associated auxiliary sets was created.")
    input_for: Optional[List[StrictStr]] = Field(default=None, description="The file sets that use this file set as an input.")
    construct_library_sets: Optional[List[StrictStr]] = Field(default=None, description="The construct library sets associated with the samples of this file set.")
    data_use_limitation_summaries: Optional[List[StrictStr]] = Field(default=None, description="The data use limitation summaries of institutional certificates covering the sample associated with this file set which are signed by the same lab (or their partner lab) as the lab that submitted this file set.")
    controlled_access: Optional[StrictBool] = Field(default=None, description="The controlled access of the institutional certificates covering the sample associated with this file set which are signed by the same lab (or their partner lab) as the lab that submitted this file set.")
    related_multiome_datasets: Optional[List[StrictStr]] = Field(default=None, description="Related datasets included in the multiome experiment this measurement set is a part of.")
    externally_hosted: Optional[StrictBool] = None
    __properties: ClassVar[List[str]] = ["control_file_sets", "release_timestamp", "publications", "documents", "lab", "award", "accession", "alternate_accessions", "collections", "status", "revoke_detail", "schema_version", "uuid", "notes", "aliases", "creation_timestamp", "submitted_by", "submitter_comment", "description", "dbxrefs", "control_type", "samples", "donors", "file_set_type", "assay_term", "protocols", "preferred_assay_title", "multiome_size", "sequencing_library_types", "strand_specificity", "auxiliary_sets", "external_image_url", "targeted_genes", "functional_assay_mechanisms", "onlist_method", "onlist_files", "@id", "@type", "summary", "files", "control_for", "submitted_files_timestamp", "input_for", "construct_library_sets", "data_use_limitation_summaries", "controlled_access", "related_multiome_datasets", "externally_hosted"]

    @field_validator('collections')
    def collections_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        for i in value:
            if i not in set(['ACMG73', 'ClinGen', 'ENCODE', 'GREGoR', 'IGVF_catalog_beta_v0.1', 'IGVF_catalog_beta_v0.2', 'IGVF_catalog_beta_v0.3', 'IGVF_catalog_beta_v0.4', 'IGVF_catalog_beta_v0.5', 'IGVF phase 1', 'MaveDB', 'Morphic', 'MPRAbase', 'StanfordFCC', 'TOPMED Freeze 8', 'VarChAMP', 'Vista', 'Williams Syndrome Research']):
                raise ValueError("each list item must be one of ('ACMG73', 'ClinGen', 'ENCODE', 'GREGoR', 'IGVF_catalog_beta_v0.1', 'IGVF_catalog_beta_v0.2', 'IGVF_catalog_beta_v0.3', 'IGVF_catalog_beta_v0.4', 'IGVF_catalog_beta_v0.5', 'IGVF phase 1', 'MaveDB', 'Morphic', 'MPRAbase', 'StanfordFCC', 'TOPMED Freeze 8', 'VarChAMP', 'Vista', 'Williams Syndrome Research')")
        return value

    @field_validator('status')
    def status_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['in progress', 'preview', 'released', 'deleted', 'replaced', 'revoked', 'archived']):
            raise ValueError("must be one of enum values ('in progress', 'preview', 'released', 'deleted', 'replaced', 'revoked', 'archived')")
        return value

    @field_validator('revoke_detail')
    def revoke_detail_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^(\S+(\s|\S)*\S+|\S)$", value):
            raise ValueError(r"must validate the regular expression /^(\S+(\s|\S)*\S+|\S)$/")
        return value

    @field_validator('schema_version')
    def schema_version_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^\d+(\.\d+)*$", value):
            raise ValueError(r"must validate the regular expression /^\d+(\.\d+)*$/")
        return value

    @field_validator('notes')
    def notes_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^(\S+(\s|\S)*\S+|\S)$", value):
            raise ValueError(r"must validate the regular expression /^(\S+(\s|\S)*\S+|\S)$/")
        return value

    @field_validator('submitter_comment')
    def submitter_comment_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^(\S+(\s|\S)*\S+|\S)$", value):
            raise ValueError(r"must validate the regular expression /^(\S+(\s|\S)*\S+|\S)$/")
        return value

    @field_validator('description')
    def description_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^(\S+(\s|\S)*\S+|\S)$", value):
            raise ValueError(r"must validate the regular expression /^(\S+(\s|\S)*\S+|\S)$/")
        return value

    @field_validator('control_type')
    def control_type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['control transduction', 'low FACS signal', 'non-targeting', 'pre-selection', 'unsorted FACS input', 'untransfected', 'untreated']):
            raise ValueError("must be one of enum values ('control transduction', 'low FACS signal', 'non-targeting', 'pre-selection', 'unsorted FACS input', 'untransfected', 'untreated')")
        return value

    @field_validator('file_set_type')
    def file_set_type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['experimental data']):
            raise ValueError("must be one of enum values ('experimental data')")
        return value

    @field_validator('preferred_assay_title')
    def preferred_assay_title_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['RNA-seq', 'scRNA-seq', 'snRNA-seq', 'scNT-seq', 'scNT-seq2', 'Parse SPLiT-seq', 'ATAC-seq', 'varACCESS', 'ACCESS-ATAC', 'scATAC-seq', 'scACCESS-ATAC', 'snATAC-seq', '10x multiome with scMito-seq', 'DOGMA-seq', '10x multiome', '10x multiome with MULTI-seq', '10X ATAC with Scale pre-indexing', '10X RNA with Scale pre-indexing', 'MULTI-seq', 'SHARE-seq', 'Histone ChIP-seq', 'TF ChIP-seq', 'MPRA', 'MPRA (scQer)', 'electroporated MPRA', 'AAV-MPRA', 'lentiMPRA', 'STARR-seq', 'SUPERSTARR', 'Cell painting', 'Variant painting via fluorescence', 'Variant painting via immunostaining', 'smFISH', 'MERFISH', 'Proliferation CRISPR screen', 'Migration CRISPR screen', 'CRISPR FlowFISH screen', 'CRISPR FACS screen', 'CRISPR MACS screen', 'CRISPR mCherry screen', 'HCR-FlowFISH screen', 'scCRISPR screen', 'Perturb-seq', 'CERES-seq', 'TAP-seq', 'Variant-EFFECTS', 'SGE', 'MIAA', 'snmC-Seq2', 'snMCT-seq', 'snM3C-seq', 'mN2H', 'semi-qY2H', 'Y2H', 'yN2H', 'VAMP-seq', 'VAMP-seq (MultiSTEP)', 'Hi-C', 'HiCAR', 'Spatial transcriptomics', 'HT-recruit', 'ONT dRNA', 'ONT Fiber-seq', 'ONT direct WGS', 'WGS']):
            raise ValueError("must be one of enum values ('RNA-seq', 'scRNA-seq', 'snRNA-seq', 'scNT-seq', 'scNT-seq2', 'Parse SPLiT-seq', 'ATAC-seq', 'varACCESS', 'ACCESS-ATAC', 'scATAC-seq', 'scACCESS-ATAC', 'snATAC-seq', '10x multiome with scMito-seq', 'DOGMA-seq', '10x multiome', '10x multiome with MULTI-seq', '10X ATAC with Scale pre-indexing', '10X RNA with Scale pre-indexing', 'MULTI-seq', 'SHARE-seq', 'Histone ChIP-seq', 'TF ChIP-seq', 'MPRA', 'MPRA (scQer)', 'electroporated MPRA', 'AAV-MPRA', 'lentiMPRA', 'STARR-seq', 'SUPERSTARR', 'Cell painting', 'Variant painting via fluorescence', 'Variant painting via immunostaining', 'smFISH', 'MERFISH', 'Proliferation CRISPR screen', 'Migration CRISPR screen', 'CRISPR FlowFISH screen', 'CRISPR FACS screen', 'CRISPR MACS screen', 'CRISPR mCherry screen', 'HCR-FlowFISH screen', 'scCRISPR screen', 'Perturb-seq', 'CERES-seq', 'TAP-seq', 'Variant-EFFECTS', 'SGE', 'MIAA', 'snmC-Seq2', 'snMCT-seq', 'snM3C-seq', 'mN2H', 'semi-qY2H', 'Y2H', 'yN2H', 'VAMP-seq', 'VAMP-seq (MultiSTEP)', 'Hi-C', 'HiCAR', 'Spatial transcriptomics', 'HT-recruit', 'ONT dRNA', 'ONT Fiber-seq', 'ONT direct WGS', 'WGS')")
        return value

    @field_validator('sequencing_library_types')
    def sequencing_library_types_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        for i in value:
            if i not in set(['direct RNA', 'exome capture', 'mRNA enriched', 'rRNA depleted', 'polyA depleted', 'polyA enriched']):
                raise ValueError("each list item must be one of ('direct RNA', 'exome capture', 'mRNA enriched', 'rRNA depleted', 'polyA depleted', 'polyA enriched')")
        return value

    @field_validator('strand_specificity')
    def strand_specificity_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['5 prime to 3 prime', '3 prime to 5 prime', 'unstranded']):
            raise ValueError("must be one of enum values ('5 prime to 3 prime', '3 prime to 5 prime', 'unstranded')")
        return value

    @field_validator('external_image_url')
    def external_image_url_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^https:\/\/cellpainting-gallery\.s3\.amazonaws\.com(\S+)$", value):
            raise ValueError(r"must validate the regular expression /^https:\/\/cellpainting-gallery\.s3\.amazonaws\.com(\S+)$/")
        return value

    @field_validator('onlist_method')
    def onlist_method_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['no combination', 'product', 'multi']):
            raise ValueError("must be one of enum values ('no combination', 'product', 'multi')")
        return value

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of MeasurementSet from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of MeasurementSet from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "control_file_sets": obj.get("control_file_sets"),
            "release_timestamp": obj.get("release_timestamp"),
            "publications": obj.get("publications"),
            "documents": obj.get("documents"),
            "lab": obj.get("lab"),
            "award": obj.get("award"),
            "accession": obj.get("accession"),
            "alternate_accessions": obj.get("alternate_accessions"),
            "collections": obj.get("collections"),
            "status": obj.get("status"),
            "revoke_detail": obj.get("revoke_detail"),
            "schema_version": obj.get("schema_version"),
            "uuid": obj.get("uuid"),
            "notes": obj.get("notes"),
            "aliases": obj.get("aliases"),
            "creation_timestamp": obj.get("creation_timestamp"),
            "submitted_by": obj.get("submitted_by"),
            "submitter_comment": obj.get("submitter_comment"),
            "description": obj.get("description"),
            "dbxrefs": obj.get("dbxrefs"),
            "control_type": obj.get("control_type"),
            "samples": obj.get("samples"),
            "donors": obj.get("donors"),
            "file_set_type": obj.get("file_set_type"),
            "assay_term": obj.get("assay_term"),
            "protocols": obj.get("protocols"),
            "preferred_assay_title": obj.get("preferred_assay_title"),
            "multiome_size": obj.get("multiome_size"),
            "sequencing_library_types": obj.get("sequencing_library_types"),
            "strand_specificity": obj.get("strand_specificity"),
            "auxiliary_sets": obj.get("auxiliary_sets"),
            "external_image_url": obj.get("external_image_url"),
            "targeted_genes": obj.get("targeted_genes"),
            "functional_assay_mechanisms": obj.get("functional_assay_mechanisms"),
            "onlist_method": obj.get("onlist_method"),
            "onlist_files": obj.get("onlist_files"),
            "@id": obj.get("@id"),
            "@type": obj.get("@type"),
            "summary": obj.get("summary"),
            "files": obj.get("files"),
            "control_for": obj.get("control_for"),
            "submitted_files_timestamp": obj.get("submitted_files_timestamp"),
            "input_for": obj.get("input_for"),
            "construct_library_sets": obj.get("construct_library_sets"),
            "data_use_limitation_summaries": obj.get("data_use_limitation_summaries"),
            "controlled_access": obj.get("controlled_access"),
            "related_multiome_datasets": obj.get("related_multiome_datasets"),
            "externally_hosted": obj.get("externally_hosted")
        })
        return _obj


