From de8a89d2af7c1d297500214fe72dd39ea1bbaa2e Mon Sep 17 00:00:00 2001 From: Weslley Morellato Bueno Date: Thu, 2 May 2024 06:47:04 -0400 Subject: [PATCH] Created link review section and table. Integration with mol* --- wwpdb/apps/ann_tasks_v2/report/PdbxReport.py | 11 +++- .../report/PdbxReportDepictBootstrap.py | 21 +++++++- .../ann_tasks_v2/report/styles/LinksReport.py | 39 ++++++++++++++ .../ann_tasks_v2/report/styles/ModelReport.py | 38 -------------- .../apps/ann_tasks_v2/report/styles/PdbxIo.py | 51 +++++++++++++++++++ .../webapp/CommonTasksWebAppWorker.py | 19 +++++++ .../webapp/ReviewDataWebAppWorker.py | 1 + 7 files changed, 139 insertions(+), 41 deletions(-) create mode 100644 wwpdb/apps/ann_tasks_v2/report/styles/LinksReport.py diff --git a/wwpdb/apps/ann_tasks_v2/report/PdbxReport.py b/wwpdb/apps/ann_tasks_v2/report/PdbxReport.py index 7174625..6e45b5e 100644 --- a/wwpdb/apps/ann_tasks_v2/report/PdbxReport.py +++ b/wwpdb/apps/ann_tasks_v2/report/PdbxReport.py @@ -20,12 +20,13 @@ import sys import traceback -from wwpdb.apps.ann_tasks_v2.report.styles.PdbxIo import PdbxReportIo, PdbxGeometryReportIo, PdbxXrayExpReportIo +from wwpdb.apps.ann_tasks_v2.report.styles.PdbxIo import PdbxReportIo, PdbxGeometryReportIo, PdbxXrayExpReportIo, PdbxLinksReportIo from mmcif_utils.style.PdbxGeometryReportCategoryStyle import PdbxGeometryReportCategoryStyle from wwpdb.apps.ann_tasks_v2.report.PdbxReportDepictBootstrap import PdbxReportDepictBootstrap from wwpdb.apps.ann_tasks_v2.report.styles.DCCReport import PdbxXrayExpReportCategoryStyle from wwpdb.apps.ann_tasks_v2.report.styles.ModelReport import PdbxReportCategoryStyle +from wwpdb.apps.ann_tasks_v2.report.styles.LinksReport import PdbxLinksReportCategoryStyle class PdbxReport(object): @@ -109,6 +110,12 @@ def makeTabularReport(self, filePath=None, contentType=None, idCode=None, layout dd = self.doReport(contentType) rdd = PdbxReportDepictBootstrap(styleObject=PdbxGeometryReportCategoryStyle(), includePath=includePath, verbose=self.__verbose, log=self.__lfh) oL = rdd.render(dd, style=layout, leadingHtmlL=leadingHtmlL, trailingHtmlL=trailingHtmlL) + + if contentType in ["links-report"]: + self.setFilePath(filePath, fileFormat=fileFormat, idCode=idCode) + dd = self.doReport(contentType) + rdd = PdbxReportDepictBootstrap(styleObject=PdbxLinksReportCategoryStyle(), includePath=includePath, verbose=self.__verbose, log=self.__lfh) + oL = rdd.render(dd, style=layout, leadingHtmlL=leadingHtmlL, trailingHtmlL=trailingHtmlL) if self.__debug: self.__lfh.write("+PdbxReport.makeTabularReport - generated HTML \n%s\n" % "\n".join(oL)) @@ -173,6 +180,8 @@ def doReport(self, contentType="model"): pdbxR = PdbxGeometryReportIo(verbose=self.__verbose, log=self.__lfh) elif contentType == "dcc-report": pdbxR = PdbxXrayExpReportIo(verbose=self.__verbose, log=self.__lfh) + elif contentType == "links-report": + pdbxR = PdbxLinksReportIo(verbose=self.__verbose, log=self.__lfh) pdbxR.setFilePath(localPath, idCode=None) pdbxR.get() diff --git a/wwpdb/apps/ann_tasks_v2/report/PdbxReportDepictBootstrap.py b/wwpdb/apps/ann_tasks_v2/report/PdbxReportDepictBootstrap.py index 8ba09a0..4368670 100644 --- a/wwpdb/apps/ann_tasks_v2/report/PdbxReportDepictBootstrap.py +++ b/wwpdb/apps/ann_tasks_v2/report/PdbxReportDepictBootstrap.py @@ -28,6 +28,7 @@ class PdbxReportDepictBootstrap(PdbxDepictBootstrapBase): This version uses Bootstrap CSS framework constructs. """ + MAX_LINES = 12 def __init__(self, styleObject=None, includePath=None, verbose=False, log=sys.stderr): """ @@ -95,7 +96,6 @@ def __setup(self): # ('citation','Primary citation','column-wise'), ("pdbx_validate_close_contact", "Close contacts", "row-wise"), ("pdbx_validate_symm_contact", "Close symmetry contacts", "row-wise"), - ("struct_conn", "Links", "row-wise"), # ('symmetry', 'Symmetry', 'row-wise'), # ('cell', 'Cell constants', 'row-wise'), # ('exptl_crystal_grow', 'Crystallization details', 'row-wise'), @@ -131,6 +131,10 @@ def __setup(self): ("pdbx_validate_polymer_linkage", "Polymer linkages", "row-wise"), ("pdbx_validate_chiral", "Chirality exceptions", "row-wise"), ] + elif self.__st.getStyleId() in ["PDBX_LINKS_REPORT_V1"]: + self.__reportCategories = [ + ("struct_conn", "", "row-wise"), + ] def render(self, eD, style="tabs", leadingHtmlL=None, trailingHtmlL=None): """ """ @@ -322,7 +326,11 @@ def __doRenderAccordion(self, eD): oL.append('

%s

' % (idTop, idSection, catNameAbbrev)) oL.append("") oL.append('
' % (idSection, active)) - oL.append('
') + + if len(cD[catName]) > PdbxReportDepictBootstrap.MAX_LINES: + oL.append('
') + else: + oL.append('
') # oL.append('') if catStyle == "column-wise": @@ -526,6 +534,15 @@ def __markupRow(self, catName, rD): itemValue, itemValue, ) + + if catName == "struct_conn": + itemName = "_struct_conn.id" + if itemName in rD: + itemValue = rD[itemName] + rD[itemName] = '%s' % ( + itemValue.strip(), + itemValue, + ) def __attributePart(self, name): i = name.find(".") diff --git a/wwpdb/apps/ann_tasks_v2/report/styles/LinksReport.py b/wwpdb/apps/ann_tasks_v2/report/styles/LinksReport.py new file mode 100644 index 0000000..5861ed9 --- /dev/null +++ b/wwpdb/apps/ann_tasks_v2/report/styles/LinksReport.py @@ -0,0 +1,39 @@ +""" +Report style details for PDBx struct_conn category. + +""" + + +from mmcif_utils.style.PdbxCategoryStyleBase import PdbxCategoryStyleBase + + +class PdbxLinksReportCategoryStyle(PdbxCategoryStyleBase): + _styleId = "PDBX_LINKS_REPORT_V1" + _categoryInfo = [ + ("struct_conn", "table"), + ] + _cDict = { + "struct_conn": [ + ('_struct_conn.id', '%s', 'str', ''), + ("_struct_conn.pdbx_leaving_atom_flag", "%s", "str", ""), + ("_struct_conn.ptnr1_auth_asym_id", "%s", "str", ""), + ("_struct_conn.ptnr1_auth_comp_id", "%s", "str", ""), + ("_struct_conn.ptnr1_auth_seq_id", "%s", "str", ""), + ("_struct_conn.ptnr1_symmetry", "%s", "str", ""), + ("_struct_conn.ptnr2_auth_asym_id", "%s", "str", ""), + ("_struct_conn.ptnr2_auth_comp_id", "%s", "str", ""), + ("_struct_conn.ptnr2_auth_seq_id", "%s", "str", ""), + ("_struct_conn.ptnr2_symmetry", "%s", "str", ""), + ("_struct_conn.pdbx_dist_value", "%s", "str", ""), + ], + } + _excludeList = [] + _suppressList = [] + # + + def __init__(self): + super(PdbxLinksReportCategoryStyle, self).__init__(styleId=PdbxLinksReportCategoryStyle._styleId, + catFormatL=PdbxLinksReportCategoryStyle._categoryInfo, + catItemD=PdbxLinksReportCategoryStyle._cDict, + excludeList=PdbxLinksReportCategoryStyle._excludeList, + suppressList=PdbxLinksReportCategoryStyle._suppressList) diff --git a/wwpdb/apps/ann_tasks_v2/report/styles/ModelReport.py b/wwpdb/apps/ann_tasks_v2/report/styles/ModelReport.py index 200eb7e..5ad4a80 100644 --- a/wwpdb/apps/ann_tasks_v2/report/styles/ModelReport.py +++ b/wwpdb/apps/ann_tasks_v2/report/styles/ModelReport.py @@ -109,7 +109,6 @@ class PdbxReportCategoryStyle(PdbxCategoryStyleBase): ("struct_conf", "table"), ("struct_conf_type", "table"), ("pdbx_struct_mod_residue", "table"), - ("struct_conn", "table"), ("struct_conn_type", "table"), ("struct_ncs_oper", "table"), ("struct_sheet", "table"), @@ -1016,43 +1015,6 @@ class PdbxReportCategoryStyle(PdbxCategoryStyleBase): ("_pdbx_struct_mod_residue.parent_comp_id", "%s", "str", ""), ("_pdbx_struct_mod_residue.details", "%s", "str", ""), ], - "struct_conn": [ - # ('_struct_conn.id', '%s', 'str', ''), - ("_struct_conn.conn_type_id", "%s", "str", ""), - ("_struct_conn.pdbx_dist_value", "%s", "str", ""), - # ('_struct_conn.pdbx_PDB_id', '%s', 'str', ''), - # ('_struct_conn.pdbx_ptnr1_mod_name', '%s', 'str', ''), - # ('_struct_conn.pdbx_ptnr1_replaced_atom', '%s', 'str', ''), - ("_struct_conn.ptnr1_label_asym_id", "%s", "str", ""), - ("_struct_conn.ptnr1_label_comp_id", "%s", "str", ""), - # ('_struct_conn.ptnr1_label_seq_id', '%s', 'str', ''), - ("_struct_conn.ptnr1_auth_seq_id", "%s", "str", ""), - ("_struct_conn.ptnr1_label_atom_id", "%s", "str", ""), - # ('_struct_conn.pdbx_ptnr1_standard_comp_id', '%s', 'str', ''), - ("_struct_conn.ptnr1_symmetry", "%s", "str", ""), - ("_struct_conn.ptnr2_label_asym_id", "%s", "str", ""), - ("_struct_conn.ptnr2_label_comp_id", "%s", "str", ""), - ("_struct_conn.ptnr2_auth_seq_id", "%s", "str", ""), - # ('_struct_conn.ptnr2_label_seq_id', '%s', 'str', ''), - ("_struct_conn.ptnr2_label_atom_id", "%s", "str", ""), - ("_struct_conn.ptnr2_symmetry", "%s", "str", ""), - ("_struct_conn.pdbx_ptnr1_label_alt_loc", "%s", "str", ""), - ("_struct_conn.pdbx_ptnr1_label_ins_code", "%s", "str", ""), - ("_struct_conn.pdbx_ptnr2_label_alt_loc", "%s", "str", ""), - ("_struct_conn.pdbx_ptnr2_label_ins_code", "%s", "str", ""), - ("_struct_conn.ptnr1_auth_asym_id", "%s", "str", ""), - ("_struct_conn.ptnr1_auth_comp_id", "%s", "str", ""), - ("_struct_conn.ptnr2_auth_asym_id", "%s", "str", ""), - ("_struct_conn.ptnr2_auth_comp_id", "%s", "str", ""), - # ('_struct_conn.pdbx_ptnr3_label_atom_id', '%s', 'str', ''), - # ('_struct_conn.pdbx_ptnr3_label_seq_id', '%s', 'str', ''), - # ('_struct_conn.pdbx_ptnr3_label_comp_id', '%s', 'str', ''), - # ('_struct_conn.pdbx_ptnr3_label_asym_id', '%s', 'str', ''), - # ('_struct_conn.pdbx_ptnr3_label_alt_loc', '%s', 'str', ''), - # ('_struct_conn.pdbx_ptnr3_label_ins_code', '%s', 'str', ''), - ("_struct_conn.details", "%s", "str", ""), - ("_struct_conn.pdbx_value_order", "%s", "str", ""), - ], "struct_conn_type": [("_struct_conn_type.id", "%s", "str", ""), ("_struct_conn_type.criteria", "%s", "str", ""), ("_struct_conn_type.reference", "%s", "str", "")], "struct_ncs_oper": [ ("_struct_ncs_oper.id", "%s", "str", ""), diff --git a/wwpdb/apps/ann_tasks_v2/report/styles/PdbxIo.py b/wwpdb/apps/ann_tasks_v2/report/styles/PdbxIo.py index 99961b2..b0af630 100644 --- a/wwpdb/apps/ann_tasks_v2/report/styles/PdbxIo.py +++ b/wwpdb/apps/ann_tasks_v2/report/styles/PdbxIo.py @@ -44,6 +44,7 @@ # from mmcif_utils.style.PdbxReportCategoryStyle import PdbxReportCategoryStyle from wwpdb.apps.ann_tasks_v2.report.styles.ModelReport import PdbxReportCategoryStyle +from wwpdb.apps.ann_tasks_v2.report.styles.LinksReport import PdbxLinksReportCategoryStyle logger = logging.getLogger() @@ -133,6 +134,56 @@ def getContourLevelMap(self, mapId="primary map"): return "" +class PdbxLinksReportIo(PdbxStyleIoUtil): + """Methods for reading PDBx data files for reporting including style details. Specific to link information.""" + + def __init__(self, verbose=True, log=sys.stderr): + super(PdbxLinksReportIo, self).__init__(styleObject=PdbxLinksReportCategoryStyle(), verbose=verbose, log=log) + self.__lfh = log + self.__filePath = None + self.__idCode = None + + def getCategory(self, catName="entity"): + return self.getItemDictList(catName) + + def setFilePath(self, filePath, idCode=None): + """Specify the file path for the target and optionally provide an identifier + for the data section within the file. + """ + self.__filePath = filePath + self.__idCode = idCode + if self.readFile(self.__filePath): + if self.__idCode is not None: + return self.setContainer(containerName=self.__idCode) + else: + return self.setContainer(containerIndex=0) + else: + return False + + def get(self): + """ + Check for a valid current data container. + + Returns True for success or False otherwise. + """ + return self.getCurrentContainerId() is not None + + def complyStyle(self): + return self.testStyleComplete(self.__lfh) + + def setBlock(self, blockId): + return self.setContainer(containerName=blockId) + + def newBlock(self, blockId): + return self.newContainer(containerName=blockId) + + def update(self, catName, attributeName, value, iRow=0): + return self.updateAttribute(catName, attributeName, value, iRow=iRow) + + def write(self, filePath): + return self.writeFile(filePath) + + class PdbxGeometryReportIo(PdbxStyleIoUtil): """Methods for reading PDBx geometry data files for reporting applications including style details.""" diff --git a/wwpdb/apps/ann_tasks_v2/webapp/CommonTasksWebAppWorker.py b/wwpdb/apps/ann_tasks_v2/webapp/CommonTasksWebAppWorker.py index 27bba52..a41c973 100644 --- a/wwpdb/apps/ann_tasks_v2/webapp/CommonTasksWebAppWorker.py +++ b/wwpdb/apps/ann_tasks_v2/webapp/CommonTasksWebAppWorker.py @@ -2094,6 +2094,7 @@ def _renderCheckReports(self, entryId, fileSource="archive", instance=None, cont "model", "dcc-report", "geometry-check-report", + "links-report", "misc-check-report", "format-check-report", "dict-check-report", @@ -2175,6 +2176,15 @@ def _renderCheckReports(self, entryId, fileSource="archive", instance=None, cont else: # myD[cT] = self.__getMessageTextWithMarkup('No geometry issues.') myD[cT] = self.__getMessageTextWithMarkup("") + elif cT == "links-report": + # Links report + ok = du.fetchId(entryId, contentType="model", formatType="pdbx", fileSource=fileSource, instance=instance, versionId=versionId) + if ok: + downloadPath = du.getDownloadPath() + aTagList.append(du.getAnchorTag()) + myD[cT] = "\n".join(pR.makeTabularReport(filePath=downloadPath, contentType="links-report", idCode=entryId, layout=layout)) + else: + myD[cT] = self.__getMessageTextWithMarkup("") elif cT == "misc-check-report": # Misc check report ok = du.fetchId(entryId, contentType="misc-check-report", formatType="txt", fileSource=fileSource, instance=instance) @@ -2491,6 +2501,15 @@ def _makeCheckReports(self, entryIdList, fileSource="wf-archive", operationList= rptPath = chk.getReportPath() duL.copyToDownload(rptPath) aTagList.append(duL.getAnchorTag()) + + if "read-links" in operationList: + reader = LinksReader(reqObj=self._reqObj, verbose=self._verbose, log=self._lfh) + reader.run(entryId=entryId, inpPath=modelFilePath) + hasDiags = chk.getReportSize() > 0 + if hasDiags: + rptPath = chk.getReportPath() + duL.copyToDownload(rptPath) + aTagList.append(duL.getAnchorTag()) if "check-special-position" in operationList: chk = SpecialPositionCalc(reqObj=self._reqObj, verbose=self._verbose, log=self._lfh) diff --git a/wwpdb/apps/ann_tasks_v2/webapp/ReviewDataWebAppWorker.py b/wwpdb/apps/ann_tasks_v2/webapp/ReviewDataWebAppWorker.py index 8a75654..dec9f10 100644 --- a/wwpdb/apps/ann_tasks_v2/webapp/ReviewDataWebAppWorker.py +++ b/wwpdb/apps/ann_tasks_v2/webapp/ReviewDataWebAppWorker.py @@ -332,6 +332,7 @@ def _generateFullCheckReportHtml(self, idCode, fileSource="wf-archive", instance "dcc-report", "special-position-report", "geometry-check-report", + "links-report", "misc-check-report", "format-check-report", "dict-check-report",