diff --git a/HISTORY.txt b/HISTORY.txt index 2d5e617..0391070 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -9,4 +9,5 @@ 21-Feb-2021 - V0.17 Separate the computation and presentation of validation scores and target interactions 22-Feb-2021 - V0.18 Tweak sorting of unique target interactions and interaction and score attributes 23-Feb-2021 - V0.19 Change the default serialization and provide and format conversion method. -24-Feb-2021 - V0.20 Avoid reload with target updates when updateOnly=True \ No newline at end of file +24-Feb-2021 - V0.20 Avoid reload with target updates when updateOnly=True +24-Feb-2021 - V0.21 Refactor and add ligand and target neighbor data. Keep all nearest residue level interacitons. \ No newline at end of file diff --git a/rcsb/utils/dictionary/DictMethodCommonUtils.py b/rcsb/utils/dictionary/DictMethodCommonUtils.py index 8ff64cf..0ef90f6 100644 --- a/rcsb/utils/dictionary/DictMethodCommonUtils.py +++ b/rcsb/utils/dictionary/DictMethodCommonUtils.py @@ -55,6 +55,7 @@ "partnerCompId", "partnerAsymId", "partnerSeqId", + "partnerAuthSeqId", "partnerAtomId", "partnerAltId", "bondDistance", @@ -67,7 +68,6 @@ "rscc", "mogul_bonds_rmsz", "mogul_angles_rmsz", - "missing_heavy_atom_count", "intermolecular_clashes", "mogul_bond_outliers", "mogul_angle_outliers", @@ -88,13 +88,14 @@ "partnerCompId", "partnerAsymId", "partnerSeqId", + "partnerAuthSeqId", "partnerAtomId", "partnerAltId", "distance", ) LigandTargetInstance = namedtuple("LigandTargetInstance", LigandTargetFields, defaults=(None,) * len(LigandTargetFields)) -ReferenceFields = ("entityId", "entityType", "asymId", "compId", "seqId", "atomId", "altId") +ReferenceFields = ("entityId", "entityType", "asymId", "compId", "seqId", "authSeqId", "atomId", "altId") ReferenceInstance = namedtuple("ReferenceInstance", ReferenceFields, defaults=(None,) * len(ReferenceFields)) @@ -156,6 +157,7 @@ def __init__(self, **kwargs): self.__instanceSiteInfoCache = CacheUtils(size=cacheSize, label="instance site details") self.__instanceUnobservedCache = CacheUtils(size=cacheSize, label="instance unobserved details") self.__modelOutliersCache = CacheUtils(size=cacheSize, label="model outlier details") + self.__neighborInfoCache = CacheUtils(size=cacheSize, label="ligand and target nearest neighbors") # logger.debug("Dictionary common utilities init") @@ -1829,7 +1831,8 @@ def getBoundNonpolymersByInstance(self, dataContainer): Returns: dict: {: NonpolymerBoundInstance( "targetCompId", "targetAtomId", "targetAltId", "connectType", "partnerEntityType", "partnerEntityId", - "partnerCompId","partnerAsymId", "partnerSeqId", "partnerAtomId", "targetAltId", "bondDistance", "bondOrder"), } + "partnerCompId","partnerAsymId", "partnerSeqId", "partnerAuthSeqId", "partnerAtomId", "targetAltId", + "bondDistance", "bondOrder"), } """ if not dataContainer or not dataContainer.getName(): @@ -1917,6 +1920,7 @@ def __getInstanceConnections(self, dataContainer): "connect_target_label_comp_id": "ptnr1_label_comp_id", "connect_target_label_asym_id": "ptnr1_label_asym_id", "connect_target_label_seq_id": "ptnr1_label_seq_id", + "connect_target_auth_seq_id": "ptnr1_auth_seq_id", "connect_target_label_atom_id": "ptnr1_label_atom_id", "connect_target_label_alt_id": "pdbx_ptnr1_label_alt_id", "connect_target_symmetry": "ptnr1_symmetry", @@ -1924,6 +1928,7 @@ def __getInstanceConnections(self, dataContainer): "connect_partner_label_comp_id": "ptnr2_label_comp_id", "connect_partner_label_asym_id": "ptnr2_label_asym_id", "connect_partner_label_seq_id": "ptnr2_label_seq_id", + "connect_partner_auth_seq_id": "ptnr2_auth_seq_id", "connect_partner_label_atom_id": "ptnr2_label_atom_id", "connect_partner_label_alt_id": "pdbx_ptnr2_label_alt_id", "connect_partner_symmetry": "ptnr2_symmetry", @@ -1938,6 +1943,7 @@ def __getInstanceConnections(self, dataContainer): "connect_target_label_comp_id": "ptnr2_label_comp_id", "connect_target_label_asym_id": "ptnr2_label_asym_id", "connect_target_label_seq_id": "ptnr2_label_seq_id", + "connect_target_auth_seq_id": "ptnr2_auth_seq_id", "connect_target_label_atom_id": "ptnr2_label_atom_id", "connect_target_label_alt_id": "pdbx_ptnr2_label_alt_id", "connect_target_symmetry": "ptnr2_symmetry", @@ -1945,6 +1951,7 @@ def __getInstanceConnections(self, dataContainer): "connect_partner_label_comp_id": "ptnr1_label_comp_id", "connect_partner_label_asym_id": "ptnr1_label_asym_id", "connect_partner_label_seq_id": "ptnr1_label_seq_id", + "connect_partner_auth_seq_id": "ptnr1_auth_seq_id", "connect_partner_label_atom_id": "ptnr1_label_atom_id", "connect_partner_label_alt_id": "pdbx_ptnr1_label_alt_id", "connect_partner_symmetry": "ptnr1_symmetry", @@ -2036,6 +2043,7 @@ def __getBoundNonpolymers(self, dataContainer, instConnectL): pEntityId = asymIdD[pAsymId] pCompId = cD["connect_partner_label_comp_id"] pSeqId = cD["connect_partner_label_seq_id"] + pAuthSeqId = cD["connect_partner_auth_seq_id"] tCompId = cD["connect_target_label_comp_id"] tAtomId = cD["connect_target_label_atom_id"] pAtomId = cD["connect_partner_label_atom_id"] @@ -2047,7 +2055,9 @@ def __getBoundNonpolymers(self, dataContainer, instConnectL): # ts.add(tCompId) boundNonpolymerInstanceD.setdefault(tAsymId, []).append( - NonpolymerBoundInstance(tCompId, tAtomId, tAltId, cD["connect_type"], eType, pEntityId, pCompId, pAsymId, pSeqId, pAtomId, pAltId, bondDist, bondOrder) + NonpolymerBoundInstance( + tCompId, tAtomId, tAltId, cD["connect_type"], eType, pEntityId, pCompId, pAsymId, pSeqId, pAuthSeqId, pAtomId, pAltId, bondDist, bondOrder + ) ) boundNonpolymerEntityD.setdefault(tEntityId, []).append(NonpolymerBoundEntity(tCompId, cD["connect_type"], pCompId, pEntityId, eType)) # @@ -3751,7 +3761,7 @@ def getInstanceNonpolymerValidationInfo(self, dataContainer): dataContainer (object): mmcif.api.mmif.api.DataContainer object instance Returns: - dict: {(modelId, asymId): NonpolymerValidationInstance(rsr, rsrCc, bondsRmsZ, anglesRmsZ, missingAtomCount, + dict: {(modelId, asymId): NonpolymerValidationInstance(rsr, rsrCc, bondsRmsZ, anglesRmsZ, intermolecular_clashes, mogul_bond_outliers, mogul_angle_outliers, stereo_outliers)} """ @@ -3838,7 +3848,6 @@ def __getInstanceModelOutliers(self, dataContainer): ): return rD # ------- --------- ------- --------- ------- --------- ------- --------- ------- --------- - nonPolyMissingAtomD = self.getUnobservedNonPolymerAtomInfo(dataContainer) instanceTypeD = self.getInstanceTypes(dataContainer) # instanceModelOutlierD = {} @@ -4110,21 +4119,16 @@ def __getInstanceModelOutliers(self, dataContainer): tS = "RSCC < 0.65 (altId %s)" % altId if altId else "RSCC < 0.65" instanceModelOutlierD.setdefault((modelId, asymId, altId, False), []).append(OutlierValue(compId, None, "RSCC_OUTLIER", tS, rsrCc)) if asymId in instanceTypeD and instanceTypeD[asymId] == "non-polymer": - missingAtomCount = len(nonPolyMissingAtomD[(modelId, compId, asymId, 0)]) if (modelId, compId, asymId, 0) in nonPolyMissingAtomD else 0 - missingAtomCount += len(nonPolyMissingAtomD[(modelId, compId, asymId, 1)]) if (modelId, compId, asymId, 1) in nonPolyMissingAtomD else 0 instanceModelValidationD[(modelId, asymId, altId, compId)] = NonpolymerValidationInstance( float(rsr) if rsr else None, float(rsrCc) if rsrCc else None, float(bondsRmsZ) if bondsRmsZ else None, float(anglesRmsZ) if anglesRmsZ else None, - missingAtomCount, npClashD[(modelId, asymId, altId, compId)] if (modelId, asymId, altId, compId) in npClashD else 0, npMogulBondOutlierD[(modelId, asymId, altId, compId)] if (modelId, asymId, altId, compId) in npMogulBondOutlierD else 0, npMogulAngleOutlierD[(modelId, asymId, altId, compId)] if (modelId, asymId, altId, compId) in npMogulAngleOutlierD else 0, npStereoOutlierD[(modelId, asymId, altId, compId)] if (modelId, asymId, altId, compId) in npStereoOutlierD else 0, ) - if missingAtomCount > 0: - logger.debug("%s %s missing atom count %d", dataContainer.getName(), compId, missingAtomCount) # logger.debug("instanceModelOutlierD %r", instanceModelOutlierD) logger.debug("instanceModelValidationD %r", instanceModelValidationD) @@ -4134,7 +4138,93 @@ def __getInstanceModelOutliers(self, dataContainer): logger.exception("%s failing with %s", dataContainer.getName(), str(e)) return rD - def getNonpolymerInstanceNeighborInfo(self, dataContainer, distLimit=5.0, targetModelId="1"): + def getNearestNeighborList(self, dataContainer): + """Return a list of nearest neighbors for ligands and targets referenced + by the target and ligand indices. + + Args: + dataContainer (object): mmcif.api.mmif.api.DataContainer object instance + + Returns: + list: [LigandTargetInstance(), ...] + + """ + if not dataContainer or not dataContainer.getName(): + return {} + wD = self.__fetchNeighborInfo(dataContainer) + return wD["nearestNeighbors"] if "nearestNeighbors" in wD else {} + + def getLigandNeighborIndex(self, dataContainer): + """Return the index of nearest neighbors for ligands interacting + with targets polymer and branched entity instances. + + Args: + dataContainer (object): mmcif.api.mmif.api.DataContainer object instance + + Returns: + (dict): {ligandAsymId: {(targetAsymId, targetAuthSeqId): nnIndex1, (): nnIndex2} + + """ + if not dataContainer or not dataContainer.getName(): + return {} + wD = self.__fetchNeighborInfo(dataContainer) + return wD["ligandNeighborIndexD"] if "ligandNeighborIndexD" in wD else {} + + def getTargetNeighborIndex(self, dataContainer): + """Return the index of nearest neighbors for polymer and branched entity targets interacting + with ligand entity instances. + + Args: + dataContainer (object): mmcif.api.mmif.api.DataContainer object instance + + Returns: + (dict): {(targetAsymId, targetAuthSeqId): {(ligandAsymId): nnIndex1, (): nnIndex2} + + """ + if not dataContainer or not dataContainer.getName(): + return {} + wD = self.__fetchNeighborInfo(dataContainer) + return wD["targetNeighborIndexD"] if "targetNeighborIndexD" in wD else {} + + def getLigandAtomCountD(self, dataContainer): + """Return the ligand atom counts for all observed alternate conformers + of ligand instances. + + Args: + dataContainer (object): mmcif.api.mmif.api.DataContainer object instance + + Returns: + (dict): {ligandAsymId: {'FL': ### 'A': ###, 'B': ###}, ... } + + """ + if not dataContainer or not dataContainer.getName(): + return {} + wD = self.__fetchNeighborInfo(dataContainer) + return wD["ligandAtomCountD"] if "ligandAtomCountD" in wD else {} + + def getLigandNeighborBoundState(self, dataContainer): + """Return the dicitonary of ligand instances with isBound boolean status. + + Args: + dataContainer (object): mmcif.api.mmif.api.DataContainer object instance + + Returns: + (dict): {ligandAsymId: True if isBound, ... } + + """ + if not dataContainer or not dataContainer.getName(): + return {} + wD = self.__fetchNeighborInfo(dataContainer) + return wD["ligandIsBoundD"] if "ligandIsBoundD" in wD else {} + + def __fetchNeighborInfo(self, dataContainer): + wD = self.__neighborInfoCache.get(dataContainer.getName()) + if not wD: + wD = self.getNeighborInfo(dataContainer) + self.__neighborInfoCache.set(dataContainer.getName(), wD) + return wD + + def getNeighborInfo(self, dataContainer, distLimit=5.0, targetModelId="1"): """Get bound and unbound neighbors for each non-polymer instance and occupancy weighted ligand counts. Args: @@ -4143,15 +4233,28 @@ def getNonpolymerInstanceNeighborInfo(self, dataContainer, distLimit=5.0, target targetModelId (str, optional): select only for this model identifier. Defaults to 1. Returns: - (dict, dict): {asymId: [LigandTargetInstance()]}, {asymId: {altId: atomcount}, } + (dict, dict, list, dict): {asymId: [LigandTargetInstance()]}, {asymId: {altId: atomcount}, } """ try: startTime = time.time() - ligandTargetInstanceD = {} + # + nearestNeighbors = [] + ligandIndexD = {} + targetIndexD = {} + ligandIsBoundD = {} ligandAtomCountD = {} + rD = { + "targetNeighborIndexD": targetIndexD, + "ligandNeighborIndexD": ligandIndexD, + "nearestNeighbors": nearestNeighbors, + "ligandIsBoundD": ligandIsBoundD, + "ligandAtomCountD": ligandAtomCountD, + } + # + ligandTargetInstanceD = {} instanceTypeD = self.getInstanceTypes(dataContainer) if "non-polymer" not in instanceTypeD.values(): - return ligandTargetInstanceD, ligandAtomCountD + return rD # entryId = dataContainer.getName() logger.debug("Starting with entry %s", entryId) @@ -4185,6 +4288,7 @@ def getNonpolymerInstanceNeighborInfo(self, dataContainer, distLimit=5.0, target # atomId = aObj.getValue("label_atom_id", ii) seqId = aObj.getValue("label_seq_id", ii) + authSeqId = aObj.getValue("auth_seq_id", ii) compId = aObj.getValue("label_comp_id", ii) altId = aObj.getValueOrDefault("label_alt_id", ii, None) xC = aObj.getValue("Cartn_x", ii) @@ -4196,10 +4300,10 @@ def getNonpolymerInstanceNeighborInfo(self, dataContainer, distLimit=5.0, target # if selectType == "target": targetXyzL.append((float(xC), float(yC), float(zC))) - targetRefL.append(ReferenceInstance(entityId, instanceType, asymId, compId, int(seqId) if seqId not in [".", "?"] else None, atomId, altId)) + targetRefL.append(ReferenceInstance(entityId, instanceType, asymId, compId, int(seqId) if seqId not in [".", "?"] else None, authSeqId, atomId, altId)) elif selectType == "ligand": ligandXyzD.setdefault(asymId, []).append((float(xC), float(yC), float(zC))) - ligandRefD.setdefault(asymId, []).append(ReferenceInstance(entityId, instanceType, asymId, compId, None, atomId, altId)) + ligandRefD.setdefault(asymId, []).append(ReferenceInstance(entityId, instanceType, asymId, compId, None, authSeqId, atomId, altId)) if not altId: ligandAtomCountD.setdefault(asymId, defaultdict(int))["FL"] += 1 @@ -4210,7 +4314,7 @@ def getNonpolymerInstanceNeighborInfo(self, dataContainer, distLimit=5.0, target # ------ logger.debug("%s targetXyzL (%d) targetRef (%d) ligandXyzD (%d) ", entryId, len(targetXyzL), len(targetXyzL), len(ligandXyzD)) if not targetXyzL: - return ligandTargetInstanceD, ligandAtomCountD + return rD tArr = np.array(targetXyzL, order="F") logger.debug("targetXyzL[0] %r tArr.shape %r tArr[0] %r", targetXyzL[0], tArr.shape, tArr[0]) tree = spatial.cKDTree(tArr) @@ -4235,6 +4339,7 @@ def getNonpolymerInstanceNeighborInfo(self, dataContainer, distLimit=5.0, target tup.partnerCompId, tup.partnerAsymId, tup.partnerSeqId, + tup.partnerAuthSeqId, tup.partnerAtomId, tup.partnerAltId, float(tup.bondDistance) if tup.bondDistance else None, @@ -4263,6 +4368,7 @@ def getNonpolymerInstanceNeighborInfo(self, dataContainer, distLimit=5.0, target targetRefL[ind].compId, targetRefL[ind].asymId, targetRefL[ind].seqId, + targetRefL[ind].authSeqId, targetRefL[ind].atomId, targetRefL[ind].altId, round(dist, 3), @@ -4276,9 +4382,29 @@ def getNonpolymerInstanceNeighborInfo(self, dataContainer, distLimit=5.0, target # re-sort by distance - for asymId in ligandTargetInstanceD: ligandTargetInstanceD[asymId] = sorted(ligandTargetInstanceD[asymId], key=itemgetter(-1)) - # ------ + # + # --- ---- + tnD = {} + ligandIsBoundD = {} + for asymId, neighborL in ligandTargetInstanceD.items(): + isBound = False + for neighbor in neighborL: + tnD.setdefault(asymId, {}).setdefault((neighbor.partnerAsymId, neighbor.partnerAuthSeqId), []).append(neighbor) + if neighbor.connectType != "non-bonded": + isBound = True + ligandIsBoundD[asymId] = isBound + # --- ---- + jj = 0 + for asymId, nD in tnD.items(): + for (pAsymId, pAuthSeqId), nL in nD.items(): + ligandIndexD.setdefault(asymId, {})[(pAsymId, pAuthSeqId)] = jj + targetIndexD.setdefault((pAsymId, pAuthSeqId), {})[asymId] = jj + nearestNeighbors.append(nL[0]) + jj += 1 + # + # --- ---- except Exception as e: logger.exception("Failing for %r with %r", dataContainer.getName() if dataContainer else None, str(e)) # logger.info("Completed %s at %s (%.4f seconds)", dataContainer.getName(), time.strftime("%Y %m %d %H:%M:%S", time.localtime()), time.time() - startTime) - return ligandTargetInstanceD, ligandAtomCountD + return rD diff --git a/rcsb/utils/dictionary/DictMethodEntityInstanceHelper.py b/rcsb/utils/dictionary/DictMethodEntityInstanceHelper.py index f89150f..44f03c8 100644 --- a/rcsb/utils/dictionary/DictMethodEntityInstanceHelper.py +++ b/rcsb/utils/dictionary/DictMethodEntityInstanceHelper.py @@ -1693,7 +1693,7 @@ def buildInstanceValidationScores(self, dataContainer, catName, **kwargs): # instanceModelValidationD = self.__commonU.getInstanceNonpolymerValidationInfo(dataContainer) # - # NonpolymerValidationFields = ("rsr", "rscc", "mogul_bonds_rmsz", "mogul_angles_rmsz", "missing_heavy_atom_count") + # NonpolymerValidationFields = ("rsr", "rscc", "mogul_bonds_rmsz", "mogul_angles_rmsz") # logger.debug("Length instanceModelValidationD %d", len(instanceModelValidationD)) # @@ -1704,23 +1704,15 @@ def buildInstanceValidationScores(self, dataContainer, catName, **kwargs): rankD = {} scoreD = {} # -- Get existing interactions or calculate on the fly - if self.__tiP.hasEntry(entryId): - intD = self.__tiP.getInteractions(entryId) - ligandAtomCountD = self.__tiP.getAtomCounts(entryId) + if False and self.__tiP.hasEntry(entryId): + pass + # intD = self.__tiP.getInteractions(entryId) + # ligandAtomCountD = self.__tiP.getAtomCounts(entryId) else: - intD, ligandAtomCountD = self.__commonU.getNonpolymerInstanceNeighbors(dataContainer) - - intTargetD = {} - intNeighborD = {} - intIsBoundD = {} - for asymId, neighborL in intD.items(): - isBound = False - for neighbor in neighborL: - intTargetD.setdefault(asymId, set()).add((neighbor.partnerEntityId, neighbor.partnerAsymId, neighbor.connectType)) - intNeighborD.setdefault((neighbor.partnerEntityId, neighbor.partnerAsymId, neighbor.connectType), []).append(neighbor) - if neighbor.connectType != "non-bonded": - isBound = True - intIsBoundD[asymId] = isBound + # intD, ligandAtomCountD = self.__commonU.getNonpolymerInstanceNeighbors(dataContainer) + ligandAtomCountD = self.__commonU.getLigandAtomCountD(dataContainer) + intIsBoundD = self.__commonU.getLigandNeighborBoundState(dataContainer) + # -- # calculate scores and ranks and find best ranking for (modelId, asymId, altId, compId), vTup in instanceModelValidationD.items(): @@ -1859,41 +1851,16 @@ def __calculateGeometryScore(self, bondsRmsZ, anglesRmsZ, meanD, stdD, loadingD) return geoScore, geoRanking - def buildInstanceTargetInteractions(self, dataContainer, catName, **kwargs): - """Build category rcsb_nonpolymer_instance_target_interactions ... + def buildInstanceTargetNeighbors(self, dataContainer, catName, **kwargs): + """Build category rcsb_target_neighbors ... Example: - loop_ - _rcsb_nonpolymer_instance_target_interactions.ordinal - _rcsb_nonpolymer_instance_target_interactions.entry_id - _rcsb_nonpolymer_instance_target_interactions.model_id - _rcsb_nonpolymer_instance_target_interactions.entity_id - _rcsb_nonpolymer_instance_target_interactions.asym_id - _rcsb_nonpolymer_instance_target_interactions.auth_asym_id - _rcsb_nonpolymer_instance_target_interactions.comp_id - _rcsb_nonpolymer_instance_target_interactions.atom_id - _rcsb_nonpolymer_instance_target_interactions.alt_id - _rcsb_nonpolymer_instance_target_interactions.target_model_id - _rcsb_nonpolymer_instance_target_interactions.target_entity_id - _rcsb_nonpolymer_instance_target_interactions.target_asym_id - _rcsb_nonpolymer_instance_target_interactions.target_seq_id - _rcsb_nonpolymer_instance_target_interactions.target_comp_id - _rcsb_nonpolymer_instance_target_interactions.target_atom_id - _rcsb_nonpolymer_instance_target_interactions.target_is_bound - 1 6TTM 1 2 B A PEG O4 A 1 1 A 270 GLU O N - 2 6TTM 1 3 C A HYO N04 . 1 1 A 119 GLU OE2 N - 3 6TTM 1 4 D A NI NI . 1 1 A 277 HIS NE2 Y - 4 6TTM 1 6 F A EDO O1 . 1 1 A 232 ASP OD2 N - 5 6TTM 1 6 G A EDO C1 . 1 1 A 102 GLU OE2 N - 6 6TTM 1 7 H A SR SR . 1 1 A 101 GLY O Y - 7 6TTM 1 8 I A UNX UNK . 1 1 A 148 ASN O N - 8 6TTM 1 8 J A UNX UNK . 1 1 A 344 LYS NZ N - # + """ logger.debug("Starting with %s %r %r", dataContainer.getName(), catName, kwargs) startTime = time.time() try: - if catName != "rcsb_nonpolymer_instance_target_interactions": + if catName != "rcsb_target_neighbors": return False if not dataContainer.exists("entry"): return False @@ -1910,27 +1877,22 @@ def buildInstanceTargetInteractions(self, dataContainer, catName, **kwargs): asymIdD = self.__commonU.getInstanceEntityMap(dataContainer) asymAuthIdD = self.__commonU.getAsymAuthIdMap(dataContainer) # -- Get existing interactions or calculate on the fly - if self.__tiP.hasEntry(entryId): - intD = self.__tiP.getInteractions(entryId) + # TODO + if False and self.__tiP.hasEntry(entryId): + # intD = self.__tiP.getInteractions(entryId) + pass else: - intD, _ = self.__commonU.getNonpolymerInstanceNeighborInfo(dataContainer) - - # intD[asymId for each ligand] -> [LigandTargetInstance(),] - intTargetD = {} - intNeighborD = {} - intIsBoundD = {} - for asymId, neighborL in intD.items(): - isBound = False - for neighbor in neighborL: - intTargetD.setdefault(asymId, set()).add((neighbor.partnerEntityId, neighbor.partnerAsymId, neighbor.connectType)) - intNeighborD.setdefault(asymId, {}).setdefault((neighbor.partnerEntityId, neighbor.partnerAsymId, neighbor.connectType), []).append(neighbor) - if neighbor.connectType != "non-bonded": - isBound = True - intIsBoundD[asymId] = isBound - # - for asymId, nS in intTargetD.items(): - for (partnerEntityId, partnerAsymId, pConnectType) in nS: - neighbor = intNeighborD[asymId][(partnerEntityId, partnerAsymId, pConnectType)][0] + ligandIndexD = self.__commonU.getLigandNeighborIndex(dataContainer) + nearestNeighborL = self.__commonU.getNearestNeighborList(dataContainer) + # + logger.debug("%s (%d) ligandIndexD %r", entryId, len(nearestNeighborL), ligandIndexD) + # + for asymId, nD in ligandIndexD.items(): + for (partnerAsymId, partnerAuthSeqId), nIndex in nD.items(): + logger.debug("%s pAsym %r pAuthSeqId %r nIndex %d", entryId, partnerAsymId, partnerAuthSeqId, nIndex) + # + neighbor = nearestNeighborL[nIndex] + # neighbor = intNeighborD[asymId][(partnerEntityId, partnerAsymId, pConnectType)][0] # entityId = asymIdD[asymId] authAsymId = asymAuthIdD[asymId] @@ -1946,11 +1908,12 @@ def buildInstanceTargetInteractions(self, dataContainer, catName, **kwargs): cObj.setValue(neighbor.ligandAltId if neighbor.ligandAltId and neighbor.ligandAltId not in ["?"] else ".", "alt_id", ii) cObj.setValue(neighbor.ligandCompId, "comp_id", ii) # - cObj.setValue(neighbor.partnerEntityId, "target_model_id", ii) + cObj.setValue(neighbor.partnerModelId, "target_model_id", ii) cObj.setValue(neighbor.partnerEntityId, "target_entity_id", ii) cObj.setValue(neighbor.partnerAsymId, "target_asym_id", ii) cObj.setValue(neighbor.partnerCompId, "target_comp_id", ii) cObj.setValue(neighbor.partnerSeqId, "target_seq_id", ii) + cObj.setValue(neighbor.partnerAuthSeqId, "target_auth_seq_id", ii) cObj.setValue(neighbor.partnerAtomId, "target_atom_id", ii) cObj.setValue("N" if neighbor.connectType == "non-bonded" else "Y", "target_is_bound", ii) cObj.setValue("%.3f" % neighbor.distance, "distance", ii) @@ -1964,3 +1927,84 @@ def buildInstanceTargetInteractions(self, dataContainer, catName, **kwargs): except Exception as e: logger.exception("For %s %r failing with %s", dataContainer.getName(), catName, str(e)) return False + + def buildInstanceLigandNeighbors(self, dataContainer, catName, **kwargs): + """Build category rcsb_target_neighbors ... + + Example: + + """ + logger.debug("Starting with %s %r %r", dataContainer.getName(), catName, kwargs) + startTime = time.time() + try: + if catName != "rcsb_ligand_neighbors": + return False + if not dataContainer.exists("entry"): + return False + # + eObj = dataContainer.getObj("entry") + entryId = eObj.getValue("id", 0) + # + # Create the new target category + if not dataContainer.exists(catName): + dataContainer.append(DataCategory(catName, attributeNameList=self.__dApi.getAttributeNameList(catName))) + cObj = dataContainer.getObj(catName) + ii = cObj.getRowCount() + # + asymIdD = self.__commonU.getInstanceEntityMap(dataContainer) + asymAuthIdD = self.__commonU.getAsymAuthIdMap(dataContainer) + # -- Get existing interactions or calculate on the fly + # TODO + if False and self.__tiP.hasEntry(entryId): + # intD = self.__tiP.getInteractions(entryId) + pass + else: + targetIndexD = self.__commonU.getTargetNeighborIndex(dataContainer) + nearestNeighborL = self.__commonU.getNearestNeighborList(dataContainer) + # + logger.debug("%s (%d) targetIndexD %r", entryId, len(nearestNeighborL), targetIndexD) + # + for (asymId, authSeqId), nD in targetIndexD.items(): + for ligandAsymId, nIndex in nD.items(): + logger.debug("%s asymId %s authSeqId %s ligandAsym %rnIndex %d", entryId, asymId, authSeqId, ligandAsymId, nIndex) + # + neighbor = nearestNeighborL[nIndex] + # + entityId = asymIdD[asymId] + authAsymId = asymAuthIdD[asymId] + # + cObj.setValue(ii + 1, "ordinal", ii) + cObj.setValue(neighbor.ligandModelId, "model_id", ii) + cObj.setValue(entryId, "entry_id", ii) + cObj.setValue(entityId, "entity_id", ii) + cObj.setValue(asymId, "asym_id", ii) + cObj.setValue(authAsymId, "auth_asym_id", ii) + cObj.setValue(neighbor.partnerCompId, "comp_id", ii) + # + cObj.setValue(neighbor.partnerSeqId, "seq_id", ii) + cObj.setValue(neighbor.partnerAuthSeqId, "auth_seq_id", ii) + + cObj.setValue(neighbor.partnerAtomId, "atom_id", ii) + cObj.setValue(neighbor.partnerAltId if neighbor.partnerAltId and neighbor.partnerAltId not in ["?"] else ".", "alt_id", ii) + # + cObj.setValue(neighbor.ligandModelId, "ligand_model_id", ii) + cObj.setValue(asymIdD[neighbor.ligandAsymId], "ligand_entity_id", ii) + cObj.setValue(neighbor.ligandAsymId, "ligand_asym_id", ii) + cObj.setValue(neighbor.ligandCompId, "ligand_comp_id", ii) + cObj.setValue(neighbor.ligandAtomId, "ligand_atom_id", ii) + cObj.setValue(neighbor.ligandAltId, "ligand_alt_id", ii) + cObj.setValue(neighbor.ligandAltId if neighbor.ligandAltId and neighbor.ligandAltId not in ["?"] else ".", "ligand_alt_id", ii) + cObj.setValue("N" if neighbor.connectType == "non-bonded" else "Y", "ligand_is_bound", ii) + cObj.setValue("%.3f" % neighbor.distance, "distance", ii) + # ---- + ii += 1 + # + ## + + # + endTime = time.time() + logger.debug("Completed at %s (%.4f seconds)", time.strftime("%Y %m %d %H:%M:%S", time.localtime()), endTime - startTime) + return True + except Exception as e: + logger.exception("For %s %r failing with %s", dataContainer.getName(), catName, str(e)) + return False diff --git a/rcsb/utils/dictionary/TargetInteractionProvider.py b/rcsb/utils/dictionary/NeighborInteractionProvider.py similarity index 78% rename from rcsb/utils/dictionary/TargetInteractionProvider.py rename to rcsb/utils/dictionary/NeighborInteractionProvider.py index da04e57..51a338b 100644 --- a/rcsb/utils/dictionary/TargetInteractionProvider.py +++ b/rcsb/utils/dictionary/NeighborInteractionProvider.py @@ -1,12 +1,12 @@ ## -# File: TargetInteractionProvider.py +# File: NeighborInteractionProvider.py # Date: 17-Feb-2021 jdw # # Updated: # ## """ -Generators and accessors for non-polymer instance target interactions +Generators and accessors for target and ligand neighbor interactions """ @@ -26,7 +26,7 @@ class TargetInteractionWorker(object): """A skeleton class that implements the interface expected by the multiprocessing - for calculating non-polymer instance target interactions -- + for calculating non-polymer instance ligand and target neighbor interactions -- """ def __init__(self, repositoryProviderObj, **kwargs): @@ -48,8 +48,8 @@ def build(self, dataList, procName, optionsD, workingDir): dataContainerList = self.__rpP.getContainerList([locatorObj]) for dataContainer in dataContainerList: entryId = dataContainer.getName() - instD, countD = self.__buildTargetInteractions(procName, dataContainer, distLimit) - retList.append((entryId, instD, countD)) + rD = self.__getNeighborInfo(procName, dataContainer, distLimit) + retList.append((entryId, rD)) # successList = sorted(set(dataList) - set(failList)) if failList: @@ -61,17 +61,18 @@ def build(self, dataList, procName, optionsD, workingDir): # return successList, retList, diagList - def __buildTargetInteractions(self, procName, dataContainer, distLimit): + def __getNeighborInfo(self, procName, dataContainer, distLimit): """Internal method return a dictionary target interactions.""" rD = {} try: - rD, countD = self.__commonU.getNonpolymerInstanceNeighborInfo(dataContainer, distLimit=distLimit) + rD = self.__commonU.getNeighborInfo(dataContainer, distLimit=distLimit) + except Exception as e: logger.exception("%s failing with %s", procName, str(e)) - return rD, countD + return rD -class TargetInteractionProvider(object): +class NeighborInteractionProvider(object): """Generators and accessors for non-polymer instance target interactions.""" def __init__(self, cfgOb, configName, cachePath, **kwargs): @@ -81,7 +82,7 @@ def __init__(self, cfgOb, configName, cachePath, **kwargs): self.__configName = configName self.__cachePath = cachePath self.__fileLimit = kwargs.get("fileLimit", None) - self.__dirPath = os.path.join(cachePath, "target-interactions") + self.__dirPath = os.path.join(cachePath, "neighbor-interactions") self.__numProc = kwargs.get("numProc", 2) self.__chunkSize = kwargs.get("chunkSize", 10) useCache = kwargs.get("useCache", True) @@ -89,35 +90,53 @@ def __init__(self, cfgOb, configName, cachePath, **kwargs): # - Configuration for stash services - # Local target directory name to be stashed. (subdir of dirPath) # - self.__stashDir = "nonpolymer-target-interactions" + self.__stashDir = "ligand-target-neighbors" # self.__mU = MarshalUtil(workPath=self.__dirPath) self.__rpP = RepositoryProvider(cfgOb=self.__cfgOb, numProc=self.__numProc, fileLimit=self.__fileLimit, cachePath=self.__cachePath) - self.__targetD = self.__reload(fmt="pickle", useCache=useCache) + self.__neighborD = self.__reload(fmt="pickle", useCache=useCache) # def testCache(self, minCount=0): try: if minCount == 0: return True - if self.__targetD and minCount and len(self.__targetD["interactions"]) >= minCount: - logger.info("Target interactions (%d) created %r version %r", len(self.__targetD["interactions"]), self.__targetD["created"], self.__targetD["version"]) + if self.__neighborD and minCount and len(self.__neighborD["entries"]) >= minCount: + logger.info( + "Target neighbor data for (%d) entries created %r version %r", len(self.__neighborD["entries"]), self.__neighborD["created"], self.__neighborD["version"] + ) return True except Exception: pass return False - def getInteractions(self, entryId): - """Return the target interactions for the non-polymer instances for the input entry. + def getLigandNeighborIndex(self, entryId): + """Return the target neighbors for the non-polymer instances for the input entry. Args: entryId (str): entry identifier Returns: - (dict): {asymId: [LigandTargetInstance(), LigandTargetInstance(), ...]} + (dict): {ligandAsymId: {(targetAsymId, targetAuthSeqId): nnIndex1, (): nnIndex2} + """ + try: + return self.__neighborD["entries"][entryId.upper()]["ligandNeighborIndexD"] + except Exception: + pass + return {} + + def getTargetNeighborIndex(self, entryId): + """Return the ligand neighbors for the polymer or branched entity instances in the input entry. + + Args: + entryId (str): entry identifier + + Returns: + (dict): {(targetAsymId, targetAuthSeqId): {(ligandAsymId): nnIndex1, (): nnIndex2} + """ try: - return self.__targetD["interactions"][entryId.upper()] + return self.__neighborD["entries"][entryId.upper()]["targetNeighborIndexD"] except Exception: pass return {} @@ -132,7 +151,7 @@ def getAtomCounts(self, entryId): (dict): {asymId: {'FL': count, 'altA': occ*count, 'altB': occ*count, ... }} """ try: - return self.__targetD["atomCounts"][entryId.upper()] + return self.__neighborD["entries"][entryId.upper()]["ligandAtomCountD"] except Exception: pass return {} @@ -147,7 +166,7 @@ def hasEntry(self, entryId): (bool): True if entry is in the cache or False otherwise """ try: - return entryId in self.__targetD["interactions"] + return entryId in self.__neighborD["entries"] except Exception: pass return False @@ -159,7 +178,7 @@ def getEntries(self): (list): [entryId, entryId, ... ] """ try: - return list(self.__targetD["interactions"].keys()) + return list(self.__neighborD["entries"].keys()) except Exception: pass return [] @@ -179,41 +198,42 @@ def generate(self, distLimit=5.0, updateOnly=False, fmt="pickle", indent=0): ok = False try: tS = time.strftime("%Y %m %d %H:%M:%S", time.localtime()) - tD, cD = self.__calculateNeighbors(distLimit=distLimit, numProc=self.__numProc, chunkSize=self.__chunkSize, updateOnly=updateOnly) - self.__targetD = {"version": self.__version, "created": tS, "interactions": tD, "atomCounts": cD} + tD = self.__calculateNeighbors(distLimit=distLimit, numProc=self.__numProc, chunkSize=self.__chunkSize, updateOnly=updateOnly) + self.__neighborD = {"version": self.__version, "created": tS, "entries": tD} kwargs = {"indent": indent} if fmt == "json" else {} targetFilePath = self.__getTargetFilePath(fmt=fmt) - ok = self.__mU.doExport(targetFilePath, self.__targetD, fmt=fmt, **kwargs) + ok = self.__mU.doExport(targetFilePath, self.__neighborD, fmt=fmt, **kwargs) logger.info("Wrote %r status %r", targetFilePath, ok) except Exception as e: logger.exception("Failing with %s", str(e)) return ok def reload(self, fmt="pickle"): - self.__targetD = self.__reload(fmt=fmt, useCache=True) - return self.__targetD is not None + self.__neighborD = self.__reload(fmt=fmt, useCache=True) + return self.__neighborD is not None def __reload(self, fmt="pickle", useCache=True): """Reload from the current cache file.""" try: targetFilePath = self.__getTargetFilePath(fmt=fmt) tS = time.strftime("%Y %m %d %H:%M:%S", time.localtime()) - targetD = {"version": self.__version, "created": tS, "interactions": {}, "atomCounts": {}} + neighborD = {"version": self.__version, "created": tS, "entries": {}} logger.debug("useCache %r targetFilePath %r", useCache, targetFilePath) # if useCache and self.__mU.exists(targetFilePath): - targetD = self.__mU.doImport(targetFilePath, fmt=fmt) - for _, neighborD in targetD["interactions"].items(): - for asymId in neighborD: - neighborD[asymId] = [LigandTargetInstance(*neighbor) for neighbor in neighborD[asymId]] + neighborD = self.__mU.doImport(targetFilePath, fmt=fmt) + # TODO + if True or fmt != "pickle": + for _, nD in neighborD["entries"].items(): + nD["nearestNeighbors"] = [LigandTargetInstance(*neighbor) for neighbor in nD["nearestNeighbors"]] except Exception as e: logger.exception("Failing with %s", str(e)) # - return targetD + return neighborD def __getTargetFilePath(self, fmt="pickle"): ext = "pic" if fmt == "pickle" else "json" - pth = os.path.join(self.__dirPath, "nonpolymer-target-interactions", "inst-target-interactions." + ext) + pth = os.path.join(self.__dirPath, "ligand-target-neighbors", "neighbor-data." + ext) return pth def __calculateNeighbors(self, distLimit=5.0, numProc=2, chunkSize=10, updateOnly=False): @@ -230,15 +250,13 @@ def __calculateNeighbors(self, distLimit=5.0, numProc=2, chunkSize=10, updateOnl contentType = "pdbx" mergeContent = None rD = {} - cD = {} exD = {} # # updateOnly - will reuse any existing data loaded when this is instantiated # otherwise the cache context is cleared before the calculation. if updateOnly: exD = {k: True for k in self.getEntries()} - rD = self.__targetD["interactions"] if "interactions" in self.__targetD else {} - cD = self.__targetD["atomCounts"] if "atomCounts" in self.__targetD else {} + rD = self.__neighborD["entries"] if "entries" in self.__neighborD else {} # locatorObjList = self.__rpP.getLocatorObjList(contentType=contentType, mergeContentTypes=mergeContent, excludeIds=exD) logger.info("Starting with %d numProc %d updateOnly (%r)", len(locatorObjList), self.__numProc, updateOnly) @@ -252,12 +270,11 @@ def __calculateNeighbors(self, distLimit=5.0, numProc=2, chunkSize=10, updateOnl if failList: logger.info("Target interaction build failures (%d): %r", len(failList), failList) # - for (entryId, tD, qD) in resultList[0]: - rD[entryId] = tD - cD[entryId] = qD + for (entryId, nD) in resultList[0]: + rD[entryId] = nD # - logger.info("Completed with multi-proc status %r failures %r total entry interactions (%d) atom counts (%d)", ok, len(failList), len(rD), len(cD)) - return rD, cD + logger.info("Completed with multi-proc status %r failures %r total entries with data (%d)", ok, len(failList), len(rD)) + return rD def toStash(self): ok = False @@ -341,8 +358,8 @@ def __fromStash(self, url, stashRemoteDirPath, userName=None, password=None, rem def convert(self, fmt1="json", fmt2="pickle"): # targetFilePath = self.__getTargetFilePath(fmt=fmt1) - self.__targetD = self.__mU.doImport(targetFilePath, fmt=fmt1) + self.__neighborD = self.__mU.doImport(targetFilePath, fmt=fmt1) # targetFilePath = self.__getTargetFilePath(fmt=fmt2) - ok = self.__mU.doExport(targetFilePath, self.__targetD, fmt=fmt2) + ok = self.__mU.doExport(targetFilePath, self.__neighborD, fmt=fmt2) return ok diff --git a/rcsb/utils/dictionary/TargetInteractionWorkflow.py b/rcsb/utils/dictionary/NeighborInteractionWorkflow.py similarity index 80% rename from rcsb/utils/dictionary/TargetInteractionWorkflow.py rename to rcsb/utils/dictionary/NeighborInteractionWorkflow.py index 0b00c37..bc8eae9 100644 --- a/rcsb/utils/dictionary/TargetInteractionWorkflow.py +++ b/rcsb/utils/dictionary/NeighborInteractionWorkflow.py @@ -1,5 +1,5 @@ ## -# File: TargetInteractionWorkflow.py +# File: NeighborInteractionWorkflow.py # Author: J. Westbrook # Date: 18-Feb-2021 # @@ -8,7 +8,7 @@ # ## """ -Worflow for generating and stashing non-polymer instance target interactions +Worflow for generating and stashing ligand and target neighbor interactions """ @@ -20,7 +20,7 @@ import logging import os -from rcsb.utils.dictionary.TargetInteractionProvider import TargetInteractionProvider +from rcsb.utils.dictionary.NeighborInteractionProvider import NeighborInteractionProvider from rcsb.utils.config.ConfigUtil import ConfigUtil HERE = os.path.abspath(os.path.dirname(__file__)) @@ -30,7 +30,7 @@ logger = logging.getLogger() -class TargetInteractionWorkflow(object): +class NeighborInteractionWorkflow(object): def __init__(self, **kwargs): # - edit as needed - self.__configName = kwargs.get("configName", "site_info_remote_configuration") @@ -43,7 +43,7 @@ def __init__(self, **kwargs): # self.__cfgOb = ConfigUtil(configPath=self.__configPath, defaultSectionName=self.__configName, mockTopPath=self.__mockTopPath) logger.info("Configuration file path %s", self.__configPath) - self.__tiP = TargetInteractionProvider(self.__cfgOb, self.__configName, self.__cachePath, useCache=self.__useCache, numProc=self.__numProc, chunkSize=self.__chunkSize) + self.__tiP = NeighborInteractionProvider(self.__cfgOb, self.__configName, self.__cachePath, useCache=self.__useCache, numProc=self.__numProc, chunkSize=self.__chunkSize) def update(self, incremental=True): ok = self.__tiP.generate(distLimit=5.0, updateOnly=incremental, fmt="pickle") @@ -65,5 +65,5 @@ def convert(self, fmt1="json", fmt2="pickle"): if __name__ == "__main__": - tiWf = TargetInteractionWorkflow() + tiWf = NeighborInteractionWorkflow() tiWf.update(incremental=False) diff --git a/rcsb/utils/dictionary/__init__.py b/rcsb/utils/dictionary/__init__.py index ededfd8..ecd2e55 100644 --- a/rcsb/utils/dictionary/__init__.py +++ b/rcsb/utils/dictionary/__init__.py @@ -2,4 +2,4 @@ __author__ = "John Westbrook" __email__ = "john.westbrook@rcsb.org" __license__ = "Apache 2.0" -__version__ = "0.20" +__version__ = "0.21" diff --git a/rcsb/utils/tests-dictionary/testDictMethodRunner.py b/rcsb/utils/tests-dictionary/testDictMethodRunner.py index 151db78..d9ad876 100644 --- a/rcsb/utils/tests-dictionary/testDictMethodRunner.py +++ b/rcsb/utils/tests-dictionary/testDictMethodRunner.py @@ -79,6 +79,8 @@ def __runContentType(self, contentType, mockLength, mergeContent): self.assertGreaterEqual(len(locatorObjList), mockLength) for container in containerList: cName = container.getName() + # if cName not in ["6TTM"]: + # continue logger.debug("Processing container %s", cName) dmh.apply(container) savePath = os.path.join(HERE, "test-output", cName + "-with-method.cif") diff --git a/rcsb/utils/tests-dictionary/testTargetInteractionProvider.py b/rcsb/utils/tests-dictionary/testNeighborInteractionProvider.py similarity index 69% rename from rcsb/utils/tests-dictionary/testTargetInteractionProvider.py rename to rcsb/utils/tests-dictionary/testNeighborInteractionProvider.py index 85fd7f4..64f0fc3 100644 --- a/rcsb/utils/tests-dictionary/testTargetInteractionProvider.py +++ b/rcsb/utils/tests-dictionary/testNeighborInteractionProvider.py @@ -1,5 +1,5 @@ ## -# File: TargetInteractionProviderTests.py +# File: NeighborInteractionProviderTests.py # Author: J. Westbrook # Date: 18-Feb-2021 # @@ -23,7 +23,7 @@ import unittest -from rcsb.utils.dictionary.TargetInteractionProvider import TargetInteractionProvider +from rcsb.utils.dictionary.NeighborInteractionProvider import NeighborInteractionProvider from rcsb.utils.config.ConfigUtil import ConfigUtil HERE = os.path.abspath(os.path.dirname(__file__)) @@ -33,7 +33,7 @@ logger = logging.getLogger() -class TargetInteractionProviderTests(unittest.TestCase): +class NeighborInteractionProviderTests(unittest.TestCase): skipFlag = True def setUp(self): @@ -50,9 +50,9 @@ def tearDown(self): endTime = time.time() logger.info("Completed %s at %s (%.4f seconds)", self.id(), time.strftime("%Y %m %d %H:%M:%S", time.localtime()), endTime - self.__startTime) - def testTargetInteractionProviderBootstrap(self): + def testNeighborInteractionProviderBootstrap(self): try: - tiP = TargetInteractionProvider(self.__cfgOb, self.__configName, self.__cachePath, useCache=False) + tiP = NeighborInteractionProvider(self.__cfgOb, self.__configName, self.__cachePath, useCache=False) ok = tiP.generate(distLimit=5.0, updateOnly=False, fmt="pickle") self.assertTrue(ok) ok = tiP.generate(distLimit=5.0, updateOnly=True, fmt="pickle") @@ -62,18 +62,9 @@ def testTargetInteractionProviderBootstrap(self): ok = tiP.testCache(minCount=85) self.assertTrue(ok) # - tiP = TargetInteractionProvider(self.__cfgOb, self.__configName, self.__cachePath, useCache=True) + tiP = NeighborInteractionProvider(self.__cfgOb, self.__configName, self.__cachePath, useCache=True) ok = tiP.testCache(minCount=85) self.assertTrue(ok) - for entryId in tiP.getEntries(): - intD = tiP.getInteractions(entryId) - for asymId, neighborL in intD.items(): - tD = {} - for neighbor in neighborL: - logger.debug("%s %s %r", entryId, asymId, neighbor) - tD.setdefault(asymId, set()).add((neighbor.partnerEntityId, neighbor.partnerAsymId, neighbor.connectType)) - if len(tD) > 1: - logger.info("%s %s (%d) %r", entryId, asymId, len(tD), tD) except Exception as e: logger.exception("Failing with %s", str(e)) self.fail() @@ -82,7 +73,7 @@ def testTargetInteractionProviderBootstrap(self): def testStashRemote(self): try: # - tiP = TargetInteractionProvider(self.__cfgOb, self.__configName, self.__cachePath, useCache=True) + tiP = NeighborInteractionProvider(self.__cfgOb, self.__configName, self.__cachePath, useCache=True) ok = tiP.testCache() self.assertTrue(ok) ok = tiP.toStash() @@ -100,7 +91,7 @@ def testStashRemote(self): def targetInteractionSuite(): suiteSelect = unittest.TestSuite() - suiteSelect.addTest(TargetInteractionProviderTests("testTargetInteractionProviderBootstrap")) + suiteSelect.addTest(NeighborInteractionProviderTests("testNeighborInteractionProviderBootstrap")) return suiteSelect diff --git a/rcsb/utils/tests-dictionary/testTargetInteractionWorkflow.py b/rcsb/utils/tests-dictionary/testNeighborInteractionWorkflow.py similarity index 82% rename from rcsb/utils/tests-dictionary/testTargetInteractionWorkflow.py rename to rcsb/utils/tests-dictionary/testNeighborInteractionWorkflow.py index 6b24c80..73396bb 100644 --- a/rcsb/utils/tests-dictionary/testTargetInteractionWorkflow.py +++ b/rcsb/utils/tests-dictionary/testNeighborInteractionWorkflow.py @@ -1,5 +1,5 @@ ## -# File: TargetInteractionWorkflowTests.py +# File: NeighborInteractionWorkflowTests.py # Author: J. Westbrook # Date: 21-Feb-2021 # @@ -8,7 +8,7 @@ # ## """ -Tests for target interaction generation/update workflow +Tests for ligand and target interaction generation/update workflow """ __docformat__ = "restructuredtext en" @@ -21,7 +21,7 @@ import time import unittest -from rcsb.utils.dictionary.TargetInteractionWorkflow import TargetInteractionWorkflow +from rcsb.utils.dictionary.NeighborInteractionWorkflow import NeighborInteractionWorkflow HERE = os.path.abspath(os.path.dirname(__file__)) TOPDIR = os.path.dirname(os.path.dirname(os.path.dirname(HERE))) @@ -30,7 +30,7 @@ logger = logging.getLogger() -class TargetInteractionWorkflowTests(unittest.TestCase): +class NeighborInteractionWorkflowTests(unittest.TestCase): skipFlag = True def setUp(self): @@ -48,7 +48,7 @@ def tearDown(self): def testTargetInteractionUpdate(self): try: - tiWf = TargetInteractionWorkflow( + tiWf = NeighborInteractionWorkflow( configPath=self.__configPath, configName=self.__configName, cachePath=self.__cachePath, @@ -66,7 +66,7 @@ def testTargetInteractionUpdate(self): @unittest.skipIf(skipFlag, "Internal test") def testTargetInteractionRestore(self): try: - tiWf = TargetInteractionWorkflow( + tiWf = NeighborInteractionWorkflow( configPath=self.__configPath, configName=self.__configName, cachePath=self.__cachePath, @@ -84,8 +84,8 @@ def testTargetInteractionRestore(self): def targetInteractionSuite(): suiteSelect = unittest.TestSuite() - suiteSelect.addTest(TargetInteractionWorkflowTests("testTargetInteractionUpdate")) - suiteSelect.addTest(TargetInteractionWorkflowTests("testTargetInteractionRestore")) + suiteSelect.addTest(NeighborInteractionWorkflowTests("testTargetInteractionUpdate")) + suiteSelect.addTest(NeighborInteractionWorkflowTests("testTargetInteractionRestore")) return suiteSelect