Changeset 281

Show
Ignore:
Timestamp:
01/26/08 23:02:35 (10 months ago)
Author:
t
Message:
  • added /style CSS;
  • gussied up the canal.templates functions, added wrap & error
  • motif order is now constant (ordered by ID) so colors stay the same
  • sequence intervals now go [1, len] rather than [0, len)
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cartwheel-server/lib/cartwheel/website/LeafFolder.py

    r273 r281  
    6464        c = DeepCatalog(m, NamedMotif, 
    6565                        limits, 
    66                         "ORDER BY UPPER(named_motifs.name)") 
     66                        "ORDER BY named_motifs.id") 
    6767 
    6868        return c 
  • trunk/cartwheel-server/tests/functional-tests/test-with-user/test-web/__init__.py

    r239 r281  
    140140    follow('admin') 
    141141    code('200') 
     142 
     143def test_style(): 
     144    "Load the style file" 
     145 
     146    go('http://localhost/style') 
     147    code('200') 
  • trunk/cartwheel-server/website/canal/__init__.py

    r4 r281  
    1515              'my',                     # personal page 
    1616              'stats',                  # server statistics 
    17               'locked']                 # locked-out account. 
     17              'locked',                 # locked-out account. 
     18              'style' ]                 # CSS 
    1819 
    1920import quixote 
     
    5859 
    5960    return request.redirect(request.get_url(1)) 
     61 
     62# 
     63# style 
     64# 
     65 
     66def style(request): 
     67    from templates import get_style_contents 
     68    response = request.response 
     69    response.set_content_type('text/css') 
     70    return get_style_contents() 
  • trunk/cartwheel-server/website/canal/motif/__init__.py

    r280 r281  
    88import cartwheel.website 
    99 
    10 from canal.templates import header, footer 
     10from canal.templates import header, footer, wrap 
    1111from canal.motif import utils 
    1212from canal.motif.analyze import AnalyzeSequenceHandler 
     
    121121""" % (motif.name,) 
    122122 
    123     return htmlfill.render(formhtml, values
     123    return wrap(htmlfill.render(formhtml, values), show_anything=False
    124124 
    125125def edit_pwm_motif(request, motif): 
     
    197197    formhtml = htmlfill.render(formhtml, values) 
    198198     
    199     return str(header("Edit PWM Motif '%s'" % (name,))) + \ 
    200                 formhtml + \ 
    201                 str(display_pwm_information(pwm, sequences, threshold)) + \ 
    202                 str(footer()
     199    return wrap(htmlfill.render(formhtml, values), 
     200                display_pwm_information(pwm, sequences, threshold), 
     201                title="Edit PWM Motif '%s'" % (name,), 
     202                show_anything = False
    203203 
    204204def batch_export(request): 
  • trunk/cartwheel-server/website/canal/motif/analyze.ptl

    r279 r281  
    99 
    1010import cartwheel.website 
    11 from canal.templates import header, footer 
     11from canal.templates import header, footer, wrap 
    1212 
    1313import pygr_draw 
     
    2929    Do the motif search & use pygr_draw to actually draw a picture. 
    3030    """ 
     31    seq_start -= 1                      # adjust for users thinking ! 0 
    3132 
    3233    sequencedb = dict(sequence=pygr.sequence.Sequence(dna_seq.seq,'sequence')) 
     
    8182    template _q_index(self, request): 
    8283        form = request.form 
    83         start = int(form.get('start', 0)) 
    84         start = max(start, 0
     84        start = int(form.get('start', 1)) 
     85        start = max(start, 1
    8586         
    8687        stop = int(form.get('stop', len(self.seq.seq))) 
    8788        stop = min(len(self.seq.seq), stop) 
     89 
     90        start, stop = min(start, stop), max(start, stop) 
     91 
     92        if form.get('reset_coords'): 
     93            start = 1 
     94            stop = len(self.seq.seq) 
     95 
     96        ### 
    8897         
    8998        (folder, motifs) = get_folder_motifs(self.manager, request) 
     
    98107        """ 
    99108        <p> 
     109        <a href='../'>return to motif library page</a> 
     110        <hr> 
    100111        <h4>Motif matches graphed against sequence:</h4> 
    101112        <a href='draw_pdf?start=%d&stop=%d'>(download as PDF)</a><br> 
     
    116127            key = motif.simple_key() 
    117128             
    118             search_results = motif.search(self.seq, start, stop) 
     129            search_results = motif.search(self.seq, start - 1, stop) 
    119130 
    120131            param_dict = dict(motif_id=motif.id, start=start, stop=stop) 
     
    137148        <p> 
    138149        <input type='submit' value='redraw'> 
     150        <input type='submit' value='show entire sequence' name='reset_coords'> 
    139151        </form> 
     152        <p> 
     153        <a href='../'>return to motif library page</a> 
    140154        """ % (start, stop) 
    141155         
     
    144158    def draw_png(self, request): 
    145159        form = request.form 
    146         seq_start = int(form.get('start', 0)) 
    147         seq_start = max(seq_start, 0
     160        seq_start = int(form.get('start', 1)) 
     161        seq_start = max(seq_start, 1
    148162 
    149163        seq_stop = int(form.get('stop', len(self.seq.seq))) 
    150164        seq_stop = min(len(self.seq.seq), seq_stop) 
     165 
     166        seq_start, seq_stop = min(seq_start, seq_stop),max(seq_start, seq_stop) 
    151167 
    152168        (folder, motifs) = get_folder_motifs(self.manager, request) 
     
    161177    def draw_pdf(self, request): 
    162178        form = request.form 
    163         seq_start = int(form.get('start', 0)) 
    164         seq_start = max(seq_start, 0
     179        seq_start = int(form.get('start', 1)) 
     180        seq_start = max(seq_start, 1
    165181         
    166182        seq_stop = int(form.get('stop', len(self.seq.seq))) 
    167183        seq_stop = min(len(self.seq.seq), seq_stop) 
     184 
     185        seq_start, seq_stop = min(seq_start, seq_stop),max(seq_start, seq_stop) 
    168186 
    169187        (folder, motifs) = get_folder_motifs(self.manager, request) 
     
    192210    template matches_detail_IUPAC(self, request, motif): 
    193211        form = request.form 
    194         seq_start = int(form.get('start', 0)) 
    195         seq_start = max(seq_start, 0
     212        seq_start = int(form.get('start', 1)) 
     213        seq_start = max(seq_start, 1
    196214         
    197215        seq_stop = int(form.get('stop', len(self.seq.seq))) 
    198216        seq_stop = min(len(self.seq.seq), seq_stop) 
    199217 
    200         matches = motif.search(self.seq, seq_start, seq_stop) 
     218        seq_start, seq_stop = min(seq_start, seq_stop),max(seq_start, seq_stop) 
     219         
     220        matches = motif.search(self.seq, seq_start - 1, seq_stop) 
    201221 
    202222        ### sort 
     
    236256        Mismatches allowed: %d<p> 
    237257        <p> 
     258        <a href='./'>return to analysis page</a> 
    238259        <hr> 
    239260        """ % (name, len(self.seq.seq), 
     
    269290                """ 
    270291                <tr><td>%d</td><td>%d</td><td>%s</td><td>%s</td></tr> 
    271                 """ % (start, stop, o, match_seq,) 
     292                """ % (start + 1, stop, o, match_seq,) 
    272293 
    273294            """ 
    274295            </table> 
     296            <p> 
     297            <a href='./'>return to analysis page</a> 
    275298            """ 
    276299 
     
    279302    template matches_detail_PWM(self, request, motif): 
    280303        form = request.form 
    281         seq_start = int(form.get('start', 0)) 
    282         seq_start = max(seq_start, 0
     304        seq_start = int(form.get('start', 1)) 
     305        seq_start = max(seq_start, 1
    283306         
    284307        seq_stop = int(form.get('stop', len(self.seq.seq))) 
    285308        seq_stop = min(len(self.seq.seq), seq_stop) 
    286309 
     310        seq_start, seq_stop = min(seq_start, seq_stop),max(seq_start, seq_stop) 
     311 
    287312        ## 
    288313 
    289314        pwm = motif.make_pwm() 
    290         matches = motif.search(self.seq, seq_start, seq_stop) 
     315        matches = motif.search(self.seq, seq_start - 1, seq_stop) 
    291316 
    292317        # add in score. 
     
    332357        Default threshold: %f 
    333358        <p> 
     359        <a href='./'>return to analysis page</a> 
    334360        <hr> 
    335361        """ % (name, len(self.seq.seq), 
     
    367393                """ 
    368394                <tr><td>%d</td><td>%d</td><td>%s</td><td>%s</td><td>%.2f</td></tr> 
    369                 """ % (start, stop, o, match_seq, score) 
     395                """ % (start + 1, stop, o, match_seq, score) 
    370396 
    371397            """ 
    372398            </table> 
     399            <p> 
     400            <a href='./'>return to analysis page</a> 
    373401            """ 
    374402 
     
    383411        seq_stop = min(len(self.seq.seq), seq_stop) 
    384412 
     413        seq_start, seq_stop = min(seq_start, seq_stop),max(seq_start, seq_stop) 
     414 
    385415        ### 
    386416 
     
    388418        motif = self.manager.load(motif_id) 
    389419 
    390         matches = motif.search(self.seq, seq_start, seq_stop) 
     420        matches = motif.search(self.seq, seq_start - 1, seq_stop) 
    391421 
    392422        s = """# motif: %s/%s/%d mismatches\n# sequence: %s\n""" % \ 
     
    395425        l = ["start,stop,orientation,match"] 
    396426        for (start, stop, orientation, match_seq) in matches: 
    397             l.append("%d,%d,%d,%s" % (start, stop, orientation, match_seq,)) 
     427            l.append("%d,%d,%d,%s" % (start + 1, stop, 
     428                                      orientation, match_seq,)) 
    398429 
    399430        request.response.set_content_type('text/plain') 
     
    409440        seq_stop = min(len(self.seq.seq), seq_stop) 
    410441 
     442        seq_start, seq_stop = min(seq_start, seq_stop),max(seq_start, seq_stop) 
     443 
    411444        ### 
    412445         
     
    416449        consensus = motif.simple_key() 
    417450        pwm = motif.make_pwm() 
    418         matches = motif.search(self.seq, seq_start, seq_stop) 
     451        matches = motif.search(self.seq, seq_start - 1, seq_stop) 
    419452 
    420453        s = """# PWM motif %s: consensus %s/threshold %f\n# sequence: %s\n"""%\ 
     
    426459        l = ["start,stop,orientation,match,score"] 
    427460        for (start, stop, orientation, match_seq, score) in matches: 
    428             l.append("%d,%d,%d,%s,%s" % (start, stop, orientation, match_seq
    429                                          score,)) 
     461            l.append("%d,%d,%d,%s,%s" % (start + 1, stop
     462                                         orientation, match_seq, score,)) 
    430463 
    431464        request.response.set_content_type('text/plain') 
  • trunk/cartwheel-server/website/canal/motif/pages.ptl

    r280 r281  
    11import cartwheel.website 
    2 from canal.templates import header, footer 
     2from canal.templates import header, footer, wrap, error 
    33from cartwheel.website.IUPACMotif import IUPACMotif 
    44from cartwheel.website.PWMMotif import PWMMotif 
     
    6262    <hr> 
    6363 
    64     <b>Add motifs:</b> <a href="add_iupac">add a simple motif</a> | 
    65                        <a href="build_pwm_from_list">build a matrix (PWM) 
     64    <b>Add motifs:</b> <ul> 
     65                       <li> <a href="add_iupac">add a simple motif</a>  
     66                       <li> <a href="build_pwm_from_list">build a matrix (PWM) 
    6667                                                from a list of sites</a> 
    67  
    68 <!-- | 
    69     <font color='red'>import a matrix from JASPAR (not yet!)</font> --> 
     68                       <li> <a href="">import matrix from JASPAR</a> 
     69       </ul> 
     70 
     71 
    7072    <p> 
    7173    """ 
     
    8688     
    8789    """ 
    88     <b>Other actions:</b>  
    89           <a href="batch_export">export motifs to a text file</a> | 
    90           <a href="batch_import">import motifs from a text file</a> 
     90    <b>Other actions:</b> <ul> 
     91          <li> <a href="batch_export">export motifs to a text file</a> 
     92          <li> <a href="batch_import">import motifs from a text file</a> 
     93         </ul> 
    9194    <p> 
    9295    <a href="../">Return to folder menu</a> 
     
    101104 
    102105    if not request.form: 
    103         return """\ 
     106        return wrap("""\ 
    104107        <h2>Add an IUPAC motif</h2> 
    105108        <form method='POST' action='add_iupac'> 
     
    130133N      G or A or T or C 
    131134</pre></blockquote> 
    132         """ 
     135        """, show_anything=False) 
    133136 
    134137    d = make_add_iupac_motif_form(request) 
     
    139142 
    140143    if not (request.form and name and iupac_str and mismatches): 
    141         return "ERROR: you have to enter name and motif!" 
     144        return error("ERROR: you have to enter name and motif!") 
    142145 
    143146    errors = [] 
     
    153156 
    154157    if errors: 
    155         return "ERROR:<p><ul><li> %s</ul>" % ("<li>".join(errors)) 
     158        return error("ERROR:<p><ul><li> %s</ul>" % ("<li>".join(errors))) 
    156159 
    157160    ### create the motif & put it into the database 
     
    185188def build_pwm_from_list(request): 
    186189    if not request.form: 
    187         return """\ 
     190        return wrap("""\ 
    188191<form method="POST"> 
    189192<h3>Build a matrix motif (PWM) from a list of known sites</h3> 
    190 Name: <input type='text' name='name'> 
    191 <p> 
    192 Aligned sequences:<br> 
    193 <textarea name='sequences' rows='5' cols='30'></textarea> 
    194 <p> 
    195 <input type='submit' value='build PWM'> 
    196 </form> 
    197 <hr> 
     193 
    198194<b>Instructions:</b> 
    199195<p> 
    200196To build a matrix motif (a.k.a. Position-Weight Matrix, or PWM),  
    201 enter a list of ungapped, aligned sequences.  For example, here is a list 
     197enter a list of ungapped, aligned sequences. 
     198<p> 
     199For example, here is a list 
    202200of GATA-type motifs: 
    203201<pre> 
     
    209207After submitting this list, a matrix motif will be built and you can 
    210208then define a threshold for searches. 
    211 """ 
     209<p> 
     210<hr> 
     211Name: <input type='text' name='name'> 
     212<p> 
     213Aligned sequences:<br> 
     214<textarea name='sequences' rows='5' cols='30'></textarea> 
     215<p> 
     216<input type='submit' value='build PWM'> 
     217</form> 
     218<p> 
     219Note: PWMs are built as in Wasserman and Sandelin, Nat Rev 
     220Genet. 2004 Apr;5(4):276-87 (PubMed ID 15131651; <a 
     221href='http://www.ncbi.nlm.nih.gov/pubmed/15131651'>PubMed Record</a>). 
     222See Box 1 of that paper for details. 
     223<hr> 
     224""", show_anything=False) 
    212225 
    213226    errors = [] 
     
    229242 
    230243    if errors: 
    231         return "ERROR:<p><ul><li> %s</ul>" % ("<li>".join(errors,)) 
     244        return error("ERROR:<p><ul><li> %s</ul>" % ("<li>".join(errors,))) 
    232245 
    233246    ### ok, validation good so far.  build the PWM & display... 
     
    340353    """ 
    341354    <p> 
    342     Maximum threshold: %.2g 
    343     """ % (pwm.max_score(),
     355    Maximum threshold: %.2f 
     356    """ % (round(pwm.max_score(), 2)
    344357     
    345358    if len(pwm) < 10: 
  • trunk/cartwheel-server/website/canal/pages.ptl

    r4 r281  
    2121        conf = cartwheel.website.get_config() 
    2222        """ 
    23         Welcome to %s! 
     23        <h2>Welcome to %s!</h2> 
     24        <p> 
    2425        """ % (cartwheel.config.get_server_name(conf),) 
     26 
     27        news() 
    2528 
    2629        user = request.session.get_user() 
     
    2932<p>             
    3033This computer is currently logged in as <b>%s</b>.  You can either 
    31 <a href="logout">log out</a>, <a href="lab/">continue this session</a>, 
     34<a href="logout">log out</a>, <a href="lab/">continue</a>, 
    3235or use this form to log in as a different user. 
    3336<p> 
     
    382385    """ 
    383386 
     387### 
     388 
     389template news(): 
     390    """ 
     391    <p> 
     392 
     393    Cartwheel is a system for cis-regulatory analysis; it lets you create 
     394    custom analyses and display the results. 
     395     
     396    <p> 
     397    Accounts are free and simply to create -- just click "add account"! 
     398     
     399    <p> 
     400     
     401    For a tutorial on using Cartwheel and FamilyRelations, please 
     402    visit <a href="http://family.caltech.edu/tutorial/">family.caltech.edu/tutorial/</a>. 
     403 
     404    <P> 
     405    """ 
  • trunk/cartwheel-server/website/canal/templates.ptl

    r4 r281  
    1414    if title: 
    1515        title = title + " -- " 
     16    else: 
     17        title = "" 
     18 
     19    request = quixote.get_request() 
     20    base_path = request.get_environ('SCRIPT_NAME') 
    1621         
    1722    """ 
    1823    <html> 
    1924    <head> 
    20     <title>%sCartwheel Analysis Server</title> 
     25    <link REL="stylesheet" TYPE="text/css" href="%(base_path)s/style"> 
     26    <title>%(title)sCartwheel Analysis Server</title> 
    2127    </head> 
    2228    <body bgcolor=white> 
    23     """ % (title,) 
     29    """ % dict(title=title, base_path=base_path,) 
    2430 
    2531# 
     
    2733# 
    2834 
    29 def footer[html](show_functions=1): 
     35def footer[html](show_functions=True, show_anything=True): 
    3036    request = quixote.get_request() 
    3137    base_path = request.get_environ('SCRIPT_NAME') 
     
    4046 
    4147    functions_html = ''  
    42     if show_functions
     48    if show_functions and show_anything
    4349        admin_html = '' 
    4450        session = quixote.publish.get_request().session 
     
    6773    <p> 
    6874    """ % pageDict 
    69 #      <a href="%(base_path)s/start/FR/jnlp"><b>start FamilyRelations</b></a> / 
    7075 
    7176    # 
     
    7378    # 
    7479 
     80    if show_anything: 
     81        """ 
     82        <hr> 
     83        <font size=-1> 
     84        %s 
     85        Questions? Comments? Contact the server administrator at <a href="mailto:%s"><i>%s</i></a>. 
     86        </font> 
     87        """  % (functions_html, admin_email, admin_email) 
     88 
    7589    """ 
    76     <hr> 
    77     <font size=-1> 
    78     %s 
    79     Problems? Questions?  Contact the server administrator at <a href="mailto:%s"><i>%s</i></a>. 
    80     </font> 
    8190    </body> 
    82     """ % (functions_html, admin_email, admin_email) 
     91    """ 
     92 
     93def wrap[html](*content, **kw): 
     94    title = kw.get('title') 
     95    show_functions = kw.get('show_functions', True) 
     96    show_anything = kw.get('show_anything', True) 
     97 
     98    text = "".join([ htmltext(i) for i in content ]) 
     99 
     100    return header(title) + text + footer(show_functions, show_anything) 
     101 
     102def error[html](error_text): 
     103    return wrap(error_text, title="ERROR!", show_anything=False) 
     104 
     105def get_style_contents(): 
     106    return """\ 
     107h1,h2,h3 { 
     108        padding: 30px 0; 
     109#        background: #655A46; 
     110        color: #333; 
     111#       color: #E4DBCF; 
     112        font-size: 1.4em; 
     113#        letter-spacing: 3px; 
     114        margin: 0; 
     115#        text-align: right; 
     116#        font: normal 3.4em "Lucida Sans Unicode","Trebuchet MS",sans-serif; 
     117
     118 
     119body,p,table,li,hr 
     120
     121font-family: verdana, arial, 'sans serif';  
     122font-size: 95% 
     123
     124 
     125body 
     126
     127#ffffff; 
     128
     129 
     130a:link {COLOR: navy;} 
     131a:visited {COLOR: navy;} 
     132/* a:active {COLOR: seashell;}  */ 
     133a:hover {COLOR: navy;} 
     134 
     135div { 
     136    margin:0; 
     137    padding:0 .25em 0 0; 
     138/*     text-align: right 
     139     border:1px solid #aaa; 
     140     background-color:#ececec; */ 
     141    } 
     142"""