Source code for schrodinger.application.desmond.rl_helper

import os
from datetime import datetime
from past.utils import old_div

import PIL

import reportlab
import reportlab.lib.colors as rlcolors
import reportlab.pdfgen.canvas as rlcanvas
import reportlab.platypus as platypus
from reportlab.lib.units import inch

styles = reportlab.lib.styles.getSampleStyleSheet()
HeaderStyle = styles["Heading1"]
ParaStyle = styles["Normal"]

gray = rlcolors.Color(old_div(136., 256), old_div(136., 256),
                      old_div(136., 256))
colors = [
    "#75D44A", "#BF58CB", "#D44B33", "#88C7D4", "#3B3628", "#CE497C", "#72D49B",
    "#59345F", "#5C7B37", "#707AC9", "#C78A3B", "#C7BD94", "#CE98B5", "#CECF4F",
    "#874236", "#597576"
]
blackColorMap = {
    5: 0xFF000000,
    7: 0xFF000000,
    8: 0xFF000000,
    9: 0xFF000000,
    13: 0xFF000000,
    14: 0xFF000000,
    15: 0xFF000000,
    16: 0xFF000000,
    17: 0xFF000000,
    35: 0xFF000000,
    53: 0xFF000000
}


[docs]def new_page(Elements): ''' insert page break ''' Elements.append(platypus.PageBreak())
[docs]def add_vtable(Elements, table, style, width_list): ''' add table, where header is in the first column ''' width = [w * inch for w in width_list] Elements.append(platypus.Table(table, width, style=style))
[docs]def add_table(Elements, table, style, col_width): ''' horizontal table, where the header is on the first row ''' nfields = len(table[0]) if isinstance(col_width, int) or isinstance(col_width, float): width = nfields * [col_width * inch] else: width = [w * inch for w in col_width] Elements.append(platypus.Table(table, width, style=style))
[docs]def add_and_parse_SMILES(smiles_str): """ parse SMILES string such that it fits on the page """ smiles_style = ParaStyle smiles_style.fontSize = 10 length = len(smiles_str) new_str = '' prev_idx = 0 max_length = 66 if length <= max_length: return smiles_str # output smiles only upto 3 lines; otherwise it gets messy. elif length > max_length * 3: return smiles_str[:max_length] + '...' for i in list(range(0, length, max_length))[1:]: new_str += smiles_str[prev_idx:i + 1] + ' ' prev_idx = i + 1 if prev_idx < length: new_str += smiles_str[prev_idx:length] return platypus.Paragraph(new_str, smiles_style)
[docs]def add_spacer(Elements): Elements.append(platypus.Spacer(1, 11))
[docs]def get_image(fn, height, width): with PIL.Image.open(fn) as img_temp: size = img_temp.size (sx, sy) = aspectScale(size[0], size[1], height, width) img = platypus.Image(fn, sx * inch, sy * inch) return img
[docs]def get_pargph(txt, fixed=False, fontsize=11, color='black', hAlign='left'): style = ParaStyle style.fontName = 'Courier' if fixed else 'Helvetica' style.fontSize = fontsize style.textColor = color style.hAlign = hAlign return platypus.Paragraph(txt, style)
[docs]def pargph(Elements, txt, fixed=False, fontsize=11, color='black', leading=None): """ Add a paragraph to the report :param list Elements: Report elements to add the paragraph to :param str txt: The paragraph text :param int fontsize: The size of the paragraph font :param str color: Font color :param leading: Spacing between paragraph lines, the default will be used if nothing is passed :type leading: int or None """ style = ParaStyle style.fontName = 'Courier' if fixed else 'Helvetica' style.fontSize = fontsize style.textColor = color if leading: # Set leading if a custom one has been provided style.leading = leading para = platypus.Paragraph(txt, style) Elements.append(para)
[docs]def aspectScale(ix, iy, bx, by): '''Scale image to fit into box (bx,by) keeping aspect ratio''' if ix > iy: # fit to width scale_factor = old_div(bx, float(ix)) sy = scale_factor * iy if sy > by: scale_factor = old_div(by, float(iy)) sx = scale_factor * ix sy = by else: sx = bx else: # fit to height scale_factor = old_div(by, float(iy)) sx = scale_factor * ix if sx > bx: scale_factor = old_div(bx, float(ix)) sx = bx sy = scale_factor * iy else: sy = by return (sx, sy)
[docs]class NumberedCanvas(rlcanvas.Canvas):
[docs] def __init__(self, *args, **kwargs): rlcanvas.Canvas.__init__(self, *args, **kwargs) self._saved_page_states = []
[docs] def showPage(self): self._saved_page_states.append(dict(self.__dict__)) self._startPage()
[docs] def save(self): """add page info to each page (page x of y)""" num_pages = len(self._saved_page_states) for state in self._saved_page_states: self.__dict__.update(state) self.drawFixedContents(num_pages) rlcanvas.Canvas.showPage(self) rlcanvas.Canvas.save(self)
[docs] def drawFixedContents(self, page_count): """ Draw nonflowables such as footers, headers and fixed graphics :param int page_count: Total number of pages """ self.setFont("Helvetica", 8) self.drawRightString(8 * inch, 0.3 * inch, "Page %d of %d" % (self._pageNumber, page_count)) s = "Schrödinger Inc. Report generated " + datetime.now().strftime( "%m-%d-%Y %H:%M") self.drawString(0.8 * inch, 0.3 * inch, s)