Ejemplo n.º 1
0
def render_signature(request):

    # grab the selections from session data

    # targets set #1
    ss_pos = request.session.get('targets_pos', False)
    # targets set #2
    ss_neg = request.session.get('selection', False)

    # setup signature
    signature = SequenceSignature()
    signature.setup_alignments_from_selection(ss_pos, ss_neg)
    # calculate the signature
    signature.calculate_signature()

    # calculate the Z-scores signatures
    signature.calculate_zscales_signature()

    # save for later
    # signature_map = feats_delta.argmax(axis=0)
    request.session['signature'] = signature.prepare_session_data()
    request.session.modified = True

    return_html = render(request, 'sequence_signature.html',
                         signature.prepare_display_data())

    return return_html
Ejemplo n.º 2
0
def render_signature(request):

    # grab the selections from session data

    # targets set #1
    ss_pos = request.session.get('targets_pos', False)
    # targets set #2
    ss_neg = request.session.get('selection', False)

    # setup signature
    signature = SequenceSignature()
    signature.setup_alignments_from_selection(ss_pos, ss_neg)
    # calculate the signature
    signature.calculate_signature()

    # calculate the Z-scores signatures
    signature.calculate_zscales_signature()

    # save for later
    # signature_map = feats_delta.argmax(axis=0)
    request.session['signature'] = signature.prepare_session_data()
    request.session.modified = True

    return_html = render(
        request,
        'sequence_signature.html',
        signature.prepare_display_data()
        )

    return return_html
Ejemplo n.º 3
0
def IMSequenceSignature(request):
    '''Accept set of proteins + generic numbers and calculate the signature for those'''
    t1 = time.time()

    pos_set_in = get_entry_names(request)
    ignore_in_alignment = get_ignore_info(request)
    segments = get_protein_segments(request)

    # get pos objects
    pos_set = Protein.objects.filter(entry_name__in=pos_set_in).select_related(
        'residue_numbering_scheme', 'species')

    # Calculate Sequence Signature
    signature = SequenceSignature()

    signature.setup_alignments_signprot(
        segments, pos_set, ignore_in_alignment=ignore_in_alignment)
    signature.calculate_signature_onesided()
    # preprocess data for return
    signature_data = signature.prepare_display_data_onesided()

    # FEATURES AND REGIONS
    feats = [feature for feature in signature_data['a_pos'].features_combo]

    # GET GENERIC NUMBERS
    generic_numbers = get_generic_numbers(signature_data)

    # FEATURE FREQUENCIES
    signature_features = get_signature_features(signature_data,
                                                generic_numbers, feats)
    grouped_features = group_signature_features(signature_features)

    # # FEATURE CONSENSUS
    # generic_numbers_flat = list(chain.from_iterable(generic_numbers))
    # sigcons = get_signature_consensus(signature_data, generic_numbers_flat)

    # rec_class = pos_set[0].get_protein_class()

    # dump = {
    #     'rec_class': rec_class,
    #     'signature': signature,
    #     'consensus': signature_data,
    #     }
    # with open('signprot/notebooks/interface_pickles/{}.p'.format(rec_class), 'wb+') as out_file:
    #     pickle.dump(dump, out_file)

    # pass back to front
    res = {
        # 'cons': sigcons,
        'feat_ungrouped': signature_features,
        'feat': grouped_features,
    }

    request.session['signature'] = signature.prepare_session_data()
    request.session.modified = True

    t2 = time.time()
    print('Runtime: {}'.format((t2 - t1) * 1000.0))

    return JsonResponse(res, safe=False)
