Changeset 112

Show
Ignore:
Timestamp:
06/28/07 17:22:18 (1 year ago)
Author:
apdavison
Message:

Fixed some regexp bugs, reorganised the code a little

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • doc/CNS2007/poster_cns2007.py

    r110 r112  
    11# encoding: utf-8 
     2""" 
     3Script to generate the poster for the CNS*2007 meeting. 
     4""" 
     5 
    26from reportlab.pdfgen.canvas import Canvas 
    37from reportlab.lib.pagesizes import A0, landscape 
     
    1923        return "%s<super>%s</super>" % (self.name, ",".join([str(a) for a in self.affiliations])) 
    2024     
    21 svnpath = "https://neuralensemble.kip.uni-heidelberg.de/svn/PyNN/branches/0.3" 
    22 DEBUG = True 
    23  
    24 TITLE = "PyNN: Towards a universal neural simulator API in Python" 
    25  
    26 INSTITUTIONS = ["UNIC, CNRS, Gif-sur-Yvette, France", 
    27                 "INCM, CNRS, Marseille, France", 
    28                 "Neurobiology and Biophysics, Albert-Ludwigs-University Freiburg, Freiburg, Germany", 
    29                 "Kirchhoff Institute for Physics, University of Heidelberg, Heidelberg, Germany"] 
    30  
    31 AUTHORS = [Author("Andrew Davison", 1), 
    32            Author("Pierre Yger", 1), 
    33            Author("Jens Kremkow", 2,3), 
    34            Author("Laurent Perrinet", 2), 
    35            Author("Eilif Muller", 4)] 
    36  
    37 SUBJECT = "Poster for CNS*2007, Toronto, Canada" 
    38  
    39 ABSTRACT = """Trends in programming language development and adoption point to Python as the high-level systems 
    40 integration language of choice. Python leverages a vast developer-base external to the neuroscience 
    41 community, and promises leaps in simulation complexity and maintainability to any neural simulator 
    42 that adopts it. PyNN [<a href="http://neuralensemble.org/PyNN">http://neuralensemble.org/PyNN</a>] strives to provide a uniform application programming 
    43 interface (API) across neural simulators. Presently NEURON, NEST are PCSIM supported, and support for 
    44 other simulators, NeuroML output and neuromorphic VLSI hardware is under development. 
    45  
    46 With PyNN it is possible to write a simulation script once and run it without modification on any 
    47 supported simulator. It is also possible to write a script that uses capabilities specific to a single 
    48 simulator. While this sacrifices simulator-independence, is adds flexibility, and can be a useful step in 
    49 porting models between simulators. The design goals of PyNN include allowing access to low-level 
    50 details of a simulation where necessary, while providing the capability to model at a high level of 
    51 abstraction, with concomitant gains in development speed and simulation maintainability. 
    52  
    53 Another of our aims with PyNN is to increase the productivity of neuroscience modeling, by making it 
    54 faster to develop models <i>de novo</i>, by promoting code sharing and reuse across simulator communities, 
    55 and by making it much easier to debug, test and validate simulations by running them on more than one 
    56 simulator. Modelers would then become free to devote more software development effort to 
    57 innovation, building on the simulator core with new tools such as network topology databases, stimulus 
    58 programming, analysis and visualization tools, and simulation accounting. The resulting, community- 
    59 developed 'meta-simulator' system would then represent a powerful tool for overcoming the so-called 
    60 <i>complexity bottleneck</i> that is presently a major roadblock for neural modeling. 
    61  
    62 This work is supported by the European Union through the FACETS project (contract number FP6- 
    63 2004-IST-FETPI-15879).""" 
    64  
    65 main_font = 'Helvetica' 
    66 margins = {'left':2*cm, 'right':2*cm, 'top':2*cm, 'bottom':2*cm} 
    67 colsep = 2*cm 
    68 titlesep = 2*cm 
    6925 
    7026def scale_style(style, x, _debug=False): 
     
    7733            setattr(style, attr_name, attr*x)      
    7834 
    79 styles = getSampleStyleSheet() 
    80 # Scale font sizes and related spacing 
    81 for style in styles.byName.values(): 
    82     scale_style(style, 3.6) 
    83 styles['Title'].fontSize += 8 
    84  
    85  
    86 author_style = ParagraphStyle('Authors', parent=styles['Heading3']) 
    87 author_style.alignment = TA_CENTER 
    88 styles.add(author_style) 
    89  
    90 affiliation_style = ParagraphStyle('Affiliations', parent=styles['Normal']) 
    91 affiliation_style.alignment = TA_CENTER 
    92 styles.add(affiliation_style) 
    93  
    94 users_guide_style = ParagraphStyle('UsersGuide', parent=styles['BodyText']) 
    95 scale_style(users_guide_style, 2.0/3.6) 
    96 styles.add(users_guide_style) 
    97  
    98 for style in "Heading1","Heading2","Heading3","Code": 
    99     newstyle = ParagraphStyle('UsersGuide%s' % style, parent=styles[style]) 
    100     scale_style(newstyle, 2.0/3.6) 
    101     styles.add(newstyle) 
    102  
    103 styles['Title'].alignment = TA_CENTER 
    104 styles['BodyText'].alignment = TA_JUSTIFY 
    105 styles['UsersGuide'].alignment = TA_JUSTIFY 
    106  
    107 print "Font sizes:" 
    108 for style in 'BodyText','Title', 'Heading1', 'Heading2', 'Heading3', 'UsersGuide': 
    109     print style, styles[style].fontSize 
    110  
    111 ##styles['UsersGuideCode'].listAttrs() 
    112  
    113 poster = Canvas("poster_cns2007.pdf", 
    114                 pagesize=landscape(A0), 
    115                 pageCompression=False, 
    116                 verbosity=2) 
    117 poster.setAuthor(", ".join([a.name for a in AUTHORS])) 
    118 poster.setTitle(TITLE) 
    119 poster.setSubject(SUBJECT) 
    120  
    121 pagewidth = poster._pagesize[0] - margins['left'] - margins['right'] 
    122 pageheight = poster._pagesize[1] - margins['bottom'] - margins['top'] 
    123 pagetop = poster._pagesize[1] - margins['top'] 
    124 pageright = poster._pagesize[0] - margins['right'] 
    125  
    126  
    127 title_frame = Frame(margins['left'], pageheight/2.0, pagewidth, 20*cm, 
    128                     showBoundary=True) 
    129  
    130  
    131  
    132 author_str = ", ".join([str(a) for a in AUTHORS]) 
    133 inst_str = ", ".join(["<super>%d</super>%s" % (i+1,inst) for i, inst in enumerate(INSTITUTIONS)]) 
    134  
    135 title_paragraph = Paragraph(TITLE, styles['Title']) 
    136 p_width = 10*cm 
    137 title_paragraph.wrap(p_width, 1e12) 
    138 while len(title_paragraph.breakLines([p_width,1e12]).lines) > 1: 
    139    p_width *= 1.1 
    140  
    141 title_components = [title_paragraph, 
    142                     Paragraph(author_str, styles['Authors']), 
    143                     Paragraph(inst_str, styles['Affiliations']) 
    144                    ] 
    145 f_height = 0 
    146 for p in title_components: 
    147     f_height += p.wrap(p_width,pageheight)[1] + p.getSpaceAfter() + p.getSpaceBefore() 
    148  
    149 x = margins['left'] + pagewidth/2.0 - p_width/2.0 
    150 y = pagetop - f_height 
    151 title_frame = Frame(x, y, p_width, f_height, showBoundary=False) 
    152 title_frame.addFromList(title_components, poster) 
    153  
    154 def print_logo(filename, position, y, f_height, maxwidth=pagewidth/10.0): 
     35def getStyleSheet(scale_factor): 
     36    styles = getSampleStyleSheet() 
     37    # Scale font sizes and related spacing 
     38    for style in styles.byName.values(): 
     39        scale_style(style, scale_factor) 
     40    styles['Title'].fontSize += 8 
     41     
     42    author_style = ParagraphStyle('Authors', parent=styles['Heading3']) 
     43    author_style.alignment = TA_CENTER 
     44    styles.add(author_style) 
     45     
     46    affiliation_style = ParagraphStyle('Affiliations', parent=styles['Normal']) 
     47    affiliation_style.alignment = TA_CENTER 
     48    styles.add(affiliation_style) 
     49     
     50    users_guide_style = ParagraphStyle('UsersGuide', parent=styles['BodyText']) 
     51    scale_style(users_guide_style, 1.5/scale_factor) 
     52    styles.add(users_guide_style) 
     53     
     54    for style in "Heading1","Heading2","Heading3","Code": 
     55        newstyle = ParagraphStyle('UsersGuide%s' % style, parent=styles[style]) 
     56        scale_style(newstyle, 1.5/scale_factor) 
     57        styles.add(newstyle) 
     58     
     59    styles['Title'].alignment = TA_CENTER 
     60    styles['BodyText'].alignment = TA_JUSTIFY 
     61    styles['UsersGuide'].alignment = TA_JUSTIFY 
     62     
     63    print "Font sizes:" 
     64    for style in 'BodyText','Title', 'Heading1', 'Heading2', 'Heading3', 'UsersGuide': 
     65        print style, styles[style].fontSize 
     66    ##styles['UsersGuideCode'].listAttrs() 
     67 
     68    return styles 
     69 
     70def print_logo(filename, position, y, f_height, maxwidth=None): 
     71    global poster, pagewidth 
     72    if maxwidth is None: 
     73        maxwidth=pagewidth/10.0 
    15574    logo = PIL.Image.open(filename) 
    15675    logo_height = 0.9*f_height 
     
    16584    poster.drawInlineImage(logo, x, y, height=logo_height, width=logo_width) 
    16685 
    167  
    168 print_logo("pynn_tree2.png", "left", y, f_height) 
    169 print_logo("facetslogoweb.gif", "right", y, f_height) 
    170 # logos 
    171 institution_logos = ['facetslogoweb.gif','logo-cnrs.jpg','bccn-logo.jpg','kip_logo.gif'] 
    172  
    173 poster.roundRect(margins['left'],y,pagewidth,f_height,2*cm) 
    174  
    175 title_bottom = y - titlesep 
    176  
    177 ncol = 3 
    178 colwidth = (pagewidth - (ncol-1)*colsep)/float(ncol) 
    179  
    180 abstract_frame = Frame(margins['left'], title_bottom - pageheight, colwidth, pageheight, 
    181                     showBoundary=True) 
    182  
    183 abstract = [Paragraph(p, styles['BodyText']) for p in ABSTRACT.split("\n\n")] 
    184 #print abstract 
    185 abstract_frame.addFromList(abstract, poster) 
    186 #while not abstract_frame.addFromList(abstract, poster): 
    187 #    abstract_frame._height += 1*cm 
    188 #    abstract_frame._geom() 
    189 #    abstract_frame._reset() 
    190 #    print abstract_frame._height 
    191 svn_client = pysvn.Client() 
    192 svn_client.checkout(svnpath, "pyNN") 
    193 import pyNN 
    194 import docutils.core 
    195  
    196 user_guide_frame = Frame(margins['left']+colwidth+colsep, title_bottom - pageheight, colwidth, pageheight, 
    197                     showBoundary=True) 
    198  
    199 import restxsl.transform 
    200 import re 
    201 paragraph_template = re.compile(r'<para( style="(?P<style>\S.*)")?>(?P<content>.*)</para>') 
    202  
    203 paragraph_list = [] 
    204 for section in "Installation", : #"Introduction", "Installation", "Low-level API": #, "High-level API": 
    205     filename = "pyNN/doc/" + section.lower().replace("-","").replace(" ","") + ".txt" 
    206     filename, xmltext = restxsl.transform.restxsl(filename, 
    207                                                   smartPunctuation=False, 
    208                                                   encoding='UTF-8', 
    209                                                   xslPath="reST2reportlab.xsl")[0] 
    210     print "*********************** " + section + " ******************************" 
    211     #xmltext = re.sub(u'\N{NON-BREAKING HYPHEN}', r'-', xmltext) 
    212     xmltext = xmltext.replace('‑','-') # the first character is a unicode non-breaking hyphen, introduced by restxsl (see restxsl/restxmldoc.py line 234) 
    213     print xmltext 
    214     paragraph_list = [Paragraph(section, styles['UsersGuideHeading1'])] 
    215     for match in paragraph_template.finditer(xmltext): 
    216         groups = match.groupdict() 
    217         content = groups['content'] 
    218         style = "UsersGuide" 
    219         if groups['style'] is not None: 
    220             style += groups['style'] 
    221         print "###### " + style 
    222         print content 
    223         paragraph_list += [Paragraph(content, styles[style])] 
    224     user_guide_frame.addFromList(paragraph_list, poster) 
    225  
    226 poster.save() 
     86def make_title(title,authors,institutions,logo_left,logo_right): 
     87    """Returns the y position of the bottom of the title (including bottom margin).""" 
     88    global poster, margins, pageheight, pagewidth, styles, pagetop 
     89    title_frame = Frame(margins['left'], pageheight/2.0, pagewidth, 20*cm, 
     90                        showBoundary=True) 
     91    author_str = ", ".join([str(a) for a in authors]) 
     92    inst_str = ", ".join(["<super>%d</super>%s" % (i+1,inst) for i, inst in enumerate(institutions)]) 
     93     
     94    title_paragraph = Paragraph(title, styles['Title']) 
     95    p_width = 10*cm 
     96    title_paragraph.wrap(p_width, 1e12) 
     97    while len(title_paragraph.breakLines([p_width,1e12]).lines) > 1: 
     98       p_width *= 1.1 
     99     
     100    title_components = [title_paragraph, 
     101                        Paragraph(author_str, styles['Authors']), 
     102                        Paragraph(inst_str, styles['Affiliations']) 
     103                       ] 
     104    f_height = 0 
     105    for p in title_components: 
     106        f_height += p.wrap(p_width,pageheight)[1] + p.getSpaceAfter() + p.getSpaceBefore() 
     107     
     108    x = margins['left'] + pagewidth/2.0 - p_width/2.0 
     109    y = pagetop - f_height 
     110    title_frame = Frame(x, y, p_width, f_height, showBoundary=False) 
     111    title_frame.addFromList(title_components, poster) 
     112 
     113    print_logo(logo_left, "left", y, f_height) 
     114    print_logo(logo_right, "right", y, f_height) 
     115 
     116    poster.roundRect(margins['left'],y,pagewidth,f_height,2*cm) 
     117 
     118    title_bottom = y - titlesep 
     119    return title_bottom 
     120 
     121def make_abstract(text,x,y,width,height,_debug): 
     122    abstract_frame = Frame(x, y - height, width, height, 
     123                           showBoundary=_debug) 
     124 
     125    abstract = [Paragraph(p, styles['BodyText']) for p in ABSTRACT.split("\n\n")] 
     126    #print abstract 
     127    abstract_frame.addFromList(abstract, poster) 
     128    #while not abstract_frame.addFromList(abstract, poster): 
     129    #    abstract_frame._height += 1*cm 
     130    #    abstract_frame._geom() 
     131    #    abstract_frame._reset() 
     132    #    print abstract_frame._height 
     133 
     134def make_users_guide(x,y,width,height,_debug=False): 
     135    global poster 
     136    svn_client = pysvn.Client() 
     137    svn_client.checkout(svnpath, "pyNN") 
     138    import pyNN 
     139    import docutils.core 
     140    import restxsl.transform 
     141    import re 
     142     
     143    user_guide_frame = Frame(x, y - height, width, height, showBoundary=_debug) 
     144 
     145    paragraph_template = re.compile(r'<para( style="(?P<style>\S*)")?>(?P<content>.*?)</para>',re.DOTALL) 
     146 
     147    for section in "High-level API", : #"Introduction", "Installation", "Low-level API": #, "High-level API": 
     148        filename = "pyNN/doc/" + section.lower().replace("-","").replace(" ","") + ".txt" 
     149        filename, xmltext = restxsl.transform.restxsl(filename, 
     150                                                      smartPunctuation=False, 
     151                                                      encoding='UTF-8', 
     152                                                      xslPath="reST2reportlab.xsl")[0] 
     153        #if _debug: print "*********************** " + section + " ******************************" 
     154        xmltext = xmltext.replace('‑','-') # the first character is a unicode non-breaking hyphen, introduced by restxsl (see restxsl/restxmldoc.py line 234) 
     155        #if _debug: print xmltext 
     156        #if _debug: print "-----------------------------" 
     157        paragraph_list = [Paragraph(section, styles['UsersGuideHeading1'])] 
     158        for match in paragraph_template.finditer(xmltext): 
     159            groups = match.groupdict() 
     160            content = groups['content'] 
     161            style = "UsersGuide" 
     162            if groups['style'] is not None: 
     163                style += groups['style'] 
     164            #if _debug: print "###### " + style 
     165            #if _debug: print content 
     166            paragraph_list += [Paragraph(content, styles[style])] 
     167        user_guide_frame.addFromList(paragraph_list, poster) 
     168 
     169# ============================================================================== 
     170 
     171if __name__ == "__main__": 
     172    svnpath = "https://neuralensemble.kip.uni-heidelberg.de/svn/PyNN/branches/0.3" 
     173    DEBUG = True 
     174     
     175    TITLE = "PyNN: Towards a universal neural simulator API in Python" 
     176     
     177    INSTITUTIONS = ["UNIC, CNRS, Gif-sur-Yvette, France", 
     178                    "INCM, CNRS, Marseille, France", 
     179                    "Neurobiology and Biophysics, Albert-Ludwigs-University Freiburg, Freiburg, Germany", 
     180                    "Kirchhoff Institute for Physics, University of Heidelberg, Heidelberg, Germany"] 
     181     
     182    AUTHORS = [Author("Andrew Davison", 1), 
     183               Author("Pierre Yger", 1), 
     184               Author("Jens Kremkow", 2,3), 
     185               Author("Laurent Perrinet", 2), 
     186               Author("Eilif Muller", 4)] 
     187     
     188    SUBJECT = "Poster for CNS*2007, Toronto, Canada" 
     189     
     190    ABSTRACT = """Trends in programming language development and adoption point to Python as the high-level systems 
     191    integration language of choice. Python leverages a vast developer-base external to the neuroscience 
     192    community, and promises leaps in simulation complexity and maintainability to any neural simulator 
     193    that adopts it. PyNN [<a href="http://neuralensemble.org/PyNN">http://neuralensemble.org/PyNN</a>] strives to provide a uniform application programming 
     194    interface (API) across neural simulators. Presently NEURON, NEST are PCSIM supported, and support for 
     195    other simulators, NeuroML output and neuromorphic VLSI hardware is under development. 
     196     
     197    With PyNN it is possible to write a simulation script once and run it without modification on any 
     198    supported simulator. It is also possible to write a script that uses capabilities specific to a single 
     199    simulator. While this sacrifices simulator-independence, is adds flexibility, and can be a useful step in 
     200    porting models between simulators. The design goals of PyNN include allowing access to low-level 
     201    details of a simulation where necessary, while providing the capability to model at a high level of 
     202    abstraction, with concomitant gains in development speed and simulation maintainability. 
     203     
     204    Another of our aims with PyNN is to increase the productivity of neuroscience modeling, by making it 
     205    faster to develop models <i>de novo</i>, by promoting code sharing and reuse across simulator communities, 
     206    and by making it much easier to debug, test and validate simulations by running them on more than one 
     207    simulator. Modelers would then become free to devote more software development effort to 
     208    innovation, building on the simulator core with new tools such as network topology databases, stimulus 
     209    programming, analysis and visualization tools, and simulation accounting. The resulting, community- 
     210    developed 'meta-simulator' system would then represent a powerful tool for overcoming the so-called 
     211    <i>complexity bottleneck</i> that is presently a major roadblock for neural modeling. 
     212     
     213    This work is supported by the European Union through the FACETS project (contract number FP6- 
     214    2004-IST-FETPI-15879).""" 
     215    main_font = 'Helvetica' 
     216    margins = {'left':2*cm, 'right':2*cm, 'top':2*cm, 'bottom':2*cm} 
     217    colsep = 2*cm 
     218    titlesep = 2*cm 
     219    styles = getStyleSheet(3.6) 
     220 
     221    poster = Canvas("poster_cns2007.pdf", 
     222                pagesize=landscape(A0), 
     223                pageCompression=False, 
     224                verbosity=2) 
     225    poster.setAuthor(", ".join([a.name for a in AUTHORS])) 
     226    poster.setTitle(TITLE) 
     227    poster.setSubject(SUBJECT) 
     228 
     229    pagewidth = poster._pagesize[0] - margins['left'] - margins['right'] 
     230    pageheight = poster._pagesize[1] - margins['bottom'] - margins['top'] 
     231    pagetop = poster._pagesize[1] - margins['top'] 
     232    pageright = poster._pagesize[0] - margins['right'] 
     233    title_bottom = make_title(TITLE, AUTHORS, INSTITUTIONS, "pynn_tree2.png", "facetslogoweb.gif") 
     234    # logos 
     235    institution_logos = ['facetslogoweb.gif','logo-cnrs.jpg','bccn-logo.jpg','kip_logo.gif'] 
     236    ncol = 3 
     237    colwidth = (pagewidth - (ncol-1)*colsep)/float(ncol) 
     238    make_abstract(ABSTRACT, margins['left'], title_bottom, colwidth, pageheight, DEBUG) 
     239    make_users_guide(margins['left']+colwidth+colsep, title_bottom, colwidth, pageheight, DEBUG) 
     240 
     241    poster.save()