Ejemplo n.º 4
0
def render_alignment_excel(request):

    # Grab all targets
    targets = request.session.get('selection', False)

    # create placeholder seq signature
    signature = SequenceSignature()
    signature.setup_alignments_from_selection(targets, targets)

    # calculate the signture
    signature.calculate_signature()
    signature.calculate_zscales_signature()

    outstream = BytesIO()
    wb = xlsxwriter.Workbook(outstream, {'in_memory': True})

    # Sequence alignment of targets
    signature.prepare_excel_worksheet(wb, 'Alignment', 'positive', 'alignment')

    # Residue properties stats
    signature.prepare_excel_worksheet(wb, 'Property_conservation', 'positive',
                                      'features')
    # Z-scales
    signature.zscales_excel(wb, "Z-scales", 'positive')
    wb.close()
    outstream.seek(0)
    response = HttpResponse(
        outstream.read(),
        content_type=
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
    response[
        'Content-Disposition'] = "attachment; filename=gpcrdb_alignment.xlsx"

    return response
Ejemplo n.º 5
0
    def get_context_data (self, **kwargs):
        # setup caches
        cache_name = "RFB"
        rfb_panel = cache.get(cache_name)
#        rfb_panel = None
        if rfb_panel == None:
            rfb_panel = {}

            # Signatures
            rfb_panel["signatures"] = {}

            # Grab relevant segments
            segments = list(ProteinSegment.objects.filter(proteinfamily='GPCR'))

            # Grab High/Low CA GPCRs (class A)
            high_ca = ["5ht2c_human", "acm4_human", "drd1_human", "fpr1_human", "ghsr_human", "cnr1_human", "aa1r_human", "gpr6_human", "gpr17_human", "gpr87_human"]
            low_ca = ["agtr1_human", "ednrb_human", "gnrhr_human", "acthr_human", "v2r_human", "gp141_human", "gp182_human"]

            # Signature High vs Low CA
            high_ca_gpcrs = Protein.objects.filter(entry_name__in=high_ca).select_related('residue_numbering_scheme', 'species')
            low_ca_gpcrs = Protein.objects.filter(entry_name__in=low_ca).select_related('residue_numbering_scheme', 'species')

            signature = SequenceSignature()
            signature.setup_alignments(segments, high_ca_gpcrs, low_ca_gpcrs)
            signature.calculate_signature()
            rfb_panel["signatures"]["cah"] = signature.signature
            rfb_panel["signatures"]["cah_positions"] = signature.common_gn

            signature = SequenceSignature()
            signature.setup_alignments(segments, low_ca_gpcrs, high_ca_gpcrs)
            signature.calculate_signature()
            rfb_panel["signatures"]["cal"] = signature.signature
            rfb_panel["signatures"]["cal_positions"] = signature.common_gn

            # Grab Gi/Gs/Gq/GI12 GPCR sets (class A)
            human_class_a_gpcrs = Protein.objects.filter(species_id=1, sequence_type_id=1, family__slug__startswith='001').distinct().prefetch_related('proteingprotein_set', 'residue_numbering_scheme')
            gs  = list(human_class_a_gpcrs.filter(proteingprotein__slug="100_001_001"))
            gio = list(human_class_a_gpcrs.filter(proteingprotein__slug="100_001_002"))
            gq  = list(human_class_a_gpcrs.filter(proteingprotein__slug="100_001_003"))
            g12 = list(human_class_a_gpcrs.filter(proteingprotein__slug="100_001_004"))
            all = set(gs + gio + gq + g12)

            # Create sequence signatures for the G-protein sets
            for gprotein in ["gs", "gio", "gq", "g12"]:
#                print("Processing " + gprotein)
                # Signature receptors specific for a G-protein vs all others
                signature = SequenceSignature()
                signature.setup_alignments(segments, locals()[gprotein], all.difference(locals()[gprotein]))
                signature.calculate_signature()
                rfb_panel["signatures"][gprotein] = signature.signature
                rfb_panel["signatures"][gprotein + "_positions"] = signature.common_gn

            # Add class A alignment features
            signature = SequenceSignature()
            signature.setup_alignments(segments, human_class_a_gpcrs, [list(human_class_a_gpcrs)[0]])
            signature.calculate_signature()
            rfb_panel["class_a_positions"] = signature.common_gn
            rfb_panel["class_a_aa"] = signature.aln_pos.consensus
            rfb_panel["class_a_prop"] = signature.features_consensus_pos

            # Add X-ray ligand contacts
            # Optionally include the curation with the following filter: structure_ligand_pair__annotated=True
            class_a_interactions = ResidueFragmentInteraction.objects.filter(
                structure_ligand_pair__structure__protein_conformation__protein__family__slug__startswith="001").exclude(interaction_type__type='hidden')\
                .values("rotamer__residue__generic_number__label").annotate(unique_receptors=Count("rotamer__residue__protein_conformation__protein__family_id", distinct=True))

            rfb_panel["ligand_binding"] = {entry["rotamer__residue__generic_number__label"] : entry["unique_receptors"] for entry in list(class_a_interactions)}

            # Add genetic variations
            all_nat_muts = NaturalMutations.objects.filter(protein__family__slug__startswith="001").values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["natural_mutations"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_nat_muts)}

            # Add PTMs
            all_ptms = PTMs.objects.filter(protein__family__slug__startswith="001").values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["ptms"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_ptms)}
            all_phos = PTMs.objects.filter(protein__family__slug__startswith="001").filter(modification="Phosphorylation").values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["phos"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_phos)}
            all_palm = PTMs.objects.filter(protein__family__slug__startswith="001").filter(modification="Palmitoylation").values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["palm"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_palm)}
            all_glyc = PTMs.objects.filter(protein__family__slug__startswith="001").filter(modification__endswith="Glycosylation").values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["glyc"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_glyc)}
            all_ubiq = PTMs.objects.filter(protein__family__slug__startswith="001").filter(modification="Ubiquitylation").values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["ubiq"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_ubiq)}

            # Thermostabilizing
            all_thermo = ConstructMutation.objects.filter(construct__protein__family__slug__startswith="001", effects__slug='thermostabilising')\
                        .values("residue__generic_number__label").annotate(unique_receptors=Count("construct__protein__family_id", distinct=True))
            rfb_panel["thermo_mutations"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_thermo)}


            # Class A ligand mutations >5 fold effect - count unique receptors
            all_ligand_mutations = MutationExperiment.objects.filter(Q(foldchange__gte = 5) | Q(foldchange__lte = -5), protein__family__slug__startswith="001")\
                            .values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["ligand_mutations"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_ligand_mutations)}

            # Class A mutations with >30% increase/decrease basal activity
            all_basal_mutations = MutationExperiment.objects.filter(Q(opt_basal_activity__gte = 130) | Q(opt_basal_activity__lte = 70), protein__family__slug__startswith="001")\
                            .values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["basal_mutations"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_basal_mutations)}

            # Intrasegment contacts
            all_contacts = InteractingResiduePair.objects.filter(~Q(res1__protein_segment_id = F('res2__protein_segment_id')), referenced_structure__protein_conformation__protein__family__slug__startswith="001")\
                            .values("res1__generic_number__label").annotate(unique_receptors=Count("referenced_structure__protein_conformation__protein__family_id", distinct=True))
            rfb_panel["intrasegment_contacts"] = {entry["res1__generic_number__label"] : entry["unique_receptors"] for entry in list(all_contacts)}


            # Active/Inactive contacts
            all_active_contacts = InteractingResiduePair.objects.filter(~Q(res2__generic_number__label = None), ~Q(res1__generic_number__label = None),\
                    referenced_structure__state__slug = "active", referenced_structure__protein_conformation__protein__family__slug__startswith="001")\
                    .values("res1__generic_number__label", "res2__generic_number__label")

            # OPTIMIZE
            active_contacts = {}
            for entry in list(all_active_contacts):
                if entry["res1__generic_number__label"] not in active_contacts:
                    active_contacts[entry["res1__generic_number__label"]] = set()
                active_contacts[entry["res1__generic_number__label"]].update([entry["res2__generic_number__label"]])
            rfb_panel["active_contacts"] = active_contacts

            all_inactive_contacts = InteractingResiduePair.objects.filter(~Q(res2__generic_number__label = None), ~Q(res1__generic_number__label = None),\
                    referenced_structure__state__slug = "inactive", referenced_structure__protein_conformation__protein__family__slug__startswith="001")\
                    .values("res1__generic_number__label", "res2__generic_number__label")

            # OPTIMIZE
            inactive_contacts = {}
            for entry in list(all_inactive_contacts):
                if entry["res1__generic_number__label"] not in inactive_contacts:
                        inactive_contacts[entry["res1__generic_number__label"]] = set()
                inactive_contacts[entry["res1__generic_number__label"]].update([entry["res2__generic_number__label"]])
            rfb_panel["inactive_contacts"] = inactive_contacts

            cache.set(cache_name, rfb_panel, 3600*24*7) # cache a week

        # Other rules
#        structural_rule_tree = create_structural_rule_trees(STRUCTURAL_RULES)

        ######## CREATE REFERENCE sets (or use structural rules)

        ## MICROSWITCHES
        ms_labels = [residue.label for residue in ResiduePositionSet.objects.get(name="State (micro-)switches").residue_position.all()]

        ## SODIUM POCKET
        sp_labels = [residue.label for residue in ResiduePositionSet.objects.get(name="Sodium ion pocket").residue_position.all()]

        ## ROTAMER SWITCHES
        rotamer_labels = []
        for entry in STRUCTURAL_SWITCHES["A"]:
            if entry["Rotamer Switch"] != "-":
                rotamer_labels.append(entry["AA1 Pos"])
                rotamer_labels.append(entry["AA2 Pos"])


        ## G PROTEIN INTERACTION POSITIONS
#        gprotein_labels = [residue.label for residue in ResiduePositionSet.objects.get(name="Signalling protein pocket").residue_position.all()]
        # Class A G-protein X-ray contacts
        # TODO: replace with automatically generated sets from X-rays stored in database
        gprotein_labels = {"1x60": {"001_006_001_001", " 001_006_001_002"},
                            "12x48": {"001_001_003_008", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "12x49": {"001_001_003_008", " 001_006_001_002"},
                            "12x51": {"001_006_001_002"},
                            "2x37": {"001_006_001_001"},
                            "2x39": {"001_002_022_003"},
                            "2x40": {"001_006_001_001"},
                            "3x49": {"001_001_003_008", " 001_002_022_003"},
                            "3x50": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "3x53": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002"},
                            "3x54": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "3x55": {"001_001_003_008", " 001_006_001_002"},
                            "3x56": {"001_006_001_002", " 001_009_001_001"},
                            "34x50": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002"},
                            "34x51": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002"},
                            "34x52": {"001_001_003_008", " 001_002_022_003", " 001_006_001_002"},
                            "34x53": {"001_001_003_008", " 001_006_001_002"},
                            "34x54": {"001_001_003_008", " 001_002_022_003", " 001_006_001_002"},
                            "34x55": {"001_001_003_008", " 001_002_022_003", " 001_006_001_002", " 001_009_001_001"},
                            "34x57": {"001_001_001_002", " 001_002_022_003"},
                            "4x40": {"001_002_022_003"},
                            "5x61": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002"},
                            "5x64": {"001_001_003_008", " 001_002_022_003", " 001_006_001_002"},
                            "5x65": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002"},
                            "5x67": {"001_001_003_008"},
                            "5x68": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002"},
                            "5x69": {"001_001_001_002", " 001_001_003_008", " 001_006_001_001", " 001_006_001_002"},
                            "5x71": {"001_001_003_008", " 001_006_001_001", " 001_006_001_002"},
                            "5x72": {"001_001_003_008", " 001_006_001_002", " 001_009_001_001"},
                            "5x74": {"001_001_003_008"},
                            "6x23": {"001_002_022_003"},
                            "6x24": {"001_009_001_001"},
                            "6x25": {"001_002_022_003", " 001_006_001_001", " 001_009_001_001"},
                            "6x26": {"001_002_022_003", " 001_009_001_001"},
                            "6x28": {"001_009_001_001"},
                            "6x29": {"001_001_001_002", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "6x32": {"001_001_001_002", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "6x33": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "6x36": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_002", " 001_009_001_001"},
                            "6x37": {"001_001_001_002", " 001_001_003_008", " 001_006_001_001", " 001_006_001_002"},
                            "7x56": {"001_001_001_002", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "8x47": {"001_001_001_002", " 001_002_022_003", " 001_006_001_001", " 001_009_001_001"},
                            "8x48": {"001_002_022_003", " 001_006_001_002", " 001_009_001_001"},
                            "8x49": {"001_006_001_001", " 001_006_001_002"},
                            "8x51": {"001_006_001_002"},
                            "8x56": {"001_006_001_001"}}

        # TODO: replace with automatically generated sets from X-rays stored in database
        # Class A Arrestin X-ray contacts
        arrestin_labels = {"12x49": {"001_009_001_001"},
                            "2x37": {"001_009_001_001"},
                            "2x38": {"001_009_001_001"},
                            "2x39": {"001_009_001_001"},
                            "2x40": {"001_009_001_001"},
                            "2x43": {"001_009_001_001"},
                            "3x50": {"001_009_001_001"},
                            "3x54": {"001_009_001_001"},
                            "3x55": {"001_009_001_001"},
                            "3x56": {"001_009_001_001"},
                            "34x50": {"001_009_001_001"},
                            "34x51": {"001_009_001_001"},
                            "34x53": {"001_009_001_001"},
                            "34x54": {"001_009_001_001"},
                            "34x55": {"001_009_001_001"},
                            "34x56": {"001_009_001_001"},
                            "4x38": {"001_009_001_001"},
                            "5x61": {"001_009_001_001"},
                            "5x64": {"001_009_001_001"},
                            "5x68": {"001_009_001_001"},
                            "5x69": {"001_009_001_001"},
                            "5x71": {"001_009_001_001"},
                            "5x72": {"001_009_001_001"},
                            "6x24": {"001_009_001_001"},
                            "6x25": {"001_009_001_001"},
                            "6x26": {"001_009_001_001"},
                            "6x28": {"001_009_001_001"},
                            "6x29": {"001_009_001_001"},
                            "6x32": {"001_009_001_001"},
                            "6x33": {"001_009_001_001"},
                            "6x36": {"001_009_001_001"},
                            "6x37": {"001_009_001_001"},
                            "6x40": {"001_009_001_001"},
                            "8x47": {"001_009_001_001"},
                            "8x48": {"001_009_001_001"},
                            "8x49": {"001_009_001_001"},
                            "8x50": {"001_009_001_001"}}

        # Positions in center of membrane selected using 4BVN (ADRB1) together with OPM membrane positioning
        # Reference: ['1x44', '2x52', '3x36', '4x54', '5x46', '6x48', '7x43']
        mid_membrane_classA = {'TM1': 44,'TM2': 52,'TM3': 36,'TM4': 54,'TM5': 46, 'TM6': 48, 'TM7': 43}

        # NOTE: We might need to split this into B1 and B2 when adhesion X-rays are published
        # Positions in center of membrane selected using 5XEZ (GCGR) together with OPM membrane positioning
        # Reference: ['1x51', '2x58', '3x41', '4x54', '5x45', '6x49', '7x50']
        mid_membrane_classB = {'TM1': 51,'TM2': 58,'TM3': 41,'TM4': 54,'TM5': 45, 'TM6': 49, 'TM7': 50}

        # Positions in center of membrane selected using 4OR2 (mGLUR1) together with OPM membrane positioning
        # Reference: ['1x49', '2x48', '3x40', '4x41', '5x48', '6x48', '7.39x40']
        mid_membrane_classC = {'TM1': 49,'TM2': 48,'TM3': 40,'TM4': 41,'TM5': 48, 'TM6': 48, 'TM7': 40}

        # Positions in center of membrane selected using 6BD4 (FZD4) together with OPM membrane positioning
        # Reference: ['1x43', '2x53', '3x38', '4x53', '5x53', '6x43', '7x47']
        mid_membrane_classF = {'TM1': 43,'TM2': 53,'TM3': 38,'TM4': 53,'TM5': 53, 'TM6': 43, 'TM7': 47}

        # Positions within membrane layer selected using 4BVN together with OPM membrane positioning
        core_membrane_classA = {'TM1': [33, 55],'TM2': [42,65],'TM3': [23,47],'TM4': [43,64],'TM5': [36,59], 'TM6': [37,60], 'TM7': [32,54]}
        # TODO: other classes
        core_membrane_classB = {'TM1': [33, 55],'TM2': [42,65],'TM3': [23,47],'TM4': [43,64],'TM5': [36,59], 'TM6': [37,60], 'TM7': [32,54]}
        core_membrane_classC = {'TM1': [33, 55],'TM2': [42,65],'TM3': [23,47],'TM4': [43,64],'TM5': [36,59], 'TM6': [37,60], 'TM7': [32,54]}
        core_membrane_classF = {'TM1': [33, 55],'TM2': [42,65],'TM3': [23,47],'TM4': [43,64],'TM5': [36,59], 'TM6': [37,60], 'TM7': [32,54]}

        # Residue oriented outward of bundle (based on inactive 4BVN and active 3SN6)
        outward_orientation = {
            'TM1' : [29, 30, 33, 34, 36, 37, 38, 40, 41, 44, 45, 48, 51, 52, 54, 55, 58],
            'TM2' : [38, 41, 45, 48, 52, 55, 56, 58, 59, 60, 62, 63, 66],
            'TM3' : [23, 24, 27, 31, 48, 51, 52, 55],
            'TM4' : [40, 41, 43, 44, 47, 48, 50, 51, 52, 54, 55, 58, 59, 62, 63, 81],
            'TM5' : [36, 37, 38, 40, 41, 42, 44, 45, 46, 48, 49, 52, 53, 55, 56, 57, 59, 60, 62, 63, 64, 66, 67, 68, 70, 71, 73, 74],
            'TM6' : [25, 28, 29, 31, 32, 34, 35, 38, 39, 42, 43, 45, 46, 49, 50, 53, 54, 56, 57, 60],
            'TM7' : [33, 34, 35, 37, 40, 41, 43, 44, 48, 51, 52, 54, 55]
        }

        ########

        # prepare context for output
        context = {"signatures" : []}
        index = 0
        for h, segment in enumerate(rfb_panel["signatures"]["gs_positions"]["gpcrdba"]):
            segment_first = True
            for i, position in enumerate(rfb_panel["signatures"]["gs_positions"]["gpcrdba"][segment]):
                if len(position) <= 5:
                    # To filter segment headers with non-GN numbering
                    if segment_first:
                        context["signatures"].append({"position" : segment})
                        index += 1
                        segment_first = False

                    # Add data
                    context["signatures"].append({})
                    context["signatures"][index]["segment"] = segment
                    context["signatures"][index]["sort"] = index
                    context["signatures"][index]["position"] = position

                    # Normalized position in TM
                    partial_position = int(position.split('x')[1][:2])

                    # RESIDUE PLACEMENT
                    context["signatures"][index]["membane_placement"] = "-"
                    context["signatures"][index]["membane_segment"] = "Extracellular"
                    context["signatures"][index]["residue_orientation"] = "-"
                    if segment in mid_membrane_classA: # TM helix
                        # parse position
                        context["signatures"][index]["membane_placement"] = partial_position - mid_membrane_classA[segment]

                        # negative is toward cytoplasm
                        if segment in ['TM1', 'TM3', 'TM5', 'TM7']: # downwards
                            context["signatures"][index]["membane_placement"] = -1 * context["signatures"][index]["membane_placement"]

                        # Segment selection
                        if partial_position >= core_membrane_classA[segment][0] and partial_position <= core_membrane_classA[segment][1]:
                            context["signatures"][index]["membane_segment"] = "Membrane"
                        elif segment in ['TM1', 'TM3', 'TM5', 'TM7']:
                            if partial_position > core_membrane_classA[segment][1]:
                                context["signatures"][index]["membane_segment"] = "Intracellular"
                        else:
                            if partial_position < core_membrane_classA[segment][0]:
                                context["signatures"][index]["membane_segment"] = "Intracellular"

                        # Orientation
                        if partial_position in outward_orientation[segment]:
                            context["signatures"][index]["residue_orientation"] = "Outward"
                        else:
                            if partial_position > min(outward_orientation[segment]) and partial_position < max(outward_orientation[segment]):
                                context["signatures"][index]["residue_orientation"] = "Inward"
                    # Intracellular segments
                    elif segment in ['ICL1', 'ICL2', 'ICL3', 'TM8', 'C-term']:
                        context["signatures"][index]["membane_segment"] = "Intracellular"

                    # COUNTS: all db results in a singe loop
                    for key in ["ligand_binding", "natural_mutations", "thermo_mutations", "ligand_mutations", "basal_mutations", "intrasegment_contacts", "phos", "palm", "glyc", "ubiq" ]: # Add in future "gprotein_interface", "arrestin_interface"
                        context["signatures"][index][key] = 0
                        if position in rfb_panel[key]:
                            context["signatures"][index][key] = rfb_panel[key][position]

                    # G-protein interface
                    context["signatures"][index]["gprotein_interface"] = 0
                    if position in gprotein_labels:
                        context["signatures"][index]["gprotein_interface"] = len(gprotein_labels[position])

                    # Arrestin interface
                    context["signatures"][index]["arrestin_interface"] = 0
                    if position in arrestin_labels:
                        context["signatures"][index]["arrestin_interface"] = len(arrestin_labels[position])

                    # BINARY

                    # Microswitch
                    context["signatures"][index]["microswitch"] = position in ms_labels

                    # Sodium pocket
                    context["signatures"][index]["sodium"] = position in sp_labels

                    # Rotamer switch
                    context["signatures"][index]["rotamer_switch"] = position in rotamer_labels

                    # contacts
                    context["signatures"][index]["active_contacts"] = 0
                    if position in rfb_panel["active_contacts"]:
                        if position in rfb_panel["inactive_contacts"]:
                            context["signatures"][index]["active_contacts"] = len(rfb_panel["active_contacts"][position].difference(rfb_panel["inactive_contacts"][position]))
                        else:
                            context["signatures"][index]["active_contacts"] = len(rfb_panel["active_contacts"][position])

                    context["signatures"][index]["inactive_contacts"] = 0
                    if position in rfb_panel["inactive_contacts"]:
                        if position in rfb_panel["active_contacts"]:
                            context["signatures"][index]["inactive_contacts"] = len(rfb_panel["inactive_contacts"][position].difference(rfb_panel["active_contacts"][position]))
                        else:
                            context["signatures"][index]["inactive_contacts"] = len(rfb_panel["inactive_contacts"][position])

                    # CLASS A sequence + property consensus
                    if position in rfb_panel["class_a_positions"]["gpcrdba"][segment]:
                        ca_index = list(rfb_panel["class_a_positions"]["gpcrdba"][segment]).index(position)

                        # Sequence consensus
                        context["signatures"][index]["class_a_aa"] = rfb_panel["class_a_aa"][segment][position][0]
                        context["signatures"][index]["class_a_aa_name"] = FULL_AMINO_ACIDS[rfb_panel["class_a_aa"][segment][position][0]]
                        if context["signatures"][index]["class_a_aa"] == '+':
                            context["signatures"][index]["class_a_aa_name"] += ": "+rfb_panel["class_a_aa"][segment][position][3]
                        context["signatures"][index]["class_a_aa_cons"] = rfb_panel["class_a_aa"][segment][position][2]

                        # Property consensus
                        context["signatures"][index]["class_a_symb"] = rfb_panel["class_a_prop"][segment][i][0]
                        context["signatures"][index]["class_a_prop"] = rfb_panel["class_a_prop"][segment][i][1]
                        context["signatures"][index]["class_a_prop_cons"] = rfb_panel["class_a_prop"][segment][i][2]

                    # SEQUENCE SIGNATURES
                    for signature_type in ["cah", "cal", "gs", "gio", "gq", "g12"]:
                        if position in rfb_panel["signatures"][signature_type + "_positions"]["gpcrdba"][segment]:
                            ca_index = list(rfb_panel["signatures"][signature_type + "_positions"]["gpcrdba"][segment]).index(position)
                            context["signatures"][index][signature_type + "_score"] = rfb_panel["signatures"][signature_type][segment][ca_index][2]
                            context["signatures"][index][signature_type + "_prop"] = rfb_panel["signatures"][signature_type][segment][ca_index][1]
                            context["signatures"][index][signature_type + "_symb"] = rfb_panel["signatures"][signature_type][segment][ca_index][0]

                    index += 1

        # Human Class A alignment - consensus/conservation
        return context
Ejemplo n.º 6
0
def render_signature_excel(request):

    # version #2 - 5 sheets with separate pieces of signature outline

    # step 1 - repeat the data preparation for a sequence signature

    # targets set #1
    ss_pos = request.session.get('targets_pos', False)
    # targets set #2
    ss_neg = request.session.get('selection', False)

    signature = SequenceSignature()
    signature.setup_alignments_from_selection(ss_pos, ss_neg)

    # calculate the signture
    signature.calculate_signature()

    outstream = BytesIO()
    # wb = xlsxwriter.Workbook('excel_test.xlsx', {'in_memory': False})
    wb = xlsxwriter.Workbook(outstream, {'in_memory': True})
    # Feature stats for signature
    signature.prepare_excel_worksheet(wb, 'signature_properties', 'signature',
                                      'features')
    # Feature stats for positive group alignment
    signature.prepare_excel_worksheet(wb, 'protein_set1_properties',
                                      'positive', 'features')
    # Positive group alignment
    signature.prepare_excel_worksheet(wb, 'protein_set1_aln', 'positive',
                                      'alignment')
    # Feature stats for negative group alignment
    signature.prepare_excel_worksheet(wb, 'protein_set2_properties',
                                      'negative', 'features')
    # Negative group alignment
    signature.prepare_excel_worksheet(wb, 'protein_set2_aln', 'negative',
                                      'alignment')
    signature.per_gn_signature_excel(wb)

    wb.close()
    outstream.seek(0)
    response = HttpResponse(
        outstream.read(),
        content_type=
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
    response[
        'Content-Disposition'] = "attachment; filename=sequence_signature.xlsx"

    return response
Ejemplo n.º 7
0
    def get_context_data (self, **kwargs):
        # setup caches
        cache_name = "RFB"
        rfb_panel = cache.get(cache_name)
#        rfb_panel = None
        if rfb_panel == None:
            rfb_panel = {}

            # Signatures
            rfb_panel["signatures"] = {}

            # Grab relevant segments
            segments = list(ProteinSegment.objects.filter(proteinfamily='GPCR'))

            # Grab High/Low CA GPCRs (class A)
            high_ca = ["5ht2c_human", "acm4_human", "drd1_human", "fpr1_human", "ghsr_human", "cnr1_human", "aa1r_human", "gpr6_human", "gpr17_human", "gpr87_human"]
            low_ca = ["agtr1_human", "ednrb_human", "gnrhr_human", "acthr_human", "v2r_human", "gp141_human", "gp182_human"]

            # Signature High vs Low CA
            high_ca_gpcrs = Protein.objects.filter(entry_name__in=high_ca).select_related('residue_numbering_scheme', 'species')
            low_ca_gpcrs = Protein.objects.filter(entry_name__in=low_ca).select_related('residue_numbering_scheme', 'species')

            signature = SequenceSignature()
            signature.setup_alignments(segments, high_ca_gpcrs, low_ca_gpcrs)
            signature.calculate_signature()
            rfb_panel["signatures"]["cah"] = signature.signature
            rfb_panel["signatures"]["cah_positions"] = signature.common_gn

            signature = SequenceSignature()
            signature.setup_alignments(segments, low_ca_gpcrs, high_ca_gpcrs)
            signature.calculate_signature()
            rfb_panel["signatures"]["cal"] = signature.signature
            rfb_panel["signatures"]["cal_positions"] = signature.common_gn

            # Grab Gi/Gs/Gq/GI12 GPCR sets (class A)
            human_class_a_gpcrs = Protein.objects.filter(species_id=1, sequence_type_id=1, family__slug__startswith='001').distinct().prefetch_related('proteingprotein_set', 'residue_numbering_scheme')
            gs  = list(human_class_a_gpcrs.filter(proteingprotein__slug="100_001_001"))
            gio = list(human_class_a_gpcrs.filter(proteingprotein__slug="100_001_002"))
            gq  = list(human_class_a_gpcrs.filter(proteingprotein__slug="100_001_003"))
            g12 = list(human_class_a_gpcrs.filter(proteingprotein__slug="100_001_004"))
            all = set(gs + gio + gq + g12)

            # Create sequence signatures for the G-protein sets
            for gprotein in ["gs", "gio", "gq", "g12"]:
#                print("Processing " + gprotein)
                # Signature receptors specific for a G-protein vs all others
                signature = SequenceSignature()
                signature.setup_alignments(segments, locals()[gprotein], all.difference(locals()[gprotein]))
                signature.calculate_signature()
                rfb_panel["signatures"][gprotein] = signature.signature
                rfb_panel["signatures"][gprotein + "_positions"] = signature.common_gn

            # Add class A alignment features
            signature = SequenceSignature()
            signature.setup_alignments(segments, human_class_a_gpcrs, [list(human_class_a_gpcrs)[0]])
            signature.calculate_signature()
            rfb_panel["class_a_positions"] = signature.common_gn
            rfb_panel["class_a_aa"] = signature.aln_pos.consensus
            rfb_panel["class_a_prop"] = signature.features_consensus_pos

            # Add X-ray ligand contacts
            # Optionally include the curation with the following filter: structure_ligand_pair__annotated=True
            class_a_interactions = ResidueFragmentInteraction.objects.filter(
                structure_ligand_pair__structure__protein_conformation__protein__family__slug__startswith="001").exclude(interaction_type__type='hidden')\
                .values("rotamer__residue__generic_number__label").annotate(unique_receptors=Count("rotamer__residue__protein_conformation__protein__family_id", distinct=True))

            rfb_panel["ligand_binding"] = {entry["rotamer__residue__generic_number__label"] : entry["unique_receptors"] for entry in list(class_a_interactions)}

            # Add genetic variations
            all_nat_muts = NaturalMutations.objects.filter(protein__family__slug__startswith="001").values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["natural_mutations"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_nat_muts)}

            # Add PTMs
            all_ptms = PTMs.objects.filter(protein__family__slug__startswith="001").values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["ptms"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_ptms)}
            all_phos = PTMs.objects.filter(protein__family__slug__startswith="001").filter(modification="Phosphorylation").values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["phos"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_phos)}
            all_palm = PTMs.objects.filter(protein__family__slug__startswith="001").filter(modification="Palmitoylation").values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["palm"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_palm)}
            all_glyc = PTMs.objects.filter(protein__family__slug__startswith="001").filter(modification__endswith="Glycosylation").values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["glyc"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_glyc)}
            all_ubiq = PTMs.objects.filter(protein__family__slug__startswith="001").filter(modification="Ubiquitylation").values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["ubiq"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_ubiq)}

            # Thermostabilizing
            all_thermo = ConstructMutation.objects.filter(construct__protein__family__slug__startswith="001", effects__slug='thermostabilising')\
                        .values("residue__generic_number__label").annotate(unique_receptors=Count("construct__protein__family_id", distinct=True))
            rfb_panel["thermo_mutations"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_thermo)}


            # Class A ligand mutations >5 fold effect - count unique receptors
            all_ligand_mutations = MutationExperiment.objects.filter(Q(foldchange__gte = 5) | Q(foldchange__lte = -5), protein__family__slug__startswith="001")\
                            .values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["ligand_mutations"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_ligand_mutations)}

            # Class A mutations with >30% increase/decrease basal activity
            all_basal_mutations = MutationExperiment.objects.filter(Q(opt_basal_activity__gte = 130) | Q(opt_basal_activity__lte = 70), protein__family__slug__startswith="001")\
                            .values("residue__generic_number__label").annotate(unique_receptors=Count("protein__family_id", distinct=True))
            rfb_panel["basal_mutations"] = {entry["residue__generic_number__label"] : entry["unique_receptors"] for entry in list(all_basal_mutations)}

            # Intrasegment contacts
            all_contacts = InteractingResiduePair.objects.filter(~Q(res1__protein_segment_id = F('res2__protein_segment_id')), referenced_structure__protein_conformation__protein__family__slug__startswith="001")\
                            .values("res1__generic_number__label").annotate(unique_receptors=Count("referenced_structure__protein_conformation__protein__family_id", distinct=True))
            rfb_panel["intrasegment_contacts"] = {entry["res1__generic_number__label"] : entry["unique_receptors"] for entry in list(all_contacts)}


            # Active/Inactive contacts
            all_active_contacts = InteractingResiduePair.objects.filter(~Q(res2__generic_number__label = None), ~Q(res1__generic_number__label = None),\
                    referenced_structure__state__slug = "active", referenced_structure__protein_conformation__protein__family__slug__startswith="001")\
                    .values("res1__generic_number__label", "res2__generic_number__label")

            # OPTIMIZE
            active_contacts = {}
            for entry in list(all_active_contacts):
                if entry["res1__generic_number__label"] not in active_contacts:
                    active_contacts[entry["res1__generic_number__label"]] = set()
                active_contacts[entry["res1__generic_number__label"]].update([entry["res2__generic_number__label"]])
            rfb_panel["active_contacts"] = active_contacts

            all_inactive_contacts = InteractingResiduePair.objects.filter(~Q(res2__generic_number__label = None), ~Q(res1__generic_number__label = None),\
                    referenced_structure__state__slug = "inactive", referenced_structure__protein_conformation__protein__family__slug__startswith="001")\
                    .values("res1__generic_number__label", "res2__generic_number__label")

            # OPTIMIZE
            inactive_contacts = {}
            for entry in list(all_inactive_contacts):
                if entry["res1__generic_number__label"] not in inactive_contacts:
                        inactive_contacts[entry["res1__generic_number__label"]] = set()
                inactive_contacts[entry["res1__generic_number__label"]].update([entry["res2__generic_number__label"]])
            rfb_panel["inactive_contacts"] = inactive_contacts

            cache.set(cache_name, rfb_panel, 3600*24*7) # cache a week

        # Other rules
#        structural_rule_tree = create_structural_rule_trees(STRUCTURAL_RULES)

        ######## CREATE REFERENCE sets (or use structural rules)

        ## MICROSWITCHES
        ms_labels = [residue.label for residue in ResiduePositionSet.objects.get(name="State (micro-)switches").residue_position.all()]

        ## SODIUM POCKET
        sp_labels = [residue.label for residue in ResiduePositionSet.objects.get(name="Sodium ion pocket").residue_position.all()]

        ## ROTAMER SWITCHES
        rotamer_labels = []
        for entry in STRUCTURAL_SWITCHES["A"]:
            if entry["Rotamer Switch"] != "-":
                rotamer_labels.append(entry["AA1 Pos"])
                rotamer_labels.append(entry["AA2 Pos"])


        ## G PROTEIN INTERACTION POSITIONS
#        gprotein_labels = [residue.label for residue in ResiduePositionSet.objects.get(name="Signalling protein pocket").residue_position.all()]
        # Class A G-protein X-ray contacts
        # TODO: replace with automatically generated sets from X-rays stored in database
        gprotein_labels = {"1x60": {"001_006_001_001", " 001_006_001_002"},
                            "12x48": {"001_001_003_008", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "12x49": {"001_001_003_008", " 001_006_001_002"},
                            "12x51": {"001_006_001_002"},
                            "2x37": {"001_006_001_001"},
                            "2x39": {"001_002_022_003"},
                            "2x40": {"001_006_001_001"},
                            "3x49": {"001_001_003_008", " 001_002_022_003"},
                            "3x50": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "3x53": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002"},
                            "3x54": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "3x55": {"001_001_003_008", " 001_006_001_002"},
                            "3x56": {"001_006_001_002", " 001_009_001_001"},
                            "34x50": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002"},
                            "34x51": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002"},
                            "34x52": {"001_001_003_008", " 001_002_022_003", " 001_006_001_002"},
                            "34x53": {"001_001_003_008", " 001_006_001_002"},
                            "34x54": {"001_001_003_008", " 001_002_022_003", " 001_006_001_002"},
                            "34x55": {"001_001_003_008", " 001_002_022_003", " 001_006_001_002", " 001_009_001_001"},
                            "34x57": {"001_001_001_002", " 001_002_022_003"},
                            "4x40": {"001_002_022_003"},
                            "5x61": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002"},
                            "5x64": {"001_001_003_008", " 001_002_022_003", " 001_006_001_002"},
                            "5x65": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002"},
                            "5x67": {"001_001_003_008"},
                            "5x68": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002"},
                            "5x69": {"001_001_001_002", " 001_001_003_008", " 001_006_001_001", " 001_006_001_002"},
                            "5x71": {"001_001_003_008", " 001_006_001_001", " 001_006_001_002"},
                            "5x72": {"001_001_003_008", " 001_006_001_002", " 001_009_001_001"},
                            "5x74": {"001_001_003_008"},
                            "6x23": {"001_002_022_003"},
                            "6x24": {"001_009_001_001"},
                            "6x25": {"001_002_022_003", " 001_006_001_001", " 001_009_001_001"},
                            "6x26": {"001_002_022_003", " 001_009_001_001"},
                            "6x28": {"001_009_001_001"},
                            "6x29": {"001_001_001_002", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "6x32": {"001_001_001_002", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "6x33": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "6x36": {"001_001_001_002", " 001_001_003_008", " 001_002_022_003", " 001_006_001_002", " 001_009_001_001"},
                            "6x37": {"001_001_001_002", " 001_001_003_008", " 001_006_001_001", " 001_006_001_002"},
                            "7x56": {"001_001_001_002", " 001_006_001_001", " 001_006_001_002", " 001_009_001_001"},
                            "8x47": {"001_001_001_002", " 001_002_022_003", " 001_006_001_001", " 001_009_001_001"},
                            "8x48": {"001_002_022_003", " 001_006_001_002", " 001_009_001_001"},
                            "8x49": {"001_006_001_001", " 001_006_001_002"},
                            "8x51": {"001_006_001_002"},
                            "8x56": {"001_006_001_001"}}

        # TODO: replace with automatically generated sets from X-rays stored in database
        # Class A Arrestin X-ray contacts
        arrestin_labels = {"12x49": {"001_009_001_001"},
                            "2x37": {"001_009_001_001"},
                            "2x38": {"001_009_001_001"},
                            "2x39": {"001_009_001_001"},
                            "2x40": {"001_009_001_001"},
                            "2x43": {"001_009_001_001"},
                            "3x50": {"001_009_001_001"},
                            "3x54": {"001_009_001_001"},
                            "3x55": {"001_009_001_001"},
                            "3x56": {"001_009_001_001"},
                            "34x50": {"001_009_001_001"},
                            "34x51": {"001_009_001_001"},
                            "34x53": {"001_009_001_001"},
                            "34x54": {"001_009_001_001"},
                            "34x55": {"001_009_001_001"},
                            "34x56": {"001_009_001_001"},
                            "4x38": {"001_009_001_001"},
                            "5x61": {"001_009_001_001"},
                            "5x64": {"001_009_001_001"},
                            "5x68": {"001_009_001_001"},
                            "5x69": {"001_009_001_001"},
                            "5x71": {"001_009_001_001"},
                            "5x72": {"001_009_001_001"},
                            "6x24": {"001_009_001_001"},
                            "6x25": {"001_009_001_001"},
                            "6x26": {"001_009_001_001"},
                            "6x28": {"001_009_001_001"},
                            "6x29": {"001_009_001_001"},
                            "6x32": {"001_009_001_001"},
                            "6x33": {"001_009_001_001"},
                            "6x36": {"001_009_001_001"},
                            "6x37": {"001_009_001_001"},
                            "6x40": {"001_009_001_001"},
                            "8x47": {"001_009_001_001"},
                            "8x48": {"001_009_001_001"},
                            "8x49": {"001_009_001_001"},
                            "8x50": {"001_009_001_001"}}

        # Positions in center of membrane selected using 4BVN (ADRB1) together with OPM membrane positioning
        # Reference: ['1x44', '2x52', '3x36', '4x54', '5x46', '6x48', '7x43']
        mid_membrane_classA = {'TM1': 44,'TM2': 52,'TM3': 36,'TM4': 54,'TM5': 46, 'TM6': 48, 'TM7': 43}

        # NOTE: We might need to split this into B1 and B2 when adhesion X-rays are published
        # Positions in center of membrane selected using 5XEZ (GCGR) together with OPM membrane positioning
        # Reference: ['1x51', '2x58', '3x41', '4x54', '5x45', '6x49', '7x50']
        mid_membrane_classB = {'TM1': 51,'TM2': 58,'TM3': 41,'TM4': 54,'TM5': 45, 'TM6': 49, 'TM7': 50}

        # Positions in center of membrane selected using 4OR2 (mGLUR1) together with OPM membrane positioning
        # Reference: ['1x49', '2x48', '3x40', '4x41', '5x48', '6x48', '7.39x40']
        mid_membrane_classC = {'TM1': 49,'TM2': 48,'TM3': 40,'TM4': 41,'TM5': 48, 'TM6': 48, 'TM7': 40}

        # Positions in center of membrane selected using 6BD4 (FZD4) together with OPM membrane positioning
        # Reference: ['1x43', '2x53', '3x38', '4x53', '5x53', '6x43', '7x47']
        mid_membrane_classF = {'TM1': 43,'TM2': 53,'TM3': 38,'TM4': 53,'TM5': 53, 'TM6': 43, 'TM7': 47}

        # Positions within membrane layer selected using 4BVN together with OPM membrane positioning
        core_membrane_classA = {'TM1': [33, 55],'TM2': [42,65],'TM3': [23,47],'TM4': [43,64],'TM5': [36,59], 'TM6': [37,60], 'TM7': [32,54]}
        # TODO: other classes
        core_membrane_classB = {'TM1': [33, 55],'TM2': [42,65],'TM3': [23,47],'TM4': [43,64],'TM5': [36,59], 'TM6': [37,60], 'TM7': [32,54]}
        core_membrane_classC = {'TM1': [33, 55],'TM2': [42,65],'TM3': [23,47],'TM4': [43,64],'TM5': [36,59], 'TM6': [37,60], 'TM7': [32,54]}
        core_membrane_classF = {'TM1': [33, 55],'TM2': [42,65],'TM3': [23,47],'TM4': [43,64],'TM5': [36,59], 'TM6': [37,60], 'TM7': [32,54]}

        # Residue oriented outward of bundle (based on inactive 4BVN and active 3SN6)
        outward_orientation = {
            'TM1' : [29, 30, 33, 34, 36, 37, 38, 40, 41, 44, 45, 48, 51, 52, 54, 55, 58],
            'TM2' : [38, 41, 45, 48, 52, 55, 56, 58, 59, 60, 62, 63, 66],
            'TM3' : [23, 24, 27, 31, 48, 51, 52, 55],
            'TM4' : [40, 41, 43, 44, 47, 48, 50, 51, 52, 54, 55, 58, 59, 62, 63, 81],
            'TM5' : [36, 37, 38, 40, 41, 42, 44, 45, 46, 48, 49, 52, 53, 55, 56, 57, 59, 60, 62, 63, 64, 66, 67, 68, 70, 71, 73, 74],
            'TM6' : [25, 28, 29, 31, 32, 34, 35, 38, 39, 42, 43, 45, 46, 49, 50, 53, 54, 56, 57, 60],
            'TM7' : [33, 34, 35, 37, 40, 41, 43, 44, 48, 51, 52, 54, 55]
        }

        ########

        # prepare context for output
        context = {"signatures" : []}
        index = 0
        for h, segment in enumerate(rfb_panel["signatures"]["gs_positions"]["gpcrdba"]):
            segment_first = True
            for i, position in enumerate(rfb_panel["signatures"]["gs_positions"]["gpcrdba"][segment]):
                if len(position) <= 5:
                    # To filter segment headers with non-GN numbering
                    if segment_first:
                        context["signatures"].append({"position" : segment})
                        index += 1
                        segment_first = False

                    # Add data
                    context["signatures"].append({})
                    context["signatures"][index]["segment"] = segment
                    context["signatures"][index]["sort"] = index
                    context["signatures"][index]["position"] = position

                    # Normalized position in TM
                    partial_position = int(position.split('x')[1][:2])

                    # RESIDUE PLACEMENT
                    context["signatures"][index]["membane_placement"] = "-"
                    context["signatures"][index]["membane_segment"] = "Extracellular"
                    context["signatures"][index]["residue_orientation"] = "-"
                    if segment in mid_membrane_classA: # TM helix
                        # parse position
                        context["signatures"][index]["membane_placement"] = partial_position - mid_membrane_classA[segment]

                        # negative is toward cytoplasm
                        if segment in ['TM1', 'TM3', 'TM5', 'TM7']: # downwards
                            context["signatures"][index]["membane_placement"] = -1 * context["signatures"][index]["membane_placement"]

                        # Segment selection
                        if partial_position >= core_membrane_classA[segment][0] and partial_position <= core_membrane_classA[segment][1]:
                            context["signatures"][index]["membane_segment"] = "Membrane"
                        elif segment in ['TM1', 'TM3', 'TM5', 'TM7']:
                            if partial_position > core_membrane_classA[segment][1]:
                                context["signatures"][index]["membane_segment"] = "Intracellular"
                        else:
                            if partial_position < core_membrane_classA[segment][0]:
                                context["signatures"][index]["membane_segment"] = "Intracellular"

                        # Orientation
                        if partial_position in outward_orientation[segment]:
                            context["signatures"][index]["residue_orientation"] = "Outward"
                        else:
                            if partial_position > min(outward_orientation[segment]) and partial_position < max(outward_orientation[segment]):
                                context["signatures"][index]["residue_orientation"] = "Inward"
                    # Intracellular segments
                    elif segment in ['ICL1', 'ICL2', 'ICL3', 'TM8', 'C-term']:
                        context["signatures"][index]["membane_segment"] = "Intracellular"

                    # COUNTS: all db results in a singe loop
                    for key in ["ligand_binding", "natural_mutations", "thermo_mutations", "ligand_mutations", "basal_mutations", "intrasegment_contacts", "phos", "palm", "glyc", "ubiq" ]: # Add in future "gprotein_interface", "arrestin_interface"
                        context["signatures"][index][key] = 0
                        if position in rfb_panel[key]:
                            context["signatures"][index][key] = rfb_panel[key][position]

                    # G-protein interface
                    context["signatures"][index]["gprotein_interface"] = 0
                    if position in gprotein_labels:
                        context["signatures"][index]["gprotein_interface"] = len(gprotein_labels[position])

                    # Arrestin interface
                    context["signatures"][index]["arrestin_interface"] = 0
                    if position in arrestin_labels:
                        context["signatures"][index]["arrestin_interface"] = len(arrestin_labels[position])

                    # BINARY

                    # Microswitch
                    context["signatures"][index]["microswitch"] = position in ms_labels

                    # Sodium pocket
                    context["signatures"][index]["sodium"] = position in sp_labels

                    # Rotamer switch
                    context["signatures"][index]["rotamer_switch"] = position in rotamer_labels

                    # contacts
                    context["signatures"][index]["active_contacts"] = 0
                    if position in rfb_panel["active_contacts"]:
                        if position in rfb_panel["inactive_contacts"]:
                            context["signatures"][index]["active_contacts"] = len(rfb_panel["active_contacts"][position].difference(rfb_panel["inactive_contacts"][position]))
                        else:
                            context["signatures"][index]["active_contacts"] = len(rfb_panel["active_contacts"][position])

                    context["signatures"][index]["inactive_contacts"] = 0
                    if position in rfb_panel["inactive_contacts"]:
                        if position in rfb_panel["active_contacts"]:
                            context["signatures"][index]["inactive_contacts"] = len(rfb_panel["inactive_contacts"][position].difference(rfb_panel["active_contacts"][position]))
                        else:
                            context["signatures"][index]["inactive_contacts"] = len(rfb_panel["inactive_contacts"][position])

                    # CLASS A sequence + property consensus
                    if position in rfb_panel["class_a_positions"]["gpcrdba"][segment]:
                        ca_index = list(rfb_panel["class_a_positions"]["gpcrdba"][segment]).index(position)

                        # Sequence consensus
                        context["signatures"][index]["class_a_aa"] = rfb_panel["class_a_aa"][segment][position][0]
                        context["signatures"][index]["class_a_aa_name"] = FULL_AMINO_ACIDS[rfb_panel["class_a_aa"][segment][position][0]]
                        if context["signatures"][index]["class_a_aa"] == '+':
                            context["signatures"][index]["class_a_aa_name"] += ": "+rfb_panel["class_a_aa"][segment][position][3]
                        context["signatures"][index]["class_a_aa_cons"] = rfb_panel["class_a_aa"][segment][position][2]

                        # Property consensus
                        context["signatures"][index]["class_a_symb"] = rfb_panel["class_a_prop"][segment][i][0]
                        context["signatures"][index]["class_a_prop"] = rfb_panel["class_a_prop"][segment][i][1]
                        context["signatures"][index]["class_a_prop_cons"] = rfb_panel["class_a_prop"][segment][i][2]

                    # SEQUENCE SIGNATURES
                    for signature_type in ["cah", "cal", "gs", "gio", "gq", "g12"]:
                        if position in rfb_panel["signatures"][signature_type + "_positions"]["gpcrdba"][segment]:
                            ca_index = list(rfb_panel["signatures"][signature_type + "_positions"]["gpcrdba"][segment]).index(position)
                            context["signatures"][index][signature_type + "_score"] = rfb_panel["signatures"][signature_type][segment][ca_index][2]
                            context["signatures"][index][signature_type + "_prop"] = rfb_panel["signatures"][signature_type][segment][ca_index][1]
                            context["signatures"][index][signature_type + "_symb"] = rfb_panel["signatures"][signature_type][segment][ca_index][0]

                    index += 1

        # Human Class A alignment - consensus/conservation
        return context
Ejemplo n.º 8
0
def render_signature_excel(request):

    # version #2 - 5 sheets with separate pieces of signature outline

    # step 1 - repeat the data preparation for a sequence signature

    # targets set #1
    ss_pos = request.session.get('targets_pos', False)
    # targets set #2
    ss_neg = request.session.get('selection', False)

    signature = SequenceSignature()
    signature.setup_alignments_from_selection(ss_pos, ss_neg)

    # calculate the signture
    signature.calculate_signature()

    outstream = BytesIO()
    # wb = xlsxwriter.Workbook('excel_test.xlsx', {'in_memory': False})
    wb = xlsxwriter.Workbook(outstream, {'in_memory': True})
    # Feature stats for signature
    signature.prepare_excel_worksheet(
        wb,
        'signature_properties',
        'signature',
        'features'
    )
    # Feature stats for positive group alignment
    signature.prepare_excel_worksheet(
        wb,
        'protein_set1_properties',
        'positive',
        'features'
    )
    # Positive group alignment
    signature.prepare_excel_worksheet(
        wb,
        'protein_set1_aln',
        'positive',
        'alignment'
    )
    # Feature stats for negative group alignment
    signature.prepare_excel_worksheet(
        wb,
        'protein_set2_properties',
        'negative',
        'features'
    )
    # Negative group alignment
    signature.prepare_excel_worksheet(
        wb,
        'protein_set2_aln',
        'negative',
        'alignment'
    )
    signature.per_gn_signature_excel(wb)

    wb.close()
    outstream.seek(0)
    response = HttpResponse(
        outstream.read(),
        content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        )
    response['Content-Disposition'] = "attachment; filename=sequence_signature.xlsx"

    return response